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; - /// - /// Set the test Addins - /// - private void LoadNeededAddins(string fileName) - { - bool blnNeedToLoadAddins = false; - - //if not launched, we have no addins. - if (!_qtpApplication.Launched) - _colLoadedAddinNames = null; - - try - { - HashSet colCurrentTestAddins = new HashSet(); - - object erroDescription; - var testAddinsObj = _qtpApplication.GetAssociatedAddinsForTest(fileName); - object[] testAddins = (object[])testAddinsObj; - - foreach (string addin in testAddins) - { - colCurrentTestAddins.Add(addin); - } - - if (_colLoadedAddinNames != null) - { - //check if we have a missing addin (and need to quit Qtp, and reload with new addins) - foreach (string addin in testAddins) - { - if (!_colLoadedAddinNames.Contains(addin)) - { - blnNeedToLoadAddins = true; - break; - } - } - - //check if there is no extra addins that need to be removed - if (_colLoadedAddinNames.Count != colCurrentTestAddins.Count) - { - blnNeedToLoadAddins = true; - } - } - else - { - //first time = load addins. - blnNeedToLoadAddins = true; - } - - _colLoadedAddinNames = colCurrentTestAddins; - - //the addins need to be refreshed, load new addins - if (blnNeedToLoadAddins) - { - if (_qtpApplication.Launched) - _qtpApplication.Quit(); - _qtpApplication.SetActiveAddins(ref testAddinsObj, out erroDescription); - } - - } - catch (Exception) - { - // Try anyway to run the test - } - } - - - /// - /// Activate all Installed Addins - /// - private void ActivateAllAddins() - { - try - { - // Get Addins collection - Addins qtInstalledAddins = _qtpApplication.Addins; - - if (qtInstalledAddins.Count > 0) - { - string[] qtAddins = new string[qtInstalledAddins.Count]; - - // Addins Object is 1 base order - for (int idx = 1; idx <= qtInstalledAddins.Count; ++idx) - { - // Our list is 0 base order - qtAddins[idx - 1] = qtInstalledAddins[idx].Name; - } - - object erroDescription; - var addinNames = (object)qtAddins; - - _qtpApplication.SetActiveAddins(ref addinNames, out erroDescription); - } - } - catch (Exception) - { - // Try anyway to run the test - } - } - - /// - /// runs the given test QTP and returns results - /// - /// the test results object containing test info and also receiving run results - /// - private GuiTestRunResult ExecuteQTPRun(TestRunResults testResults) - { - GuiTestRunResult result = new GuiTestRunResult { IsSuccess = true }; - try - { - Type runResultsOptionstype = Type.GetTypeFromProgID("QuickTest.RunResultsOptions"); - var options = (RunResultsOptions)Activator.CreateInstance(runResultsOptionstype); - options.ResultsLocation = testResults.ReportLocation; - _qtpApplication.Options.Run.RunMode = "Fast"; - - //Check for cancel before executing - if (_runCancelled()) - { - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.GeneralTestCanceled; - ConsoleWriter.WriteLine(Resources.GeneralTestCanceled); - result.IsSuccess = false; - return result; - } - ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerRunningTest, testResults.TestPath)); - - _qtpApplication.Test.Run(options, false, _qtpParameters); - - result.ReportPath = Path.Combine(testResults.ReportLocation, "Report"); - int slept = 0; - while ((slept < 20000 && _qtpApplication.GetStatus().Equals("Ready")) || _qtpApplication.GetStatus().Equals("Waiting")) - { - Thread.Sleep(50); - slept += 50; - } - - - while (!_runCancelled() && (_qtpApplication.GetStatus().Equals("Running") || _qtpApplication.GetStatus().Equals("Busy"))) - { - Thread.Sleep(200); - if (_timeLeftUntilTimeout - _stopwatch.Elapsed <= TimeSpan.Zero) - { - _qtpApplication.Test.Stop(); - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.GeneralTimeoutExpired; - ConsoleWriter.WriteLine(Resources.GeneralTimeoutExpired); - - result.IsSuccess = false; - return result; - } - } - - if (_runCancelled()) - { - QTPTestCleanup(); - KillQtp(); - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.GeneralTestCanceled; - ConsoleWriter.WriteLine(Resources.GeneralTestCanceled); - Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted; - result.IsSuccess = false; - return result; - } - string lastError = _qtpApplication.Test.LastRunResults.LastError; - - //read the lastError - if (!String.IsNullOrEmpty(lastError)) - { - testResults.TestState = TestState.Error; - testResults.ErrorDesc = lastError; - } - - // the way to check the logical success of the target QTP test is: app.Test.LastRunResults.Status == "Passed". - if (_qtpApplication.Test.LastRunResults.Status.Equals("Passed")) - { - testResults.TestState = TestState.Passed; - - } - else if (_qtpApplication.Test.LastRunResults.Status.Equals("Warning")) - { - testResults.TestState = TestState.Passed; - testResults.HasWarnings = true; - - if (Launcher.ExitCode != Launcher.ExitCodeEnum.Failed && Launcher.ExitCode != Launcher.ExitCodeEnum.Aborted) - Launcher.ExitCode = Launcher.ExitCodeEnum.Unstable; - } - else - { - testResults.TestState = TestState.Failed; - testResults.FailureDesc = "Test failed"; - - Launcher.ExitCode = Launcher.ExitCodeEnum.Failed; - } - } - catch (NullReferenceException e) - { - ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e.Message, e.StackTrace)); - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.QtpRunError; - - result.IsSuccess = false; - return result; - } - catch (SystemException e) - { - KillQtp(); - ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e.Message, e.StackTrace)); - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.QtpRunError; - - result.IsSuccess = false; - return result; - } - catch (Exception e2) - { - - ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e2.Message, e2.StackTrace)); - testResults.TestState = TestState.Error; - testResults.ErrorDesc = Resources.QtpRunError; - - result.IsSuccess = false; - return result; - } - - - return result; - } - - private void KillQtp() - { - //error during run, process may have crashed (need to cleanup, close QTP and qtpRemote for next test to run correctly) - CleanUp(); - - //kill the qtp automation, to make sure it will run correctly next time - Process[] processes = Process.GetProcessesByName("qtpAutomationAgent"); - Process qtpAuto = processes.Where(p => p.SessionId == Process.GetCurrentProcess().SessionId).FirstOrDefault(); - if (qtpAuto != null) - qtpAuto.Kill(); - } - - private bool HandleOutputArguments(ref string errorReason) - { - try - { - var outputArguments = new XmlDocument { PreserveWhitespace = true }; - outputArguments.LoadXml(""); - - for (int i = 1; i <= _qtpParamDefs.Count; ++i) - { - var pd = _qtpParamDefs[i]; - if (pd.InOut == qtParameterDirection.qtParamDirOut) - { - var node = outputArguments.CreateElement(pd.Name); - var value = _qtpParameters[pd.Name].Value; - if (value != null) - node.InnerText = value.ToString(); - - outputArguments.DocumentElement.AppendChild(node); - } - } - } - catch (Exception e) - { - errorReason = Resources.QtpNotLaunchedError; - return false; - } - return true; - } - private bool VerifyParameterValueType(object paramValue, qtParameterType type) - { - bool legal = false; - - switch (type) - { - case qtParameterType.qtParamTypeBoolean: - legal = paramValue is bool; - break; - - case qtParameterType.qtParamTypeDate: - legal = paramValue is DateTime; - break; - - case qtParameterType.qtParamTypeNumber: - legal = ((paramValue is int) || (paramValue is long) || (paramValue is decimal) || (paramValue is float) || (paramValue is double)); - break; - - case qtParameterType.qtParamTypePassword: - legal = paramValue is string; - break; - - case qtParameterType.qtParamTypeString: - legal = paramValue is string; - break; - - default: - legal = true; - break; - } - - return legal; - } - - private bool HandleInputParameters(string fileName, ref string errorReason, Dictionary inputParams) - { - try - { - string path = fileName; - - if (_runCancelled()) - { - QTPTestCleanup(); - KillQtp(); - return false; - } - - _qtpApplication.Open(path, true, false); - _qtpParamDefs = _qtpApplication.Test.ParameterDefinitions; - _qtpParameters = _qtpParamDefs.GetParameters(); - - // handle all parameters (index starts with 1 !!!) - for (int i = 1; i <= _qtpParamDefs.Count; i++) - { - // input parameters - if (_qtpParamDefs[i].InOut == qtParameterDirection.qtParamDirIn) - { - string paramName = _qtpParamDefs[i].Name; - qtParameterType type = _qtpParamDefs[i].Type; - - // if the caller supplies value for a parameter we set it - if (inputParams.ContainsKey(paramName)) - { - // first verify that the type is correct - object paramValue = inputParams[paramName]; - if (!VerifyParameterValueType(paramValue, type)) - { - ConsoleWriter.WriteErrLine(string.Format("Illegal input parameter type (skipped). param: '{0}'. expected type: '{1}'. actual type: '{2}'", paramName, Enum.GetName(typeof(qtParameterType), type), paramValue.GetType())); - } - else - { - _qtpParameters[paramName].Value = paramValue; - } - } - } - } - } - catch (Exception e) - { - errorReason = Resources.QtpRunError; - return false; - } - return true; - - } - - /// - /// stops and closes qtp test, to make sure nothing is left floating after run. - /// - private void QTPTestCleanup() - { - try - { - lock (_lockObject) - { - if (_qtpApplication == null) - { - return; - } - - var qtpTest = _qtpApplication.Test; - if (qtpTest != null) - { - if (_qtpApplication.GetStatus().Equals("Running") || _qtpApplication.GetStatus().Equals("Busy")) - { - try - { - _qtpApplication.Test.Stop(); - } - catch (Exception e) - { - } - finally - { - - } - } - } - } - } - catch (Exception ex) - { - } - - _qtpParameters = null; - _qtpParamDefs = null; - _qtpApplication = null; - } - - - /// - /// Why we need this? If we run jenkins in a master slave node where there is a jenkins service installed in the slave machine, we need to change the DCOM settings as follow: - /// dcomcnfg.exe -> My Computer -> DCOM Config -> QuickTest Professional Automation -> Identity -> and select The Interactive User - /// - private void ChangeDCOMSettingToInteractiveUser() - { - string errorMsg = "Unable to change DCOM settings. To chage it manually: " + - "run dcomcnfg.exe -> My Computer -> DCOM Config -> QuickTest Professional Automation -> Identity -> and select The Interactive User"; - - string interactiveUser = "Interactive User"; - string runAs = "RunAs"; - - try - { - var regKey = GetQuickTestProfessionalAutomationRegKey(RegistryView.Registry32); - - if (regKey == null) - { - regKey = GetQuickTestProfessionalAutomationRegKey(RegistryView.Registry64); - } - - if (regKey == null) - throw new Exception(@"Unable to find in registry SOFTWARE\Classes\AppID\{A67EB23A-1B8F-487D-8E38-A6A3DD150F0B"); - - object runAsKey = regKey.GetValue(runAs); - - if (runAsKey == null || !runAsKey.ToString().Equals(interactiveUser)) - { - regKey.SetValue(runAs, interactiveUser); - } - - } - catch (Exception ex) - { - throw new Exception(errorMsg + "detailed error is : " + ex.Message); - } - - - } - - private RegistryKey GetQuickTestProfessionalAutomationRegKey(RegistryView registryView) - { - RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); - localKey = localKey.OpenSubKey(@"SOFTWARE\Classes\AppID\{A67EB23A-1B8F-487D-8E38-A6A3DD150F0B}", true); - - return localKey; - } - - - #endregion - - - - - - /// - /// holds the resutls for a GUI test - /// - private class GuiTestRunResult - { - public GuiTestRunResult() - { - ReportPath = ""; - } - - public bool IsSuccess { get; set; } - public string ReportPath { 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.TestRunners; +using HpToolsLauncher.Utils; +using Microsoft.Win32; +using QTObjectModelLib; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; +using Resources = HpToolsLauncher.Properties.Resources; +using AuthType = HpToolsLauncher.McConnectionInfo.AuthType; + +namespace HpToolsLauncher +{ + public class GuiTestRunner : IFileSysTestRunner + { + // Setting keys for mobile + private const string MC_TYPE = "MobileCenterType"; + private const string MOBILE_HOST_ADDRESS = "ALM_MobileHostAddress"; + private const string MOBILE_HOST_PORT = "ALM_MobileHostPort"; + private const string MOBILE_USER = "ALM_MobileUserName"; + private const string MOBILE_PASSWORD = "ALM_MobilePassword"; + private const string MOBILE_CLIENTID = "EXTERNAL_MobileClientID"; + private const string MOBILE_SECRET = "EXTERNAL_MobileSecretKey"; + private const string MOBILE_AUTH_TYPE = "EXTERNAL_MobileAuthType"; + private const string MOBILE_TENANT = "EXTERNAL_MobileTenantId"; + private const string MOBILE_USE_SSL = "ALM_MobileUseSSL"; + private const string MOBILE_USE_PROXY = "EXTERNAL_MobileProxySetting_UseProxy"; + private const string MOBILE_PROXY_SETTING = "EXTERNAL_MobileProxySetting"; + private const string MOBILE_PROXY_SETTING_ADDRESS = "EXTERNAL_MobileProxySetting_Address"; + private const string MOBILE_PROXY_SETTING_PORT = "EXTERNAL_MobileProxySetting_Port"; + private const string MOBILE_PROXY_SETTING_AUTHENTICATION = "EXTERNAL_MobileProxySetting_Authentication"; + private const string MOBILE_PROXY_SETTING_USERNAME = "EXTERNAL_MobileProxySetting_UserName"; + private const string MOBILE_PROXY_SETTING_PASSWORD = "EXTERNAL_MobileProxySetting_Password"; + private const string MOBILE_INFO = "mobileinfo"; + private const string REPORT = "Report"; + private const string READY = "Ready"; + private const string WAITING = "Waiting"; + private const string BUSY = "Busy"; + private const string RUNNING = "Running"; + private const string PASSED = "Passed"; + private const string WARNING = "Warning"; + private const int MEMBER_NOT_FOUND = -2147352573; + private const string PROTECT_BstrToBase64_FAILED = "ProtectBSTRToBase64 failed for {0}."; + private const string WEB = "Web"; + private const string CLOUD_BROWSER = "CloudBrowser"; + private const string SYSTEM_PROXY = "System Proxy"; + private const string HTTP_PROXY = "HTTP Proxy"; + + private readonly Type _qtType = Type.GetTypeFromProgID("Quicktest.Application"); + private readonly IAssetRunner _runNotifier; + private readonly object _lockObject = new object(); + private TimeSpan _timeLeftUntilTimeout = TimeSpan.MaxValue; + private readonly string _uftRunMode; + 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; + private CloudBrowser _cloudBrowser; + private bool _printInputParams; + private bool _isCancelledByUser; + private RunAsUser _uftRunAsUser; + + /// + /// constructor + /// + /// + /// + /// + public GuiTestRunner(IAssetRunner runNotifier, bool useUftLicense, TimeSpan timeLeftUntilTimeout, string uftRunMode, DigitalLab digitalLab, bool printInputParams, RunAsUser uftRunAsUser) + { + _timeLeftUntilTimeout = timeLeftUntilTimeout; + _uftRunMode = uftRunMode; + _stopwatch = Stopwatch.StartNew(); + _runNotifier = runNotifier; + _useUFTLicense = useUftLicense; + _mcConnection = digitalLab.ConnectionInfo; + _mobileInfo = digitalLab.MobileInfo; + _cloudBrowser = digitalLab.CloudBrowser; + _printInputParams = printInputParams; + _uftRunAsUser = uftRunAsUser; + } + + #region QTP + + /// + /// runs the given test and returns resutls + /// + /// + /// + /// + /// + public TestRunResults RunTest(TestInfo testinf, ref string errorReason, RunCancelledDelegate runCancelled, out Dictionary outParams) + { + outParams = new Dictionary(); + var testPath = testinf.TestPath; + TestRunResults runDesc = new TestRunResults { TestType = TestType.QTP }; + ConsoleWriter.ActiveTestRun = runDesc; + ConsoleWriter.WriteLineWithTime("Running: " + testPath); + + runDesc.TestPath = testPath; + + // default report location is the test path + runDesc.ReportLocation = testPath; + // check if the report path has been defined + if (!string.IsNullOrEmpty(testinf.ReportPath)) + { + if (!Helper.TrySetTestReportPath(runDesc, testinf, ref errorReason)) + { + return runDesc; + } + } + + runDesc.TestState = TestState.Unknown; + + _runCancelled = runCancelled; + + if (!Helper.IsQtpInstalled()) + { + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = string.Format(Resources.GeneralQtpNotInstalled, Environment.MachineName); + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + return runDesc; + } + + string reason; + if (!Helper.CanUftProcessStart(out reason)) + { + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = reason; + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + return runDesc; + } + + Version qtpVersion; + try + { + lock (_lockObject) + { + _qtpApplication = Activator.CreateInstance(_qtType) as Application; + if (_uftRunAsUser != null) + { + try + { + if (_qtpApplication.Launched) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + } + _qtpApplication.LaunchAsUser(_uftRunAsUser.Username, _uftRunAsUser.EncodedPassword); + } + catch (COMException e) + { + if (e.ErrorCode == MEMBER_NOT_FOUND) + { + errorReason = Resources.UftLaunchAsUserNotSupported; + } + throw; + } + if (_qtpApplication.Visible) + { + _qtpApplication.Visible = false; + } + } + + qtpVersion = Version.Parse(_qtpApplication.Version); + if (qtpVersion.Equals(new Version(11, 0))) + { + runDesc.ReportLocation = GetReportLocation(testinf, testPath); + } + // Check for required Addins + LoadNeededAddins(testPath); + + // set Mc connection and other mobile info into rack if neccesary + SetMobileInfo(); + + if (!_qtpApplication.Launched) + { + if (_runCancelled()) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + runDesc.TestState = TestState.Error; + return runDesc; + } + // Launch application after set Addins + _qtpApplication.Launch(); + _qtpApplication.Visible = false; + } + } + } + catch (Exception e) + { + if (string.IsNullOrEmpty(errorReason)) + { + errorReason = Resources.QtpNotLaunchedError; + runDesc.ErrorDesc = e.Message; + ConsoleWriter.WriteErrLine(e.Message); + } + else + { + runDesc.ErrorDesc = errorReason; + ConsoleWriter.WriteErrLine(errorReason); + } +#if DEBUG + ConsoleWriter.WriteException(e); +#endif + runDesc.TestState = TestState.Error; + runDesc.ReportLocation = string.Empty; + 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); + + Dictionary paramDict; + try + { + paramDict = testinf.GetParameterDictionaryForQTP(); + } + catch (ArgumentException) + { + ConsoleWriter.WriteErrLine(Resources.FsDuplicateParamNames); + throw; + } + + if (!HandleInputParameters(testPath, ref errorReason, paramDict, testinf)) + { + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = errorReason; + return runDesc; + } + + if (!HandleCloudBrowser(qtpVersion, ref errorReason)) + { + ConsoleWriter.WriteErrLine(errorReason); + 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, out outParams)) + { + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = errorReason; + return runDesc; + } + + QTPTestCleanup(); + _qtpApplication = null; + + return runDesc; + } + + private string GetReportLocation(TestInfo testinf, string testPath) + { + // use the defined report path if provided + string rptLocation = string.IsNullOrEmpty(testinf.ReportPath) ? + Path.Combine(testPath, REPORT) : + Path.Combine(testinf.ReportPath, REPORT); + + if (Directory.Exists(rptLocation)) + { + int lastIndex = rptLocation.IndexOf("\\"); + var location = rptLocation.Substring(0, lastIndex); + var name = rptLocation.Substring(lastIndex + 1); + rptLocation = Helper.GetNextResFolder(location, name); + Directory.CreateDirectory(rptLocation); + } + return rptLocation; + } + + private void SetMobileInfo() + { + if (_mcConnection == null) return; + + #region Mc connection and other mobile info + + ITDPierToTulip tulip = _qtpApplication.TDPierToTulip; + // Mc Address, username and password + if (!_mcConnection.HostAddress.IsNullOrEmpty()) + { + tulip.SetTestOptionsVal(MC_TYPE, (int)_mcConnection.LabType); + + tulip.SetTestOptionsVal(MOBILE_HOST_ADDRESS, _mcConnection.HostAddress); + if (!_mcConnection.HostPort.IsNullOrEmpty()) + { + tulip.SetTestOptionsVal(MOBILE_HOST_PORT, _mcConnection.HostPort); + } + + AuthType mcAuthType = _mcConnection.MobileAuthType; + switch (mcAuthType) + { + case AuthType.AuthToken: + var token = _mcConnection.GetAuthToken(); + + tulip.SetTestOptionsVal(MOBILE_CLIENTID, token.ClientId); + tulip.SetTestOptionsVal(MOBILE_SECRET, token.SecretKey); + + break; + case AuthType.UsernamePassword: + if (!_mcConnection.UserName.IsNullOrEmpty()) + { + tulip.SetTestOptionsVal(MOBILE_USER, _mcConnection.UserName); + } + + if (!_mcConnection.Password.IsNullOrEmpty()) + { + string encriptedMcPassword = WinUserNativeMethods.ProtectBSTRToBase64(_mcConnection.Password); + if (encriptedMcPassword == null) + { + ConsoleWriter.WriteLine(string.Format(PROTECT_BstrToBase64_FAILED, "DL Password")); + throw new Exception(string.Format(PROTECT_BstrToBase64_FAILED, "DL Password")); + } + tulip.SetTestOptionsVal(MOBILE_PASSWORD, encriptedMcPassword); + } + break; + } + + // set authentication type + tulip.SetTestOptionsVal(MOBILE_AUTH_TYPE, mcAuthType); + + // set tenantID + if (!_mcConnection.TenantId.IsNullOrEmpty()) + { + tulip.SetTestOptionsVal(MOBILE_TENANT, _mcConnection.TenantId); + } + + // ssl and proxy info + tulip.SetTestOptionsVal(MOBILE_USE_SSL, _mcConnection.UseSslAsInt); + + if (_mcConnection.UseProxy) + { + tulip.SetTestOptionsVal(MOBILE_USE_PROXY, _mcConnection.UseProxyAsInt); + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING, _mcConnection.ProxyType == 1 ? SYSTEM_PROXY : HTTP_PROXY); + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_ADDRESS, _mcConnection.ProxyAddress); + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_PORT, _mcConnection.ProxyPort); + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_AUTHENTICATION, _mcConnection.UseProxyAuthAsInt); + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_USERNAME, _mcConnection.ProxyUserName); + string encMcProxyPassword = WinUserNativeMethods.ProtectBSTRToBase64(_mcConnection.ProxyPassword); + if (encMcProxyPassword == null) + { + ConsoleWriter.WriteLine(string.Format(PROTECT_BstrToBase64_FAILED, "DL Proxy Password")); + throw new Exception(string.Format(PROTECT_BstrToBase64_FAILED, "DL Proxy Password")); + } + tulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_PASSWORD, encMcProxyPassword); + } + + // Mc info (device, app, launch and terminate data) + if (!string.IsNullOrEmpty(_mobileInfo)) + { + tulip.SetTestOptionsVal(MOBILE_INFO, _mobileInfo); + } + } + #endregion + } + + /// + /// performs global cleanup code for this type of runner + /// + public void CleanUp() + { + try + { + lock (_lockObject) + { + //if we don't have a qtp instance, create one + if (_qtpApplication == null) + { + _qtpApplication = Activator.CreateInstance(_qtType) as Application; + } + + _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) + } + } + + public void SafelyCancel() + { + _isCancelledByUser = true; + ConsoleWriter.WriteLine(Resources.GeneralStopAborted); + QTPTestCleanup(); + CleanUpAndKillQtp(); + ConsoleWriter.WriteLine(Resources.GeneralAbortedByUser); + } + + static HashSet _colLoadedAddinNames = null; + /// + /// Set the test Addins + /// + private void LoadNeededAddins(string fileName) + { + bool blnNeedToLoadAddins = false; + + //if not launched, we have no addins. + if (!_qtpApplication.Launched) + _colLoadedAddinNames = null; + + try + { + HashSet colCurrentTestAddins = new HashSet(); + + object erroDescription; + var testAddinsObj = _qtpApplication.GetAssociatedAddinsForTest(fileName); + object[] testAddins = (object[])testAddinsObj; + + foreach (string addin in testAddins) + { + colCurrentTestAddins.Add(addin); + } + + if (_colLoadedAddinNames != null) + { + //check if we have a missing addin (and need to quit Qtp, and reload with new addins) + foreach (string addin in testAddins) + { + if (!_colLoadedAddinNames.Contains(addin)) + { + blnNeedToLoadAddins = true; + break; + } + } + + //check if there is no extra addins that need to be removed + if (_colLoadedAddinNames.Count != colCurrentTestAddins.Count) + { + blnNeedToLoadAddins = true; + } + } + else + { + //first time = load addins. + blnNeedToLoadAddins = true; + } + + _colLoadedAddinNames = colCurrentTestAddins; + + //the addins need to be refreshed, load new addins + if (blnNeedToLoadAddins) + { + if (_qtpApplication.Launched && _uftRunAsUser == null) + _qtpApplication.Quit(); + _qtpApplication.SetActiveAddins(ref testAddinsObj, out erroDescription); + } + } + catch (Exception) + { + // Try anyway to run the test + } + } + + + /// + /// Activate all Installed Addins + /// + private void ActivateAllAddins() + { + try + { + // Get Addins collection + Addins qtInstalledAddins = _qtpApplication.Addins; + + if (qtInstalledAddins.Count > 0) + { + string[] qtAddins = new string[qtInstalledAddins.Count]; + + // Addins Object is 1 base order + for (int idx = 1; idx <= qtInstalledAddins.Count; ++idx) + { + // Our list is 0 base order + qtAddins[idx - 1] = qtInstalledAddins[idx].Name; + } + + object erroDescription; + var addinNames = (object)qtAddins; + + _qtpApplication.SetActiveAddins(ref addinNames, out erroDescription); + } + } + catch (Exception) + { + // Try anyway to run the test + } + } + + /// + /// runs the given test QTP and returns results + /// + /// the test results object containing test info and also receiving run results + /// + private GuiTestRunResult ExecuteQTPRun(TestRunResults testResults) + { + GuiTestRunResult result = new GuiTestRunResult { IsSuccess = true }; + try + { + Type runResultsOptionstype = Type.GetTypeFromProgID("QuickTest.RunResultsOptions"); + var options = (RunResultsOptions)Activator.CreateInstance(runResultsOptionstype); + options.ResultsLocation = testResults.ReportLocation; + if (_uftRunMode != null) + { + _qtpApplication.Options.Run.RunMode = _uftRunMode; + } + + //Check for cancel before executing + if (_runCancelled()) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.GeneralTestCanceled; + ConsoleWriter.WriteLine(Resources.GeneralTestCanceled); + result.IsSuccess = false; + Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted; + return result; + } + ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerRunningTest, testResults.TestPath)); + + _qtpApplication.Test.Run(options, false, _qtpParameters); + + result.ReportPath = Path.Combine(testResults.ReportLocation, REPORT); + int slept = 0; + while ((slept < 20000 && _qtpApplication.GetStatus() == READY) || _qtpApplication.GetStatus() == WAITING) + { + Thread.Sleep(50); + slept += 50; + } + + while (!_runCancelled() && (_qtpApplication.GetStatus() == RUNNING || _qtpApplication.GetStatus() == BUSY)) + { + Thread.Sleep(200); + if (_timeLeftUntilTimeout - _stopwatch.Elapsed <= TimeSpan.Zero) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.GeneralTimeoutExpired; + ConsoleWriter.WriteLine(Resources.GeneralTimeoutExpired); + Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted; + result.IsSuccess = false; + return result; + } + } + + if (_runCancelled()) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.GeneralTestCanceled; + ConsoleWriter.WriteLine(Resources.GeneralTestCanceled); + Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted; + result.IsSuccess = false; + return result; + } + string lastError = _qtpApplication.Test.LastRunResults.LastError; + + //read the lastError + if (!string.IsNullOrEmpty(lastError)) + { + testResults.TestState = TestState.Error; + testResults.ErrorDesc = lastError; + } + + // the way to check the logical success of the target QTP test is: app.Test.LastRunResults.Status == "Passed". + if (_qtpApplication.Test.LastRunResults.Status == PASSED) + { + testResults.TestState = TestState.Passed; + } + else if (_qtpApplication.Test.LastRunResults.Status == WARNING) + { + testResults.TestState = TestState.Warning; + testResults.HasWarnings = true; + + if (Launcher.ExitCode != Launcher.ExitCodeEnum.Failed && Launcher.ExitCode != Launcher.ExitCodeEnum.Aborted) + Launcher.ExitCode = Launcher.ExitCodeEnum.Unstable; + } + else + { + testResults.TestState = TestState.Failed; + testResults.FailureDesc = "Test failed"; + + Launcher.ExitCode = Launcher.ExitCodeEnum.Failed; + } + } + catch (NullReferenceException e) + { + ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e.Message, e.StackTrace)); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.QtpRunError; + + result.IsSuccess = false; + return result; + } + catch (SystemException e) + { + CleanUpAndKillQtp(); + ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e.Message, e.StackTrace)); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.QtpRunError; + + result.IsSuccess = false; + return result; + } + catch (Exception e2) + { + if (_isCancelledByUser) + { + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.GeneralStopAborted; + } + else + { + ConsoleWriter.WriteLine(string.Format(Resources.GeneralErrorWithStack, e2.Message, e2.StackTrace)); + testResults.TestState = TestState.Error; + testResults.ErrorDesc = Resources.QtpRunError; + } + + result.IsSuccess = false; + return result; + } + + return result; + } + + private void CleanUpAndKillQtp() + { + //error during run, process may have crashed (need to cleanup, close QTP and qtpRemote for next test to run correctly) + CleanUp(); + + //kill the qtp automation, to make sure it will run correctly next time + Process[] processes = Process.GetProcessesByName("qtpAutomationAgent"); + Process qtpAuto = processes.Where(p => p.SessionId == Process.GetCurrentProcess().SessionId).FirstOrDefault(); + if (qtpAuto != null) + { + qtpAuto.Kill(); + } + } + + private bool HandleOutputArguments(ref string errorReason, out Dictionary outParams) + { + outParams = new Dictionary(); + try + { + for (int i = 1; i <= _qtpParamDefs.Count; ++i) + { + var pd = _qtpParamDefs[i]; + if (pd.InOut == qtParameterDirection.qtParamDirOut) + { + var value = _qtpParameters[pd.Name].Value; + if (value != null) + { + if (outParams.ContainsKey(pd.Name)) + { + outParams[pd.Name] = value.ToString(); + } + else + { + outParams.Add(pd.Name, value.ToString()); + } + } + } + } + } + catch (Exception) + { + errorReason = Resources.QtpNotLaunchedError; + return false; + } + return true; + } + private bool VerifyParameterValueType(object paramValue, qtParameterType type) + { + bool legal = false; + + switch (type) + { + case qtParameterType.qtParamTypeBoolean: + legal = paramValue is bool; + break; + + case qtParameterType.qtParamTypeDate: + legal = paramValue is DateTime; + break; + + case qtParameterType.qtParamTypeNumber: + legal = ((paramValue is int) || (paramValue is long) || (paramValue is decimal) || (paramValue is float) || (paramValue is double)); + break; + + case qtParameterType.qtParamTypePassword: + case qtParameterType.qtParamTypeString: + case qtParameterType.qtParamTypeAny: + legal = paramValue is string; + break; + + default: + legal = false; + break; + } + + return legal; + } + + private bool HandleCloudBrowser(Version qtpVersion, ref string errorReason) + { + if (_cloudBrowser != null) + { + if (qtpVersion < new Version(2023, 4)) + { + errorReason = string.Format(Resources.CloudBrowserNotSupported, qtpVersion.ToString(2)); + return false; + } + try + { + var launcher = _qtpApplication.Test.Settings.Launchers[WEB]; + launcher.Active = true; + launcher.SetLab(CLOUD_BROWSER); + if (!_cloudBrowser.Url.IsNullOrWhiteSpace()) + launcher.Address = _cloudBrowser.Url; + launcher.CloudBrowser.OS = _cloudBrowser.OS; + launcher.CloudBrowser.Browser = _cloudBrowser.Browser; + launcher.CloudBrowser.BrowserVersion = _cloudBrowser.Version; + launcher.CloudBrowser.Location = _cloudBrowser.Region; + } + catch (Exception ex) + { + errorReason = ex.Message; + return false; + } + } + return true; + } + + private bool HandleInputParameters(string fileName, ref string errorReason, Dictionary inputParams, TestInfo testInfo) + { + try + { + string path = fileName; + + if (_runCancelled()) + { + QTPTestCleanup(); + CleanUpAndKillQtp(); + return false; + } + + _qtpApplication.Open(path, true, false); + _qtpParamDefs = _qtpApplication.Test.ParameterDefinitions; + _qtpParameters = _qtpParamDefs.GetParameters(); + + // handle all parameters (index starts with 1 !!!) + for (int i = 1; i <= _qtpParamDefs.Count; i++) + { + // input parameters + if (_qtpParamDefs[i].InOut == qtParameterDirection.qtParamDirIn) + { + string paramName = _qtpParamDefs[i].Name; + qtParameterType type = _qtpParamDefs[i].Type; + + // if the caller supplies value for a parameter we set it + if (!inputParams.ContainsKey(paramName)) continue; + + // first verify that the type is correct + object paramValue = inputParams[paramName]; + if (!VerifyParameterValueType(paramValue, type)) + { + try + { + ConsoleWriter.WriteErrLine(string.Format(Resources.GeneralParameterTypeMismatchWith2Types, paramName, Enum.GetName(typeof(qtParameterType), type), paramValue.GetType())); + } + catch (Exception) + { + ConsoleWriter.WriteErrLine(string.Format(Resources.GeneralParameterTypeMismatchWith2Types, paramName, Enum.GetName(typeof(qtParameterType), type), null)); + } + } + else + { + // second-check + try + { + _qtpParameters[paramName].Value = paramValue; + if (_printInputParams) + { + if (type == qtParameterType.qtParamTypePassword) + ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsageMask, paramName)); + else + ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsage, paramName, type != qtParameterType.qtParamTypeDate ? paramValue : ((DateTime)paramValue).ToShortDateString())); + } + } + catch (Exception) + { + ConsoleWriter.WriteErrLine(string.Format(Resources.GeneralParameterTypeMismatchWith1Type, paramName)); + } + } + } + } + + // specify data table path + if (testInfo.DataTablePath != null) + { + _qtpApplication.Test.Settings.Resources.DataTablePath = testInfo.DataTablePath; + ConsoleWriter.WriteLine("Using external data table: " + testInfo.DataTablePath); + } + + // specify iteration mode + if (testInfo.IterationInfo != null) + { + try + { + IterationInfo ii = testInfo.IterationInfo; + if (!IterationInfo.AvailableTypes.Contains(ii.IterationMode)) + { + throw new ArgumentException(string.Format("Illegal iteration mode '{0}'. Available modes are : {1}", ii.IterationMode, string.Join(", ", IterationInfo.AvailableTypes))); + } + + bool rangeMode = IterationInfo.RANGE_ITERATION_MODE.Equals(ii.IterationMode); + if (rangeMode) + { + int start = int.Parse(ii.StartIteration); + int end = int.Parse(ii.EndIteration); + + _qtpApplication.Test.Settings.Run.StartIteration = start; + _qtpApplication.Test.Settings.Run.EndIteration = end; + } + + _qtpApplication.Test.Settings.Run.IterationMode = testInfo.IterationInfo.IterationMode; + + ConsoleWriter.WriteLine("Using iteration mode: " + testInfo.IterationInfo.IterationMode + + (rangeMode ? " " + testInfo.IterationInfo.StartIteration + "-" + testInfo.IterationInfo.EndIteration : string.Empty)); + } + catch (Exception e) + { + string msg = "Failed to parse 'Iterations' element . Using default iteration settings. Error : " + e.Message; + ConsoleWriter.WriteLine(msg); + } + } + } + catch (Exception) + { + errorReason = Resources.QtpRunError; + return false; + } + return true; + } + + /// + /// stops and closes qtp test, to make sure nothing is left floating after run. + /// + private void QTPTestCleanup() + { + try + { + lock (_lockObject) + { + if (_qtpApplication == null) + { + return; + } + + var qtpTest = _qtpApplication.Test; + if (qtpTest != null) + { + try + { + _qtpApplication.Test.Stop(); + _qtpApplication.Test.Close(); + } + catch (Exception) + { } + } + } + } + catch (Exception) + { + } + + _qtpParameters = null; + _qtpParamDefs = null; + } + + private RegistryKey GetQuickTestProfessionalAutomationRegKey(RegistryView registryView) + { + RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); + localKey = localKey.OpenSubKey(@"SOFTWARE\Classes\AppID\{A67EB23A-1B8F-487D-8E38-A6A3DD150F0B}", true); + + return localKey; + } + +#endregion + + /// + /// holds the resutls for a GUI test + /// + private class GuiTestRunResult + { + public GuiTestRunResult() + { + ReportPath = string.Empty; + } + + public bool IsSuccess { get; set; } + public string ReportPath { get; set; } + } + } +} diff --git a/HpToolsLauncher/TestRunners/IterationInfo.cs b/HpToolsLauncher/TestRunners/IterationInfo.cs new file mode 100644 index 0000000000..a62828ab44 --- /dev/null +++ b/HpToolsLauncher/TestRunners/IterationInfo.cs @@ -0,0 +1,51 @@ +/* + * 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; + +namespace HpToolsLauncher.TestRunners +{ + public class IterationInfo + { + public const string RANGE_ITERATION_MODE = "rngIterations"; + public const string ONE_ITERATION_MODE = "oneIteration"; + public const string ALL_ITERATION_MODE = "rngAll"; + public static ISet AvailableTypes = new HashSet() { RANGE_ITERATION_MODE, ONE_ITERATION_MODE, ALL_ITERATION_MODE }; + + public string IterationMode { get; set; } + + public string StartIteration { get; set; } + + public string EndIteration { get; set; } + } +} diff --git a/HpToolsLauncher/TestRunners/ParallelTestRunner.cs b/HpToolsLauncher/TestRunners/ParallelTestRunner.cs new file mode 100644 index 0000000000..640995ab3f --- /dev/null +++ b/HpToolsLauncher/TestRunners/ParallelTestRunner.cs @@ -0,0 +1,449 @@ +/* + * 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.ParallelRunner; +using HpToolsLauncher.Utils; +using QTObjectModelLib; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Environment = System.Environment; +using Resources = HpToolsLauncher.Properties.Resources; +namespace HpToolsLauncher.TestRunners +{ + /// + /// The ParallelTestRunner class + /// Contains all methods for running a file system test using parallel runner. + /// + class ParallelTestRunner : IFileSysTestRunner + { + // each test has a list of environments that it will run on + private readonly Dictionary> _environments; + private readonly IAssetRunner _runner; + private readonly McConnectionInfo _mcConnectionInfo; + private const string ParallelRunnerExecutable = "ParallelRunner.exe"; + private string _parallelRunnerPath; + private RunCancelledDelegate _runCancelled; + private const int PollingTimeMs = 500; + private readonly bool _canRun = false; + private const string ParallelRunnerArguments = "-o static -c \"{0}\""; + + private List _configFiles = new List(); + private IProcessAdapter _processAdapter; + private readonly Type _qtType = Type.GetTypeFromProgID("Quicktest.Application"); + private RunAsUser _uftRunAsUser; + + public ParallelTestRunner(IAssetRunner runner, McConnectionInfo mcConnectionInfo, Dictionary> environments, RunAsUser uftRunAsUser) + { + _runner = runner; + _mcConnectionInfo = mcConnectionInfo; + _environments = environments; + _canRun = TrySetupParallelRunner(); + _uftRunAsUser = uftRunAsUser; + } + + /// + /// Tries to find the parallel runner executable. + /// + /// + /// True if the executable has been found,False otherwise + /// + private bool TrySetupParallelRunner() + { + _parallelRunnerPath = Helper.GetParallelRunnerDirectory(ParallelRunnerExecutable); + + ConsoleWriter.WriteLine("Attempting to start parallel runner from: " + _parallelRunnerPath); + + return _parallelRunnerPath != null && File.Exists(_parallelRunnerPath); + } + + /// + /// Set the test run results based on the parallel runner exit code. + /// + /// + /// + /// + /// + private void RunResultsFromParallelRunnerExitCode(TestRunResults runResults, int exitCode, string failureReason, ref string errorReason) + { + // set the status of the build based on the exit code + switch (exitCode) + { + case (int)ParallelRunResult.Pass: + runResults.TestState = TestState.Passed; + break; + case (int)ParallelRunResult.Warning: + runResults.TestState = TestState.Warning; + break; + case (int)ParallelRunResult.Fail: + runResults.ErrorDesc = "ParallelRunner test has FAILED!"; + runResults.TestState = TestState.Failed; + break; + case (int)ParallelRunResult.Cancelled: + runResults.ErrorDesc = "ParallelRunner was stopped since job has timed out!"; + ConsoleWriter.WriteErrLine(runResults.ErrorDesc); + runResults.TestState = TestState.Error; + break; + case (int)ParallelRunResult.Error: + errorReason = failureReason; + runResults.ErrorDesc = errorReason; + ConsoleWriter.WriteErrLine(runResults.ErrorDesc); + runResults.TestState = TestState.Error; + break; + default: + ConsoleWriter.WriteErrLine(errorReason); + runResults.ErrorDesc = errorReason; + runResults.TestState = TestState.Error; + break; + } + } + + /// + /// Runs the provided test on all the environments. + /// + /// The test information. + /// failure reason + /// delegate to RunCancelled + /// + /// The run results for the current test. + /// + public TestRunResults RunTest(TestInfo testInfo, ref string errorReason, RunCancelledDelegate runCancelled, out Dictionary outParams) + { + outParams = new Dictionary(); + + testInfo.ReportPath = testInfo.TestPath + @"\ParallelReport"; + + // this is to make sure that we do not overwrite the report + // when we run the same test multiple times on the same build + string resFolder = Helper.GetNextResFolder(testInfo.ReportPath, "Res"); + + var runResults = new TestRunResults + { + ReportLocation = testInfo.ReportPath, + ErrorDesc = errorReason, + TestState = TestState.Unknown, + TestPath = testInfo.TestPath, + TestType = TestType.ParallelRunner + }; + + // set the active test run + ConsoleWriter.ActiveTestRun = runResults; + + if (!_canRun) + { + ConsoleWriter.WriteLine("Could not find parallel runner executable!"); + errorReason = Resources.ParallelRunnerExecutableNotFound; + runResults.TestState = TestState.Error; + runResults.ErrorDesc = errorReason; + return runResults; + } + + // Try to create the ParalleReport path + try + { + Directory.CreateDirectory(runResults.ReportLocation); + } + catch (Exception) + { + errorReason = string.Format(Resources.FailedToCreateTempDirError, runResults.ReportLocation); + runResults.TestState = TestState.Error; + runResults.ErrorDesc = errorReason; + + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + return runResults; + } + + ConsoleWriter.WriteLineWithTime("Using ParallelRunner to execute test: " + testInfo.TestPath); + + _runCancelled = runCancelled; + + // prepare the json file for the process + string configFilePath; + + try + { + configFilePath = ParallelRunnerEnvironmentUtil.GetConfigFilePath(testInfo, _mcConnectionInfo, _environments); + _configFiles.Add(configFilePath); + } + catch (ParallelRunnerConfigurationException ex) // invalid configuration + { + errorReason = ex.Message; + runResults.ErrorDesc = errorReason; + runResults.TestState = TestState.Error; + return runResults; + } + + // Parallel runner argument "-c" for config path and "-o static" so that + // the output from ParallelRunner is compatible with Jenkins + var arguments = string.Format(ParallelRunnerArguments, configFilePath); + + // the test can be started now + runResults.TestState = TestState.Running; + + var runTime = new Stopwatch(); + runTime.Start(); + + string failureReason = null; + runResults.ErrorDesc = null; + + // execute parallel runner and get the run result status + int exitCode = ExecuteProcess(arguments, ref failureReason); + + // set the status of the build based on the exit code + RunResultsFromParallelRunnerExitCode(runResults, exitCode, failureReason, ref errorReason); + + // update the run time + runResults.Runtime = runTime.Elapsed; + + // update the report location as the report should be + // generated by now + runResults.ReportLocation = resFolder; + + return runResults; + } + + public void CleanUp() + { + // DONT'T remove the json files from _configFiles as they are useful for troubleshooting + } + + private void CloseUft() + { + try + { + var qtpApplication = Activator.CreateInstance(_qtType) 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) + } + } + + public void SafelyCancel() + { + ConsoleWriter.WriteLine(Resources.GeneralStopAborted); + CloseUft(); + if (_processAdapter != null && !_processAdapter.HasExited) + { + try + { + _processAdapter.Close(); + } + catch + { + _processAdapter.Kill(); + } + } + CleanUp(); + ConsoleWriter.WriteLine(Resources.GeneralAbortedByUser); + } + + #region Process + + /// + /// Check if the parent of the current process is running in the user session. + /// + /// true if the parent process is running in the user session, false otherwise. + private bool IsParentProcessRunningInUserSession() + { + Process currentProcess = Process.GetCurrentProcess(); + Process parentProcess = currentProcess.Parent(); + + Process[] explorers; + try + { + explorers = Process.GetProcessesByName("explorer"); + } + catch (InvalidOperationException) + { + // try to start the process from the current session + return true; + } + + // could not retrieve the explorer process + if (explorers == null || explorers.Length == 0) + { + // try to start the process from the current session + return true; + } + + // if they are not in the same session we will assume it is a service + return explorers.Where(p => p.SessionId == parentProcess.SessionId).Any(); + } + + /// + /// Return the corresponding process object based on the type of jenkins instance. + /// + /// the filename to be ran + /// the arguments for the process + /// the corresponding process type, based on the jenkins instance + private object GetProcessTypeForCurrentSession(string fileName, string arguments) + { + try + { + //print command line + ConsoleWriter.WriteLineWithTime(string.Format("{0} {1}", fileName, arguments)); + + if (IsParentProcessRunningInUserSession()) + { + return InitProcess(fileName, arguments); + } + + if (_uftRunAsUser != null) + { + ConsoleWriter.WriteLine("Starting ParallelRunner as different user from service session is not supported at this moment."); + return null; + } + ConsoleWriter.WriteLine("Starting ParallelRunner from service session!"); + + // the process must be started in the user session + return new ElevatedProcess(fileName, arguments, Helper.GetSTInstallPath()); + } + catch (Exception) + { + return null; + } + } + + /// + /// executes the run of the test by using the Init and RunProcss routines + /// + /// the arguments for the process + /// the reason why the process failed + /// the exit code of the process + private int ExecuteProcess(string arguments, ref string failureReason) + { + _processAdapter = ProcessAdapterFactory.CreateAdapter(GetProcessTypeForCurrentSession(_parallelRunnerPath, arguments)); + + if (_processAdapter == null) + { + failureReason = "Could not create ProcessAdapter instance!"; + return (int)ParallelRunResult.Error; + } + + try + { + int exitCode = RunProcess(_processAdapter); + + if (_runCancelled()) + { + if (!_processAdapter.HasExited) + { + _processAdapter.Kill(); + return (int)ParallelRunResult.Cancelled; + } + } + + return exitCode; + } + catch (Exception e) + { + failureReason = e.Message; + return (int)ParallelRunResult.Error; + } + finally + { + if (_processAdapter != null) + { + _processAdapter.Close(); + } + } + } + + /// + /// Initializes the ParallelRunner process + /// + /// the file name + /// the process arguments + private Process InitProcess(string fileName, string arguments) + { + var info = new ProcessStartInfo + { + FileName = fileName, + Arguments = arguments, + WorkingDirectory = Directory.GetCurrentDirectory(), + WindowStyle = ProcessWindowStyle.Hidden + }; + if (_uftRunAsUser != null) + { + info.UserName = _uftRunAsUser.Username; + info.Password = _uftRunAsUser.Password; + info.UseShellExecute = false; + info.RedirectStandardOutput = true; + info.RedirectStandardError = true; + } + + Process p = new Process { StartInfo = info }; + p.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Console.Error.WriteLine(e.Data); }; + p.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Console.Out.WriteLine(e.Data); }; + return p; + } + + /// + /// runs the ParallelRunner process after initialization + /// + /// + /// + private int RunProcess(IProcessAdapter proc) + { + proc.Start(); + + proc.WaitForExit(PollingTimeMs); + + while (!_runCancelled() && !proc.HasExited) + { + proc.WaitForExit(PollingTimeMs); + } + + return proc.ExitCode; + } + + #endregion + } + + public enum ParallelRunResult : int + { + Pass = 1004, + Warning = 1005, + Fail = 1006, + Cancelled = 1007, + Error = 1008, + } +} \ No newline at end of file diff --git a/HpToolsLauncher/TestRunners/PerformanceTestRunner.cs b/HpToolsLauncher/TestRunners/PerformanceTestRunner.cs index bc5a42aec1..7bfb40da25 100644 --- a/HpToolsLauncher/TestRunners/PerformanceTestRunner.cs +++ b/HpToolsLauncher/TestRunners/PerformanceTestRunner.cs @@ -1,965 +1,1024 @@ -//© 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. - - - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; -using HP.LoadRunner.Interop.Wlrun; -using HpToolsLauncher.Properties; -using System.Xml; -using System.Security.AccessControl; -//using Analysis.Api; - -namespace HpToolsLauncher.TestRunners -{ - - - public class PerformanceTestRunner : IFileSysTestRunner - { - public const string LRR_FOLDER = "LRR"; - public const string LRA_FOLDER = "LRA"; - public const string HTML_FOLDER = "HTML"; - public const string ANALYSIS_LAUNCHER = @".\LRAnalysisLauncher.exe"; - - private IAssetRunner _runner; - private TimeSpan _timeout; - private int _pollingInterval; - private TimeSpan _perScenarioTimeOutMinutes; - private RunCancelledDelegate _runCancelled; - - private bool _scenarioEnded; - private bool _scenarioEndedEvent; - private LrEngine _engine; - private Stopwatch _stopWatch; - private string _resultsFolder; - private string _controller_result_dir; - private List _ignoreErrorStrings; - - private enum VuserStatus - { - Down = 1, - Pending = 2, - Init = 3, - Ready = 4, - Run = 5, - Rendez = 6, - Passed = 7, - Failed = 8, - Error = 9, - GradualExiting = 12, - Exiting = 10, - Stopped = 11 - }; - private int[] _vuserStatus = new int[13]; - - private enum ERRORState { Ignore, Error }; - - private class ControllerError - { - public ERRORState state { get; set; } - public int occurences { get; set; } - }; - - Dictionary _errors; - int _errorsCount; - - - - - public PerformanceTestRunner(IAssetRunner runner, TimeSpan timeout, int pollingInterval, TimeSpan perScenarioTimeOut, List ignoreErrorStrings) - { - this._runner = runner; - this._timeout = timeout; - this._pollingInterval = pollingInterval; - this._perScenarioTimeOutMinutes = perScenarioTimeOut; - this._ignoreErrorStrings = ignoreErrorStrings; - this._scenarioEnded = false; - _engine = null; - this._errors = null; - this._errorsCount = 0; - } - - public TestRunResults RunTest(TestInfo scenarioInf, ref string errorReason, RunCancelledDelegate runCancelled) - { - string scenarioPath = scenarioInf.TestPath; - //prepare the instance that will contain test results for JUnit - TestRunResults runDesc = new TestRunResults(); - - ConsoleWriter.ActiveTestRun = runDesc; - ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running: " + scenarioPath); - - runDesc.TestType = TestType.LoadRunner.ToString(); - _resultsFolder = Helper.GetTempDir(); - - //a directory with this name may already exist. try to delete it. - if (Directory.Exists(_resultsFolder)) - { - try - { - // Directory.Delete(_resultsFolder, true); - DirectoryInfo dir = new DirectoryInfo(_resultsFolder); - dir.GetFiles().ToList().ForEach(file => file.Delete()); - dir.GetDirectories().ToList().ForEach(subdir => subdir.Delete()); - } - catch (Exception) - { - Console.WriteLine(string.Format(Resources.CannotDeleteReportFolder, _resultsFolder)); - } - - } - else - { - try - { - Directory.CreateDirectory(_resultsFolder); - } - catch (Exception e) - { - errorReason = string.Format(Resources.FailedToCreateTempDirError, _resultsFolder); - runDesc.TestState = TestState.Error; - runDesc.ErrorDesc = errorReason; - - Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; - return runDesc; - } - } - //create LRR folder: - _controller_result_dir = Path.Combine(_resultsFolder, LRR_FOLDER); - - - Directory.CreateDirectory(_controller_result_dir); - - //init result params - runDesc.ErrorDesc = errorReason; - runDesc.TestPath = scenarioPath; - runDesc.TestState = TestState.Unknown; - - if (!Helper.isLoadRunnerInstalled()) - { - runDesc.TestState = TestState.Error; - runDesc.ErrorDesc = string.Format(Resources.LoadRunnerNotInstalled, System.Environment.MachineName); - ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); - Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; - return runDesc; - } - - //from here on, we may delegate runCancelled(). - _runCancelled = runCancelled; - - //start scenario stop watch - Stopwatch scenarioStopWatch = Stopwatch.StartNew(); - - //set state to running - runDesc.TestState = TestState.Running; - - //and run the scenario - bool res = runScenario(scenarioPath, ref errorReason, runCancelled); - - if (!res) - { - //runScenario failed. print the error and set test as failed - ConsoleWriter.WriteErrLine(errorReason); - runDesc.TestState = TestState.Error; - runDesc.ErrorDesc = errorReason; - runDesc.Runtime = scenarioStopWatch.Elapsed; - - //and try to close the controller - closeController(); - return runDesc; - } - else - { - try - { - ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator); - runDesc.ReportLocation = _resultsFolder; - ConsoleWriter.WriteLine(Resources.LrAnalysingResults); - - //close the controller, so Analysis can be opened - ConsoleWriter.WriteLine("closing Controller"); - closeController(); - ConsoleWriter.WriteLine("Controller closed"); - - //generate report using Analysis: - ConsoleWriter.WriteLine("calling analysis report generator"); - generateAnalysisReport(runDesc); - ConsoleWriter.WriteLine("analysis report generator finished"); - - - //check for errors: - if (File.Exists(Path.Combine(_resultsFolder, "errors.xml"))) - { - checkForErrors(); - } - - ConsoleWriter.WriteLine(Resources.LRErrorsSummary); - - //count how many ignorable errors and how many fatal errors occured. - int ignore = getErrorsCount(ERRORState.Ignore); - int fatal = getErrorsCount(ERRORState.Error); - runDesc.FatalErrors = fatal; - ConsoleWriter.WriteLine(String.Format(Resources.LrErrorSummeryNum, ignore, fatal)); - ConsoleWriter.WriteLine(""); - if (_errors != null && _errors.Count > 0) - { - foreach (ERRORState state in Enum.GetValues(typeof(ERRORState))) - { - ConsoleWriter.WriteLine(printErrorSummary(state)); - } - } - - //if scenario ended with fatal errors, change test state - if (fatal > 0) - { - ConsoleWriter.WriteErrLine(string.Format(Resources.LRTestFailDueToFatalErrors, fatal)); - errorReason = buildErrorReasonForErrors(); - runDesc.TestState = TestState.Failed; - } - else if (ignore > 0) - { - ConsoleWriter.WriteLine(string.Format(Resources.LRTestWarningDueToIgnoredErrors, ignore)); - runDesc.HasWarnings = true; - runDesc.TestState = TestState.Warning; - } - else - { - Console.WriteLine(Resources.LRTestPassed); - runDesc.TestState = TestState.Passed; - } - - } - catch (Exception e) - { - ConsoleWriter.WriteException(Resources.LRExceptionInAnalysisRunner, e); - runDesc.TestState = TestState.Error; - runDesc.ErrorDesc = Resources.LRExceptionInAnalysisRunner; - runDesc.Runtime = scenarioStopWatch.Elapsed; - } - - //runDesc.ReportLocation = _resultsFolder; - - } - - runDesc.Runtime = scenarioStopWatch.Elapsed; - if (!string.IsNullOrEmpty(errorReason)) - runDesc.ErrorDesc = errorReason; - KillController(); - return runDesc; - } - - private string buildErrorReasonForErrors() - { - //ConsoleWriter.WriteLine("building Error ResultString"); - string res = Resources.LRErrorReasonSummaryTitle; - res += printErrorSummary(ERRORState.Error); - return res; - } - - private string printErrorSummary(ERRORState state) - { - string res = ""; - List validKeys = (from x in _errors where x.Value.state == state select x.Key).ToList(); - if (validKeys.Count == 0) - { - return ""; - } - - res += state + " summary:\n"; - foreach (string errorString in validKeys) - { - res += (_errors[errorString].occurences + " : " + errorString) + "\n"; - } - return res; - } - - private bool runScenario(string scenario, ref string errorReason, RunCancelledDelegate runCancelled) - { - cleanENV(); - - ConsoleWriter.WriteLine(string.Format(Resources.LrInitScenario, scenario)); - - //start controller - _engine = new LrEngine(); - if (_engine == null) - { - errorReason = string.Format(Resources.LrFailToOpenController, scenario); - return false; - } - - //try to register the end scenario event: - _scenarioEndedEvent = false; - try - { - _engine.Events.ScenarioEvents.OnScenarioEnded += ScenarioEvents_OnScenarioEnded; - _scenarioEndedEvent = true; - } - catch (Exception e) - { - ConsoleWriter.WriteException(Resources.LrFailToRegisterEndScenarioEvent, e); - _scenarioEndedEvent = false; - } - - _engine.ShowMainWindow(0); -#if DEBUG - _engine.ShowMainWindow(1); -#endif - //pointer to the scenario object: - LrScenario currentScenario = _engine.Scenario; - - //try to open the scenario and validate the scenario and connect to load generators - if (openScenario(scenario, ref errorReason) && validateScenario(currentScenario, ref errorReason)) - { - //set the result dir: - ConsoleWriter.WriteLine("setting scenario result folder to " + Path.Combine(_resultsFolder, LRR_FOLDER)); - currentScenario.ResultDir = Path.Combine(_resultsFolder, LRR_FOLDER); - ConsoleWriter.WriteLine("scenario result folder: " + currentScenario.ResultDir); - - //check if canceled or timedOut: - if (_runCancelled()) - { - errorReason = Resources.GeneralTimedOut; - return false; - } - - _scenarioEnded = false; - - ConsoleWriter.WriteLine(Resources.LrStartScenario); - - int ret = currentScenario.Start(); - - if (!currentScenario.ResultDir.Equals(Path.Combine(_resultsFolder, LRR_FOLDER))) - { - ConsoleWriter.WriteLine("controller failed to write to " + Path.Combine(_resultsFolder, LRR_FOLDER) + " setting result folder to " + currentScenario.ResultDir); - _controller_result_dir = new DirectoryInfo(currentScenario.ResultDir).Name; - ConsoleWriter.WriteLine("controller reult dir: " + _controller_result_dir); - } - - - if (ret != 0) - { - errorReason = string.Format(Resources.LrStartScenarioFail, scenario, ret); - return false; - } - //per scenario timeout stopwatch - _stopWatch = Stopwatch.StartNew(); - //wait for scenario to end: - if (!waitForScenario(ref errorReason)) - { - //something went wrong during scenario execution, error reason set in errorReason string - return false; - } - else - {//scenario has ended - Console.WriteLine(string.Format(Resources.LrScenarioEnded, scenario,_stopWatch.Elapsed.Hours,_stopWatch.Elapsed.Minutes, _stopWatch.Elapsed.Seconds)); - - //collate results - collateResults(); - } - } - else - { - return false; - } - - return true; - } - - private bool openScenario(string scenario, ref string errorReason) - { - int ret; - try - { - ThreadStart tstart = () => - { - try - { - ret = _engine.Scenario.Open(scenario, false); - if (ret != 0) - { - throw new Exception(ret.ToString()); - } - } - catch (Exception) { } - }; - Thread t = new Thread(tstart); - t.Start(); - if (!t.Join(_pollingInterval * 1000 * 2)) - { - errorReason = "cannot open scenario - timeout!"; - return false; - } - } - catch (Exception e) - { - errorReason = string.Format(Resources.LrFailedToOpenScenario, scenario, int.Parse(e.Message)); - return false; - } - return true; - } - - - - private void generateAnalysisReport(TestRunResults runDesc) - { - string lrrLocation = Path.Combine(runDesc.ReportLocation, LRR_FOLDER, LRR_FOLDER + ".lrr"); - string lraLocation = Path.Combine(runDesc.ReportLocation, LRA_FOLDER, LRA_FOLDER + ".lra"); - string htmlLocation = Path.Combine(runDesc.ReportLocation, HTML_FOLDER, HTML_FOLDER + ".html"); - - ProcessStartInfo analysisRunner = new ProcessStartInfo(); - analysisRunner.FileName = ANALYSIS_LAUNCHER; - analysisRunner.Arguments = "\""+lrrLocation + "\" \"" + lraLocation + "\" \"" + htmlLocation+"\""; - analysisRunner.UseShellExecute = false; - analysisRunner.RedirectStandardOutput = true; - - ConsoleWriter.WriteLine("executing Analysis launcher with arguments : "+analysisRunner.Arguments); - ConsoleWriter.WriteLine("time for analysis: " + _perScenarioTimeOutMinutes.ToString(@"dd\:\:hh\:mm\:ss")); - analysisRunner.RedirectStandardOutput = true; - analysisRunner.RedirectStandardError = true; - Process runner = Process.Start(analysisRunner); - if (runner != null) - { - runner.OutputDataReceived += runner_OutputDataReceived; - runner.ErrorDataReceived += runner_ErrorDataReceived; - runner.BeginOutputReadLine(); - runner.BeginErrorReadLine(); - Stopwatch analysisStopWatch = Stopwatch.StartNew(); - - while (!runner.WaitForExit(_pollingInterval * 1000) && analysisStopWatch.Elapsed < _perScenarioTimeOutMinutes) ; - - analysisStopWatch.Stop(); - runner.CancelOutputRead(); - runner.CancelErrorRead(); - ConsoleWriter.WriteLine("time passed: " + analysisStopWatch.Elapsed.ToString(@"dd\:\:hh\:mm\:ss")); - if (analysisStopWatch.Elapsed > _perScenarioTimeOutMinutes) - { - runDesc.ErrorDesc = Resources.LrAnalysisTimeOut; - ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); - runDesc.TestState = TestState.Error; - if (!runner.HasExited) - { - runner.Kill(); - } - } - //ConsoleWriter.WriteLine("checking error code"); - if (runner.ExitCode != (int)Launcher.ExitCodeEnum.Passed) - { - runDesc.ErrorDesc = Resources.LrAnalysisRunTimeError; - ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); - runDesc.TestState = TestState.Error; - } - //using (StreamReader reader = runner.StandardOutput) - //{ - // string result = reader.ReadToEnd(); - // ConsoleWriter.WriteLine(Resources.LrAnlysisResults); - // ConsoleWriter.WriteLine(""); - // ConsoleWriter.WriteLine(result); - //} - - } - else - { - runDesc.ErrorDesc = Resources.LrAnlysisInitFail; - ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); - runDesc.TestState = TestState.Error; - } - - } - - void runner_ErrorDataReceived(object sender, DataReceivedEventArgs errData) - { - if (!String.IsNullOrEmpty(errData.Data)) - ConsoleWriter.WriteErrLine(errData.Data); - } - - void runner_OutputDataReceived(object sender, DataReceivedEventArgs outLine) - { - if (!String.IsNullOrEmpty(outLine.Data)) - { - ConsoleWriter.WriteLine(outLine.Data); - } - } - - - private void collateResults() - { - int ret = _engine.Scenario.CollateResults(); - if (ret != 0) - { - ConsoleWriter.WriteErrLine(string.Format(Resources.LrScenarioCollateFail, ret)); - } - - while (!_engine.Scenario.IsResultsCollated() && _stopWatch.Elapsed < _perScenarioTimeOutMinutes) - { - - Stopper collateStopper = new Stopper(_pollingInterval * 1000); - collateStopper.Start(); - } - - } - - private void closeController() - { - //try to gracefully shut down the controller - if (_engine != null) - { - try - { - var process = Process.GetProcessesByName("Wlrun"); - if (process.Length > 0) - { - int rc = _engine.CloseController(); - if (rc != 0) - { - ConsoleWriter.WriteErrLine( - "\t\tFailed to close Controller with CloseController API function, rc: " + rc); - } - } - - //give the controller 15 secs to shutdown. otherwise, print an error. - Stopper controllerStopper = new Stopper(15000); - controllerStopper.Start(); - - if (_engine != null) - { - - process = Process.GetProcessesByName("Wlrun"); - if (process.Length > 0) - { - ConsoleWriter.WriteErrLine("\t\tThe Controller is still running..."); - Stopper wlrunStopper = new Stopper(10000); - wlrunStopper.Start(); - return; - } - } - } - catch (Exception e) - { - ConsoleWriter.WriteErrLine("\t\t Cannot close Controller gracefully, exception details:"); - ConsoleWriter.WriteErrLine(e.Message); - ConsoleWriter.WriteErrLine(e.StackTrace); - ConsoleWriter.WriteErrLine("killing Controller process"); - cleanENV(); - } - } - _engine = null; - } - - private void closeController_Kill() - { - //try to gracefully shut down the controller - if (_engine != null) - { - try - { - var process = Process.GetProcessesByName("Wlrun"); - if (process.Length > 0) - { - int rc = _engine.CloseController(); - if (rc != 0) - { - ConsoleWriter.WriteErrLine( - "\t\tFailed to close Controller with CloseController API function, rc: " + rc); - } - } - - if (_engine != null) - { - - process = Process.GetProcessesByName("Wlrun"); - if (process.Length > 0) - { - ConsoleWriter.WriteErrLine("\t\tThe Controller is still running..."); - Stopper wlrunStopper = new Stopper(10000); - wlrunStopper.Start(); - KillController(); - return; - } - } - } - catch (Exception e) - { - ConsoleWriter.WriteErrLine("\t\t Cannot close Controller gracefully, exception details:"); - ConsoleWriter.WriteErrLine(e.Message); - ConsoleWriter.WriteErrLine(e.StackTrace); - ConsoleWriter.WriteErrLine("killing Controller process"); - cleanENV(); - } - } - _engine = null; - } - - void DoTask(Object state) - { - AutoResetEvent are = (AutoResetEvent) state; - - while (!_scenarioEnded) - { - if (!_scenarioEndedEvent) - { - //if all Vusers are in ending state, scenario is finished. - _scenarioEnded = isFinished(); - Thread.Sleep(5000); - } - } - are.Set(); - } - - AutoResetEvent autoEvent = new AutoResetEvent(false); - - - private bool waitForScenario(ref string errorReason) - { - ConsoleWriter.WriteLine("Scenario run has started"); - - ThreadPool.QueueUserWorkItem(DoTask, autoEvent); - - //wait for the scenario to end gracefully: - int time = _pollingInterval * 1000; - while (_stopWatch.Elapsed <= _perScenarioTimeOutMinutes) - { - if (_runCancelled()) - { - errorReason = Resources.GeneralTimedOut; - return false; - } - if (autoEvent.WaitOne(time)) - { - break; - } - } - - if (_stopWatch.Elapsed > _perScenarioTimeOutMinutes) - { - _stopWatch.Stop(); - ConsoleWriter.WriteErrLine(string.Format(Resources.LrScenarioTimeOut, _stopWatch.Elapsed.Seconds)); - errorReason = string.Format(Resources.LrScenarioTimeOut, _stopWatch.Elapsed.Seconds); - } - - - if (_scenarioEndedEvent) - { - try - { - //ConsoleWriter.WriteLine("unregistering event"); - _engine.Events.ScenarioEvents.OnScenarioEnded -= ScenarioEvents_OnScenarioEnded; - _scenarioEndedEvent = false; - } - catch { } - } - - //if scenario not ended until now, force stop it. - if (!_scenarioEnded) - { - - ConsoleWriter.WriteErrLine(Resources.LrScenarioTimeOut); - - int ret = _engine.Scenario.StopNow(); - if (ret != 0) - { - errorReason = string.Format(Resources.LrStopScenarioEnded); - return false; - } - - int tries = 2; - while (_engine.Scenario.IsActive() && tries > 0) - { - //ConsoleWriter.WriteLine("\t\tScenario is still running. Waiting for the scenario to stop..."); - Stopper wlrunStopper = new Stopper(_pollingInterval * 1000); - wlrunStopper.Start(); - tries--; - } - - if (_engine.Scenario.IsActive()) - { - errorReason = Resources.LrControllerFailedToStop; - return false; - } - } - - return true; - } - - private void checkForErrors() - { - //init variables - string message = null; - - XmlDocument errorsXML = new XmlDocument(); - errorsXML.Load(Path.Combine(_resultsFolder, "errors.xml")); - - _errors = new Dictionary(); - - //new unseen error(s) - foreach (XmlNode errorNode in errorsXML.DocumentElement.ChildNodes) - { - message = errorNode.InnerText; - - //ControllerError cerror; - //if error exist, just update the count: - bool added = false; - //check if the error is ignorable - foreach (string ignoreError in _ignoreErrorStrings) - { - if (message.ToLowerInvariant().Contains(ignoreError.ToLowerInvariant())) - { - ConsoleWriter.WriteLine(string.Format(Resources.LrErrorIgnored, message, ignoreError)); - if (_errors.ContainsKey(message)) - _errors[message].occurences++; - else - _errors.Add(message, new ControllerError { state = ERRORState.Ignore, occurences = 1 }); - added = true; - _errorsCount++; - } - } - - //error was not ignored, and was not added yet. add it now. - if (!added) - { - // non ignorable error message, - ConsoleWriter.WriteErrLine(message);//+ ", time " + time + ", host: " + host + ", VuserID: " + vuserId + ", script: " + script + ", line: " + line); - - if (_errors.ContainsKey(message)) - { - _errors[message].occurences++; - } - else - { - _errors.Add(message, new ControllerError { state = ERRORState.Error, occurences = 1 }); - } - _errorsCount++; - //if the scenario ended event was not registered, we need to provide the opportunity to check the vuser status. - //if (!_scenarioEndedEvent) - //{ - break; - //} - } - - } - ConsoleWriter.WriteErrLine("total number of errors: " + _errorsCount); - - - - } - - - private int getErrorsCount(ERRORState state) - { - return (_errors != null) ? (from x in _errors where x.Value.state == state select x.Value.occurences).Sum() : 0; - } - - - - private void updateError(string message) - { - - ControllerError s = _errors[message]; - if (s != null) - { - s.occurences++; - _errors[message] = s; - } - - } - - private void ScenarioEvents_OnScenarioEnded() - { - //ConsoleWriter.WriteLine("scenario ended event"); - _scenarioEnded = true; - - } - - - private bool isFinished() - { - updateVuserStatus(); - bool isFinished = false; - - isFinished = _vuserStatus[(int)VuserStatus.Down] == 0 && - _vuserStatus[(int)VuserStatus.Pending] == 0 && - _vuserStatus[(int)VuserStatus.Init] == 0 && - _vuserStatus[(int)VuserStatus.Ready] == 0 && - _vuserStatus[(int)VuserStatus.Run] == 0 && - _vuserStatus[(int)VuserStatus.Rendez] == 0 && - _vuserStatus[(int)VuserStatus.Exiting] == 0 && - _vuserStatus[(int)VuserStatus.GradualExiting] == 0; - - return isFinished; - } - - private void printVusersStatus() - { - Console.WriteLine("Vusers status:"); - string res = ""; - foreach (var val in Enum.GetValues(typeof(VuserStatus))) - { - res += ((VuserStatus)val) + ": " + _vuserStatus[(int)val] + " , "; - } - res = res.Substring(0, res.LastIndexOf(",")); - ConsoleWriter.WriteLine(res); - } - - private void updateVuserStatus() - { - foreach (int val in Enum.GetValues(typeof(VuserStatus))) - { - _vuserStatus[val] = _engine.Scenario.GetVusersCount(val); - } - } - - private bool validateScenario(LrScenario scenario, ref string errorReason) - { - - //validate that scenario has SLA - if (!scenario.DoesScenarioHaveSLAConfiguration()) - { - errorReason = string.Format(Resources.LrScenarioValidationFailNoSLA, scenario.FileName); - return false; - - } - //validate that all scripts are available. - if (!scenario.AreScriptsAccessible(out errorReason)) - { - //error message in errorReason - return false; - } - - //validate that scenario has time limited schedule: - if (!scenario.DoesScenarioHaveLimitedSchedule(out errorReason)) - { - //error message in errorReason - return false; - } - - //validate LGs: - if (scenario.Hosts.Count == 0) - { - errorReason = string.Format(Resources.LrScenarioValidationFailNoLGs, scenario.FileName); - return false; - } - - //connect to all active load generators == hosts: - int ret; - foreach (LrHost lg in scenario.Hosts) - { - //handle only active hosts - if (lg.IsUsed()) - { - //connect to the host - ret = lg.Connect(); - if (ret != 0) - { - errorReason = string.Format(Resources.LrScenarioValidationCannotConnectLG, lg.Name); - return false; - } - - //sync with the host - ret = lg.Sync(60); - if (ret <= 0) - { - errorReason = string.Format(Resources.LrScenarioValidationCannotSyncLG, lg.Name); ; - return false; - } - - //if host is not ready after sync, invalidate the test - if (lg.Status != LrHostStatus.lrHostReady) - { - errorReason = string.Format(Resources.LrScenarioValidationLGNotReady, lg.Name); - return false; - } - - //if we got this far, lg is connected and ready to go - ConsoleWriter.WriteLine(string.Format(Resources.LrScenarioValidationLGConnected, lg.Name)); - } - } - return true; - } - - private void cleanENV() - { - ConsoleWriter.WriteLine(Resources.LrCleanENV); - try - { - // check if any mdrv.exe process existed, kill them. - var mdrvProcesses = Process.GetProcessesByName("mdrv"); - foreach (Process p in mdrvProcesses) - { - p.Kill(); - Stopper stopper = new Stopper(500); - stopper.Start(); - - - } - - // check if any wlrun.exe process existed, kill them. - - KillController(); - } - catch (Exception e) - { - - } - } - - private static void KillController() - { - var wlrunProcesses = Process.GetProcessesByName("Wlrun"); - if (wlrunProcesses.Length > 0) - { - foreach (Process p in wlrunProcesses) - { - p.Kill(); - // When kill wlrun process directly, there might be a werfault.exe process generated, kill it if it appears. - DateTime nowTime = DateTime.Now; - while (DateTime.Now.Subtract(nowTime).TotalSeconds < 10) - { - var werFaultProcesses = Process.GetProcessesByName("WerFault"); - if (werFaultProcesses.Length > 0) - { - //Console.WriteLine("Kill process of WerFault"); - foreach (Process pf in werFaultProcesses) - { - pf.Kill(); - } - break; - } - Stopper werFaultProcessesStopper = new Stopper(2000); - werFaultProcessesStopper.Start(); - } - Stopper wlrunStopper = new Stopper(2000); - wlrunStopper.Start(); - } - ConsoleWriter.WriteLine("wlrun killed"); - } - } - - public void CleanUp() - { - //ConsoleWriter.WriteLine("clenUp"); - - //ConsoleWriter.WriteLine("Closing controller"); - closeController(); - cleanENV(); - } - - } -} +/* + * 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 HpToolsLauncher.Properties; +using HpToolsLauncher.RTS; +using HpToolsLauncher.Utils; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Xml; + +namespace HpToolsLauncher.TestRunners +{ + + + public class PerformanceTestRunner : IFileSysTestRunner + { + public const string LRR_FOLDER = "LRR"; + public const string LRA_FOLDER = "LRA"; + public const string HTML_FOLDER = "HTML"; + public const string ANALYSIS_LAUNCHER = @".\LRAnalysisLauncher.exe"; + + private IAssetRunner _runner; + private TimeSpan _timeout; + private int _pollingInterval; + private TimeSpan _perScenarioTimeOutMinutes; + private RunCancelledDelegate _runCancelled; + private bool _displayController; + private string _analysisTemplate; + private SummaryDataLogger _summaryDataLogger; + private List _scriptRTSSet; + + private bool _scenarioEnded; + private bool _scenarioEndedEvent; + private LrEngine _engine; + private Stopwatch _stopWatch; + private string _resultsFolder; + private string _controller_result_dir; + private List _ignoreErrorStrings; + + private enum VuserStatus + { + Down = 1, + Pending = 2, + Init = 3, + Ready = 4, + Run = 5, + Rendez = 6, + Passed = 7, + Failed = 8, + Error = 9, + GradualExiting = 12, + Exiting = 10, + Stopped = 11 + }; + private int[] _vuserStatus = new int[13]; + + private enum ERRORState { Ignore, Error }; + + private class ControllerError + { + public ERRORState state { get; set; } + public int occurences { get; set; } + }; + + Dictionary _errors; + int _errorsCount; + + public PerformanceTestRunner(IAssetRunner runner, TimeSpan timeout, int pollingInterval, TimeSpan perScenarioTimeOut, List ignoreErrorStrings, bool displayController, string analysisTemplate, SummaryDataLogger summaryDataLogger, List scriptRTSSet) + { + this._runner = runner; + this._timeout = timeout; + this._pollingInterval = pollingInterval; + this._perScenarioTimeOutMinutes = perScenarioTimeOut; + this._ignoreErrorStrings = ignoreErrorStrings; + this._displayController = displayController; + this._analysisTemplate = analysisTemplate; + this._summaryDataLogger = summaryDataLogger; + this._scriptRTSSet = scriptRTSSet; + + this._scenarioEnded = false; + _engine = null; + this._errors = null; + this._errorsCount = 0; + } + + public TestRunResults RunTest(TestInfo scenarioInf, ref string errorReason, RunCancelledDelegate runCancelled, out Dictionary outParams) + { + outParams = new Dictionary(); + string scenarioPath = scenarioInf.TestPath; + //prepare the instance that will contain test results for JUnit + TestRunResults runDesc = new TestRunResults { TestType = TestType.LoadRunner }; + + ConsoleWriter.ActiveTestRun = runDesc; + ConsoleWriter.WriteLineWithTime("Running: " + scenarioPath); + + _resultsFolder = Helper.GetTempDir(); + if (!scenarioInf.ReportPath.IsNullOrEmpty()) + { + _resultsFolder = scenarioInf.ReportPath; + } + + //a directory with this name may already exist. try to delete it. + if (Directory.Exists(_resultsFolder)) + { + try + { + // Directory.Delete(_resultsFolder, true); + DirectoryInfo dir = new DirectoryInfo(_resultsFolder); + dir.GetFiles().ToList().ForEach(file => file.Delete()); + dir.GetDirectories().ToList().ForEach(subdir => subdir.Delete()); + } + catch (Exception) + { + Console.WriteLine(string.Format(Resources.CannotDeleteReportFolder, _resultsFolder)); + } + } + else + { + try + { + Directory.CreateDirectory(_resultsFolder); + } + catch + { + errorReason = string.Format(Resources.FailedToCreateTempDirError, _resultsFolder); + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = errorReason; + + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + return runDesc; + } + } + //create LRR folder: + _controller_result_dir = Path.Combine(_resultsFolder, LRR_FOLDER); + + Directory.CreateDirectory(_controller_result_dir); + + //init result params + runDesc.ErrorDesc = errorReason; + runDesc.TestPath = scenarioPath; + ConsoleWriter.WriteLine(runDesc.TestPath); + runDesc.TestState = TestState.Unknown; + + if (!Helper.isLoadRunnerInstalled()) + { + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = string.Format(Resources.LoadRunnerNotInstalled, System.Environment.MachineName); + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + return runDesc; + } + + //from here on, we may delegate runCancelled(). + _runCancelled = runCancelled; + + //start scenario stop watch + Stopwatch scenarioStopWatch = Stopwatch.StartNew(); + + //set state to running + runDesc.TestState = TestState.Running; + + //and run the scenario + bool res = runScenario(scenarioPath, ref errorReason, runCancelled); + + if (!res) + { + //runScenario failed. print the error and set test as failed + ConsoleWriter.WriteErrLine(errorReason); + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = errorReason; + runDesc.Runtime = scenarioStopWatch.Elapsed; + + //and try to close the controller + closeController(); + return runDesc; + } + else + { + try + { + ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator); + runDesc.ReportLocation = _resultsFolder; + ConsoleWriter.WriteLine(Resources.LrAnalysingResults); + + //close the controller, so Analysis can be opened + ConsoleWriter.WriteLine("closing Controller"); + closeController(); + ConsoleWriter.WriteLine("Controller closed"); + + //generate report using Analysis: + ConsoleWriter.WriteLine("calling analysis report generator"); + generateAnalysisReport(runDesc); + ConsoleWriter.WriteLine("analysis report generator finished"); + + //check for errors: + if (File.Exists(Path.Combine(_resultsFolder, "errors.xml"))) + { + checkForErrors(); + } + + ConsoleWriter.WriteLine(Resources.LRErrorsSummary); + + //count how many ignorable errors and how many fatal errors occured. + int ignore = getErrorsCount(ERRORState.Ignore); + int fatal = getErrorsCount(ERRORState.Error); + runDesc.FatalErrors = fatal; + ConsoleWriter.WriteLine(string.Format(Resources.LrErrorSummeryNum, ignore, fatal)); + ConsoleWriter.WriteLine(string.Empty); + if (_errors != null && _errors.Count > 0) + { + foreach (ERRORState state in Enum.GetValues(typeof(ERRORState))) + { + ConsoleWriter.WriteLine(printErrorSummary(state)); + } + } + + //if scenario ended with fatal errors, change test state + if (fatal > 0) + { + ConsoleWriter.WriteErrLine(string.Format(Resources.LRTestFailDueToFatalErrors, fatal)); + errorReason = buildErrorReasonForErrors(); + runDesc.TestState = TestState.Failed; + } + else if (ignore > 0) + { + ConsoleWriter.WriteLine(string.Format(Resources.LRTestWarningDueToIgnoredErrors, ignore)); + runDesc.HasWarnings = true; + runDesc.TestState = TestState.Warning; + } + else + { + Console.WriteLine(Resources.LRTestPassed); + runDesc.TestState = TestState.Passed; + } + } + catch (Exception e) + { + ConsoleWriter.WriteException(Resources.LRExceptionInAnalysisRunner, e); + runDesc.TestState = TestState.Error; + runDesc.ErrorDesc = Resources.LRExceptionInAnalysisRunner; + runDesc.Runtime = scenarioStopWatch.Elapsed; + } + + //runDesc.ReportLocation = _resultsFolder; + } + + runDesc.Runtime = scenarioStopWatch.Elapsed; + if (!string.IsNullOrEmpty(errorReason)) + runDesc.ErrorDesc = errorReason; + KillController(); + return runDesc; + } + + private string buildErrorReasonForErrors() + { + //ConsoleWriter.WriteLine("building Error ResultString"); + string res = Resources.LRErrorReasonSummaryTitle; + res += printErrorSummary(ERRORState.Error); + return res; + } + + private string printErrorSummary(ERRORState state) + { + string res = ""; + List validKeys = (from x in _errors where x.Value.state == state select x.Key).ToList(); + if (validKeys.Count == 0) + { + return ""; + } + + res += state + " summary:\n"; + foreach (string errorString in validKeys) + { + res += (_errors[errorString].occurences + " : " + errorString) + "\n"; + } + return res; + } + + private bool runScenario(string scenario, ref string errorReason, RunCancelledDelegate runCancelled) + { + cleanENV(); + + ConsoleWriter.WriteLine(string.Format(Resources.LrInitScenario, scenario)); + + //start controller + _engine = new LrEngine(); + if (_engine == null) + { + errorReason = string.Format(Resources.LrFailToOpenController, scenario); + return false; + } + + //try to register the end scenario event: + _scenarioEndedEvent = false; + try + { + _engine.Events.ScenarioEvents.OnScenarioEnded += ScenarioEvents_OnScenarioEnded; + _scenarioEndedEvent = true; + } + catch (Exception e) + { + ConsoleWriter.WriteException(Resources.LrFailToRegisterEndScenarioEvent, e); + _scenarioEndedEvent = false; + } + + + if (_displayController == true) + { + _engine.ShowMainWindow(1); + } + else + { + _engine.ShowMainWindow(0); + } + + //pointer to the scenario object: + LrScenario currentScenario = _engine.Scenario; + + //try to open the scenario and validate the scenario and connect to load generators + if (openScenario(scenario, ref errorReason) && validateScenario(currentScenario, ref errorReason)) + { + //apply rts to scripts + foreach (ScriptRTSModel scriptRTS in _scriptRTSSet) + { + try + { + LrScripts currentScripts = currentScenario.Scripts; + LrScript currentScript = currentScripts.Item[scriptRTS.GetScriptName()]; + string runtimeSettings = "", + actionLogic = ""; + currentScript.GetScriptRunTimeSettings(ref runtimeSettings, ref actionLogic); + RTSHelper rtsHelper = new RTSHelper(runtimeSettings, RTSHelper.COMMAND_ARGUMENTS, scriptRTS.GetKeyValuePairs()); + string updatedRuntimeSettings = rtsHelper.GetUpdatedIniFileText(); + currentScript.SetScriptRunTimeSettings(updatedRuntimeSettings, actionLogic); + } + catch (Exception e) + { + errorReason = string.Format(Resources.LrRTSError, scriptRTS.GetScriptName(), e.Message); + return false; + } + } + + //set the result dir: + ConsoleWriter.WriteLine("setting scenario result folder to " + Path.Combine(_resultsFolder, LRR_FOLDER)); + currentScenario.ResultDir = Path.Combine(_resultsFolder, LRR_FOLDER); + ConsoleWriter.WriteLine("scenario result folder: " + currentScenario.ResultDir); + + //check if canceled or timedOut: + if (_runCancelled()) + { + errorReason = Resources.GeneralTimedOut; + return false; + } + + _scenarioEnded = false; + + ConsoleWriter.WriteLine(Resources.LrStartScenario); + + int ret = currentScenario.Start(); + + if (!currentScenario.ResultDir.Equals(Path.Combine(_resultsFolder, LRR_FOLDER))) + { + ConsoleWriter.WriteLine("controller failed to write to " + Path.Combine(_resultsFolder, LRR_FOLDER) + " setting result folder to " + currentScenario.ResultDir); + _controller_result_dir = new DirectoryInfo(currentScenario.ResultDir).Name; + ConsoleWriter.WriteLine("controller reult dir: " + _controller_result_dir); + } + + if (ret != 0) + { + errorReason = string.Format(Resources.LrStartScenarioFail, scenario, ret); + return false; + } + //per scenario timeout stopwatch + _stopWatch = Stopwatch.StartNew(); + //wait for scenario to end: + if (!waitForScenario(ref errorReason)) + { + //something went wrong during scenario execution, error reason set in errorReason string + return false; + } + else + {//scenario has ended + Console.WriteLine(string.Format(Resources.LrScenarioEnded, scenario, _stopWatch.Elapsed.Hours, _stopWatch.Elapsed.Minutes, _stopWatch.Elapsed.Seconds)); + + //collate results + collateResults(); + } + } + else + { + return false; + } + + return true; + } + + private bool openScenario(string scenario, ref string errorReason) + { + int ret; + try + { + ThreadStart tstart = () => + { + try + { + ret = _engine.Scenario.Open(scenario, false); + if (ret != 0) + { + throw new Exception(ret.ToString()); + } + } + catch { } + }; + Thread t = new Thread(tstart); + t.Start(); + if (!t.Join(_pollingInterval * 1000 * 2)) + { + errorReason = "cannot open scenario - timeout!"; + return false; + } + } + catch (Exception e) + { + errorReason = string.Format(Resources.LrFailedToOpenScenario, scenario, int.Parse(e.Message)); + return false; + } + return true; + } + + private void LogDataDuringScenarioExecution() + { + ThreadStart summaryDataLoggingThread = () => + { + try + { + LrScenario currentScenario = _engine.Scenario; + + while (!_scenarioEnded) + { + _summaryDataLogger.LogSummaryData(currentScenario); + Thread.Sleep(_summaryDataLogger.GetPollingInterval()); + } + } + catch (Exception e) + { + ConsoleWriter.WriteErrLine(string.Format(Resources.LrSummaryDataLoggingError, e.Message)); + return; + } + }; + Thread t = new Thread(summaryDataLoggingThread); + t.Start(); + } + + private void generateAnalysisReport(TestRunResults runDesc) + { + string lrrLocation = Path.Combine(runDesc.ReportLocation, LRR_FOLDER, LRR_FOLDER + ".lrr"); + string lraLocation = Path.Combine(runDesc.ReportLocation, LRA_FOLDER, LRA_FOLDER + ".lra"); + string htmlLocation = Path.Combine(runDesc.ReportLocation, HTML_FOLDER, HTML_FOLDER + ".html"); + + ProcessStartInfo analysisRunner = new ProcessStartInfo(); + analysisRunner.FileName = ANALYSIS_LAUNCHER; + analysisRunner.Arguments = "\"" + lrrLocation + "\" \"" + lraLocation + "\" \"" + htmlLocation + "\" \"" + _analysisTemplate + "\""; + analysisRunner.UseShellExecute = false; + analysisRunner.RedirectStandardOutput = true; + + ConsoleWriter.WriteLine("executing Analysis launcher with arguments : " + analysisRunner.Arguments); + ConsoleWriter.WriteLine("time for analysis: " + _perScenarioTimeOutMinutes.ToString(@"dd\:\:hh\:mm\:ss")); + analysisRunner.RedirectStandardOutput = true; + analysisRunner.RedirectStandardError = true; + Process runner = Process.Start(analysisRunner); + if (runner != null) + { + runner.OutputDataReceived += runner_OutputDataReceived; + runner.ErrorDataReceived += runner_ErrorDataReceived; + runner.BeginOutputReadLine(); + runner.BeginErrorReadLine(); + Stopwatch analysisStopWatch = Stopwatch.StartNew(); + + while (!runner.WaitForExit(_pollingInterval * 1000) && analysisStopWatch.Elapsed < _perScenarioTimeOutMinutes) ; + + analysisStopWatch.Stop(); + runner.CancelOutputRead(); + runner.CancelErrorRead(); + ConsoleWriter.WriteLine("time passed: " + analysisStopWatch.Elapsed.ToString(@"dd\:\:hh\:mm\:ss")); + if (analysisStopWatch.Elapsed > _perScenarioTimeOutMinutes) + { + runDesc.ErrorDesc = Resources.LrAnalysisTimeOut; + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + runDesc.TestState = TestState.Error; + if (!runner.HasExited) + { + runner.Kill(); + } + } + //ConsoleWriter.WriteLine("checking error code"); + if (runner.ExitCode != (int)Launcher.ExitCodeEnum.Passed) + { + runDesc.ErrorDesc = Resources.LrAnalysisRunTimeError; + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + runDesc.TestState = TestState.Error; + } + //using (StreamReader reader = runner.StandardOutput) + //{ + // string result = reader.ReadToEnd(); + // ConsoleWriter.WriteLine(Resources.LrAnlysisResults); + // ConsoleWriter.WriteLine(""); + // ConsoleWriter.WriteLine(result); + //} + + } + else + { + runDesc.ErrorDesc = Resources.LrAnlysisInitFail; + ConsoleWriter.WriteErrLine(runDesc.ErrorDesc); + runDesc.TestState = TestState.Error; + } + + } + + void runner_ErrorDataReceived(object sender, DataReceivedEventArgs errData) + { + if (!errData.Data.IsNullOrEmpty()) + ConsoleWriter.WriteErrLine(errData.Data); + } + + void runner_OutputDataReceived(object sender, DataReceivedEventArgs outLine) + { + if (!outLine.Data.IsNullOrEmpty()) + { + ConsoleWriter.WriteLine(outLine.Data); + } + } + + private void collateResults() + { + int ret = _engine.Scenario.CollateResults(); + if (ret != 0) + { + ConsoleWriter.WriteErrLine(string.Format(Resources.LrScenarioCollateFail, ret)); + } + + while (!_engine.Scenario.IsResultsCollated() && _stopWatch.Elapsed < _perScenarioTimeOutMinutes) + { + + Stopper collateStopper = new Stopper(_pollingInterval * 1000); + collateStopper.Start(); + } + } + + private void closeController() + { + //try to gracefully shut down the controller + if (_engine != null) + { + try + { + var process = Process.GetProcessesByName("Wlrun"); + if (process.Length > 0) + { + int rc = _engine.CloseController(); + if (rc != 0) + { + ConsoleWriter.WriteErrLine( + "\t\tFailed to close Controller with CloseController API function, rc: " + rc); + } + } + + //give the controller 15 secs to shutdown. otherwise, print an error. + Stopper controllerStopper = new Stopper(15000); + controllerStopper.Start(); + + if (_engine != null) + { + + process = Process.GetProcessesByName("Wlrun"); + if (process.Length > 0) + { + ConsoleWriter.WriteErrLine("\t\tThe Controller is still running..."); + Stopper wlrunStopper = new Stopper(10000); + wlrunStopper.Start(); + return; + } + } + } + catch (Exception e) + { + ConsoleWriter.WriteErrLine("\t\t Cannot close Controller gracefully, exception details:"); + ConsoleWriter.WriteErrLine(e.Message); + ConsoleWriter.WriteErrLine(e.StackTrace); + ConsoleWriter.WriteErrLine("killing Controller process"); + cleanENV(); + } + } + _engine = null; + } + + private void closeController_Kill() + { + //try to gracefully shut down the controller + if (_engine != null) + { + try + { + var process = Process.GetProcessesByName("Wlrun"); + if (process.Length > 0) + { + int rc = _engine.CloseController(); + if (rc != 0) + { + ConsoleWriter.WriteErrLine( + "\t\tFailed to close Controller with CloseController API function, rc: " + rc); + } + } + + if (_engine != null) + { + + process = Process.GetProcessesByName("Wlrun"); + if (process.Length > 0) + { + ConsoleWriter.WriteErrLine("\t\tThe Controller is still running..."); + Stopper wlrunStopper = new Stopper(10000); + wlrunStopper.Start(); + KillController(); + return; + } + } + } + catch (Exception e) + { + ConsoleWriter.WriteErrLine("\t\t Cannot close Controller gracefully, exception details:"); + ConsoleWriter.WriteErrLine(e.Message); + ConsoleWriter.WriteErrLine(e.StackTrace); + ConsoleWriter.WriteErrLine("killing Controller process"); + cleanENV(); + } + } + _engine = null; + } + + void DoTask(Object state) + { + AutoResetEvent are = (AutoResetEvent)state; + + while (!_scenarioEnded) + { + //Currently logging events causes controller scenario end event to unregister causing hptoolslauncher to be stuck + if (!_scenarioEndedEvent || _summaryDataLogger.IsAnyDataLogged()) + { + //if all Vusers are in ending state, scenario is finished. + _scenarioEnded = isFinished(); + Thread.Sleep(5000); + } + } + are.Set(); + } + + AutoResetEvent autoEvent = new AutoResetEvent(false); + + private bool waitForScenario(ref string errorReason) + { + ConsoleWriter.WriteLine("Scenario run has started"); + + ThreadPool.QueueUserWorkItem(DoTask, autoEvent); + + //wait for the scenario to end gracefully: + int time = _pollingInterval * 1000; + + if (_summaryDataLogger.IsAnyDataLogged()) + { + LogDataDuringScenarioExecution(); + } + while (_stopWatch.Elapsed <= _perScenarioTimeOutMinutes) + { + if (_runCancelled()) + { + errorReason = Resources.GeneralTimedOut; + return false; + } + if (autoEvent.WaitOne(time)) + { + break; + } + } + + if (_stopWatch.Elapsed > _perScenarioTimeOutMinutes) + { + _stopWatch.Stop(); + errorReason = string.Format(Resources.LrScenarioTimeOut, _stopWatch.Elapsed.ToString("dd\\:hh\\:mm\\:ss")); + ConsoleWriter.WriteErrLine(errorReason); + } + + if (_scenarioEndedEvent) + { + try + { + //ConsoleWriter.WriteLine("unregistering event"); + _engine.Events.ScenarioEvents.OnScenarioEnded -= ScenarioEvents_OnScenarioEnded; + _scenarioEndedEvent = false; + } + catch { } + } + + //if scenario not ended until now, force stop it. + if (!_scenarioEnded) + { + int ret = _engine.Scenario.StopNow(); + if (ret != 0) + { + errorReason = string.Format(Resources.LrStopScenarioEnded); + return false; + } + + int tries = 2; + while (_engine.Scenario.IsActive() && tries > 0) + { + //ConsoleWriter.WriteLine("\t\tScenario is still running. Waiting for the scenario to stop..."); + Stopper wlrunStopper = new Stopper(_pollingInterval * 1000); + wlrunStopper.Start(); + tries--; + } + + if (_engine.Scenario.IsActive()) + { + errorReason = Resources.LrControllerFailedToStop; + return false; + } + } + + return true; + } + + private void checkForErrors() + { + //init variables + string message = null; + + XmlDocument errorsXML = new XmlDocument(); + errorsXML.Load(Path.Combine(_resultsFolder, "errors.xml")); + + _errors = new Dictionary(); + + //new unseen error(s) + foreach (XmlNode errorNode in errorsXML.DocumentElement.ChildNodes) + { + message = errorNode.InnerText; + + //ControllerError cerror; + //if error exist, just update the count: + bool added = false; + //check if the error is ignorable + foreach (string ignoreError in _ignoreErrorStrings) + { + if (message.ToLowerInvariant().Contains(ignoreError.ToLowerInvariant())) + { + ConsoleWriter.WriteLine(string.Format(Resources.LrErrorIgnored, message, ignoreError)); + if (_errors.ContainsKey(message)) + _errors[message].occurences++; + else + _errors.Add(message, new ControllerError { state = ERRORState.Ignore, occurences = 1 }); + added = true; + _errorsCount++; + } + } + + //error was not ignored, and was not added yet. add it now. + if (!added) + { + // non ignorable error message, + ConsoleWriter.WriteErrLine(message);//+ ", time " + time + ", host: " + host + ", VuserID: " + vuserId + ", script: " + script + ", line: " + line); + + if (_errors.ContainsKey(message)) + { + _errors[message].occurences++; + } + else + { + _errors.Add(message, new ControllerError { state = ERRORState.Error, occurences = 1 }); + } + _errorsCount++; + //if the scenario ended event was not registered, we need to provide the opportunity to check the vuser status. + //if (!_scenarioEndedEvent) + //{ + break; + //} + } + + } + ConsoleWriter.WriteErrLine("total number of errors: " + _errorsCount); + } + + private int getErrorsCount(ERRORState state) + { + return (_errors != null) ? (from x in _errors where x.Value.state == state select x.Value.occurences).Sum() : 0; + } + + private void updateError(string message) + { + ControllerError s = _errors[message]; + if (s != null) + { + s.occurences++; + _errors[message] = s; + } + } + + private void ScenarioEvents_OnScenarioEnded() + { + //ConsoleWriter.WriteLine("scenario ended event"); + _scenarioEnded = true; + + } + + private bool isFinished() + { + bool isFinished = false; + try + { + updateVuserStatus(); + } + catch + { + ConsoleWriter.WriteErrLine("Lost connection to Controller"); + return true; + } + + isFinished = _vuserStatus[(int)VuserStatus.Down] == 0 && + _vuserStatus[(int)VuserStatus.Pending] == 0 && + _vuserStatus[(int)VuserStatus.Init] == 0 && + _vuserStatus[(int)VuserStatus.Ready] == 0 && + _vuserStatus[(int)VuserStatus.Run] == 0 && + _vuserStatus[(int)VuserStatus.Rendez] == 0 && + _vuserStatus[(int)VuserStatus.Exiting] == 0 && + _vuserStatus[(int)VuserStatus.GradualExiting] == 0; + + return isFinished; + } + + private void printVusersStatus() + { + Console.WriteLine("Vusers status:"); + string res = ""; + foreach (var val in Enum.GetValues(typeof(VuserStatus))) + { + res += ((VuserStatus)val) + ": " + _vuserStatus[(int)val] + " , "; + } + res = res.Substring(0, res.LastIndexOf(",")); + ConsoleWriter.WriteLine(res); + } + + private void updateVuserStatus() + { + foreach (int val in Enum.GetValues(typeof(VuserStatus))) + { + _vuserStatus[val] = _engine.Scenario.GetVusersCount(val); + } + } + + private bool validateScenario(LrScenario scenario, ref string errorReason) + { + //validate that scenario has SLA + if (!scenario.DoesScenarioHaveSLAConfiguration()) + { + errorReason = string.Format(Resources.LrScenarioValidationFailNoSLA, scenario.FileName); + return false; + + } + //validate that all scripts are available. + if (!scenario.AreScriptsAccessible(out errorReason)) + { + //error message in errorReason + return false; + } + + //validate LGs: + if (scenario.Hosts.Count == 0) + { + errorReason = string.Format(Resources.LrScenarioValidationFailNoLGs, scenario.FileName); + return false; + } + + //connect to all active load generators == hosts: + int ret; + foreach (LrHost lg in scenario.Hosts) + { + //handle only active hosts + if (lg.IsUsed()) + { + //connect to the host + ret = lg.Connect(); + if (ret != 0) + { + errorReason = string.Format(Resources.LrScenarioValidationCannotConnectLG, lg.Name); + return false; + } + + //sync with the host + ret = lg.Sync(60); + if (ret <= 0) + { + errorReason = string.Format(Resources.LrScenarioValidationCannotSyncLG, lg.Name); ; + return false; + } + + //if host is not ready after sync, invalidate the test + if (lg.Status != LrHostStatus.lrHostReady) + { + errorReason = string.Format(Resources.LrScenarioValidationLGNotReady, lg.Name); + return false; + } + + //if we got this far, lg is connected and ready to go + ConsoleWriter.WriteLine(string.Format(Resources.LrScenarioValidationLGConnected, lg.Name)); + } + } + return true; + } + + private void cleanENV() + { + ConsoleWriter.WriteLine(Resources.LrCleanENV); + try + { + // check if any mdrv.exe process existed, kill them. + var mdrvProcesses = Process.GetProcessesByName("mdrv"); + foreach (Process p in mdrvProcesses) + { + p.Kill(); + Stopper stopper = new Stopper(500); + stopper.Start(); + } + + // check if any wlrun.exe process existed, kill them. + + KillController(); + } + catch (Exception) + { + + } + } + + private static void KillController() + { + var wlrunProcesses = Process.GetProcessesByName("Wlrun"); + if (wlrunProcesses.Length > 0) + { + foreach (Process p in wlrunProcesses) + { + if (!p.HasExited) + { + p.Kill(); + // When kill wlrun process directly, there might be a werfault.exe process generated, kill it if it appears. + DateTime nowTime = DateTime.Now; + while (DateTime.Now.Subtract(nowTime).TotalSeconds < 10) + { + var werFaultProcesses = Process.GetProcessesByName("WerFault"); + if (werFaultProcesses.Length > 0) + { + //Console.WriteLine("Kill process of WerFault"); + foreach (Process pf in werFaultProcesses) + { + pf.Kill(); + } + break; + } + Stopper werFaultProcessesStopper = new Stopper(2000); + werFaultProcessesStopper.Start(); + } + Stopper wlrunStopper = new Stopper(2000); + wlrunStopper.Start(); + } + } + ConsoleWriter.WriteLine("wlrun killed"); + } + } + + public void CleanUp() + { + //ConsoleWriter.WriteLine("clenUp"); + + //ConsoleWriter.WriteLine("Closing controller"); + closeController(); + cleanENV(); + } + public void SafelyCancel() + { + } + } +} diff --git a/HpToolsLauncher/TestSuiteRunResults.cs b/HpToolsLauncher/TestSuiteRunResults.cs index 2e8d356e3e..4b172916ac 100644 --- a/HpToolsLauncher/TestSuiteRunResults.cs +++ b/HpToolsLauncher/TestSuiteRunResults.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; @@ -14,6 +41,7 @@ public class TestSuiteRunResults private int m_numErrors = 0; private int m_numFailures = 0; private int m_numTests = 0; + private int m_numWarnings = 0; private TimeSpan m_totalRunTime = TimeSpan.Zero; public string SuiteName { get; set; } @@ -30,6 +58,12 @@ public int NumTests set { m_numTests = value; } } + public int NumWarnings + { + get { return m_numWarnings; } + set { m_numWarnings = value; } + } + public TimeSpan TotalRunTime { get { return m_totalRunTime; } @@ -56,6 +90,7 @@ internal void AppendResults(TestSuiteRunResults desc) this.NumErrors += desc.NumErrors; this.NumFailures += desc.NumFailures; this.NumTests += desc.NumTests; + this.NumWarnings += desc.NumWarnings; } } } diff --git a/HpToolsLauncher/Utils/Encoder.cs b/HpToolsLauncher/Utils/Encoder.cs new file mode 100644 index 0000000000..14c2171a19 --- /dev/null +++ b/HpToolsLauncher/Utils/Encoder.cs @@ -0,0 +1,77 @@ +/* + * 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.Utils +{ + public static class Encoder + { + [DllImport("Encode.dll")] + private static extern IntPtr MicCryptEncrypt([MarshalAs(UnmanagedType.LPWStr)] string dataToBeEncrypted); + + [DllImport("Encode.dll")] + private static extern IntPtr MicCryptDecrypt([MarshalAs(UnmanagedType.LPWStr)] string dataToBeDecrypted); + + [DllImport("Encode.dll")] + private static extern void MicCryptDestroyStr(IntPtr stirngToBeDestroyed); + + public static string Encode(string dataToBeEncrypted) + { + if (string.IsNullOrEmpty(dataToBeEncrypted)) + { + return dataToBeEncrypted; + } + + var encryptedDataPtr = MicCryptEncrypt(dataToBeEncrypted); + string encrpted = Marshal.PtrToStringAuto(encryptedDataPtr); + + MicCryptDestroyStr(encryptedDataPtr); + return encrpted; + } + + public static string Decode(string dataToBeDecrypted) + { + if (string.IsNullOrEmpty(dataToBeDecrypted)) + { + return dataToBeDecrypted; + } + + var decryptedDataPtr = MicCryptDecrypt(dataToBeDecrypted); + string decrpted = Marshal.PtrToStringAuto(decryptedDataPtr); + MicCryptDestroyStr(decryptedDataPtr); + return decrpted; + } + } +} diff --git a/HpToolsLauncher/Utils/Encrypter.cs b/HpToolsLauncher/Utils/Encrypter.cs new file mode 100644 index 0000000000..e1d98fd049 --- /dev/null +++ b/HpToolsLauncher/Utils/Encrypter.cs @@ -0,0 +1,172 @@ +/* + * 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.IO; +using System.Security; +using System.Security.Cryptography; +using System.Text; + +namespace HpToolsLauncher.Utils +{ + public static class Encrypter + { + private const string KeyPath = @"secrets/.hptoolslaunchersecret.key"; + private static readonly string SecretKey; + private static readonly RSACryptoServiceProvider Rsa; + + static Encrypter() + { +#if DEBUG + return; +#else + SecretKey = Environment.GetEnvironmentVariable("hptoolslauncher.key"); + var keyPath = Environment.GetEnvironmentVariable("hptoolslauncher.rootpath"); + + if (string.IsNullOrEmpty(SecretKey) || string.IsNullOrEmpty(keyPath)) + throw new ArgumentException("Invalid environment, no secretkey or root path was set, aborting."); + + keyPath += Path.DirectorySeparatorChar + KeyPath; + + string cnt; + try + { + cnt = File.ReadAllText(keyPath); + } + catch (IOException) + { + ConsoleWriter.WriteErrLine("Failed to open file with decryption key."); + throw new ArgumentException( + "Check the secret key for the hptoolslauncher in the secrets directory or force a new key pair."); + } + catch (SecurityException) + { + ConsoleWriter.WriteErrLine("You do not have access to open the file with the decryption key."); + throw new ArgumentException("Check the permissions for the secret key in the secrets directory."); + } + catch (UnauthorizedAccessException) + { + ConsoleWriter.WriteErrLine("You do not have access to open the file with the decryption key or something else has occurred."); + throw new ArgumentException("Check the permissions for the secret key in the secrets directory or the existence of the file."); + } + + var pkXml = DecryptWithPwd(cnt); + try + { + Rsa = new RSACryptoServiceProvider(); + Rsa.FromXmlString(pkXml); // init + } + catch (CryptographicException) + { + ConsoleWriter.WriteErrLine("The cryptography provider could not be acquired."); + throw new ArgumentException("Try forcing a new key pair."); + } + catch (ArgumentNullException) + { + ConsoleWriter.WriteErrLine("No valid private key were provided for cryptography."); + throw new ArgumentException("Try forcing a new key pair generation."); + } +#endif + } + + /// + /// Decrypts the data with the node's private key. + /// + /// + /// + public static string Decrypt(string textToDecrypt) + { +#if DEBUG + return textToDecrypt; +#else + var encryptedBytes = Convert.FromBase64String(textToDecrypt); + byte[] text; + try + { + text = Rsa.Decrypt(encryptedBytes, false); + } + catch (CryptographicException) + { + ConsoleWriter.WriteErrLine("Failed to decrypt data using private key, try forcing a new public-private key pair."); + throw new ArgumentException("Decryption failed using private key."); + } + + return Encoding.UTF8.GetString(text); +#endif + } + + /// + /// Internal usage only, used for private key decryption. + /// + /// + /// + private static string DecryptWithPwd(string textToDecrypt) + { +#if DEBUG + return textToDecrypt; +#else + var rijndaelCipher = new RijndaelManaged + { + BlockSize = 0x80, + KeySize = 0x100, + Mode = CipherMode.CBC, + Padding = PaddingMode.PKCS7 + }; + + var encryptedData = Convert.FromBase64String(textToDecrypt); + var pwdBytes = Encoding.UTF8.GetBytes(SecretKey); + + var ivBytes = new byte[0x10]; + Array.Copy(encryptedData, ivBytes, 16); + var cntBytes = new byte[encryptedData.Length - 16]; + Array.Copy(encryptedData, 16, cntBytes, 0, cntBytes.Length); + + rijndaelCipher.Key = pwdBytes; + rijndaelCipher.IV = ivBytes; + + byte[] plainText; + try + { + plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(cntBytes, 0, cntBytes.Length); + } + catch (CryptographicException) + { + ConsoleWriter.WriteErrLine("Failed to decrypt using AES, possibly master key have changed since the encryption."); + throw new ArgumentException( + "Try forcing a new public-private key pair on this node, by deselecting encryption in Node configurations."); + } + + return Encoding.UTF8.GetString(plainText); +#endif + } + } +} diff --git a/HpToolsLauncher/Utils/Extensions.cs b/HpToolsLauncher/Utils/Extensions.cs new file mode 100644 index 0000000000..6bd99b1bd5 --- /dev/null +++ b/HpToolsLauncher/Utils/Extensions.cs @@ -0,0 +1,114 @@ +/* + * 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.Runtime.InteropServices; +using System; +using System.Security; +using System.Linq; +using System.ComponentModel; + +namespace HpToolsLauncher.Utils +{ + internal static class Extensions + { + public static SecureString ToSecureString(this string plainString) + { + if (plainString == null) + return null; + + SecureString secureString = new SecureString(); + foreach (char c in plainString.ToCharArray()) + { + secureString.AppendChar(c); + } + return secureString; + } + public static string ToPlainString(this SecureString value) + { + IntPtr valuePtr = IntPtr.Zero; + try + { + valuePtr = Marshal.SecureStringToBSTR(value); + return Marshal.PtrToStringBSTR(valuePtr); + } + finally + { + Marshal.ZeroFreeBSTR(valuePtr); + } + } + + public static bool IsNullOrEmpty(this string value) + { + return string.IsNullOrEmpty(value); + } + public static bool IsNullOrWhiteSpace(this string value) + { + return string.IsNullOrWhiteSpace(value); + } + + public static bool IsEmptyOrWhiteSpace(this string str) + { + return str != null && str.Trim() == string.Empty; + } + + public static bool IsValidUrl(this string url) + { + return Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute); + } + + public static bool EqualsIgnoreCase(this string s1, string s2) + { + return (s1 == null || s2 == null) ? (s1 == s2) : s1.Equals(s2, StringComparison.OrdinalIgnoreCase); + } + + public static bool In(this string str, bool ignoreCase, params string[] values) + { + if (ignoreCase) + { + return values != null && values.Any((string s) => EqualsIgnoreCase(str, s)); + } + return In(str, values); + } + + public static bool In(this T obj, params T[] values) + { + return values != null && values.Any((T o) => Equals(obj, o)); + } + + public static string GetEnumDescription(this Enum enumValue) + { + var fieldInfo = enumValue.GetType().GetField(enumValue.ToString()); + var descrAttrs = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); + return descrAttrs.Length > 0 ? descrAttrs[0].Description : enumValue.ToString(); + } + } +} diff --git a/HpToolsLauncher/Utils/Helper.cs b/HpToolsLauncher/Utils/Helper.cs new file mode 100644 index 0000000000..0c692e2155 --- /dev/null +++ b/HpToolsLauncher/Utils/Helper.cs @@ -0,0 +1,1305 @@ +/* + * 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 Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Web.UI; +using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; +using System.Xml.Xsl; + +namespace HpToolsLauncher.Utils +{ + public enum TestType + { + Unknown, + QTP, + ST, + LoadRunner, + ParallelRunner + } + + 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 STFileExt = ".st"; + public const string QTPFileExt = ".tsp"; + public const string LoadRunnerFileExt = ".lrs"; + public const string MtbFileExt = ".mtb"; + public const string MtbxFileExt = ".mtbx"; + + private const string SOFTWARE_Classes_AppID_A67EB23A = @"SOFTWARE\Classes\AppID\{A67EB23A-1B8F-487D-8E38-A6A3DD150F0B}"; + + private const string SYSTEM_CURRENTCONTROLSET_CONTROL = @"SYSTEM\CurrentControlSet\Control"; + private const string INTERACTIVE_USER = "Interactive User"; + private const string RUN_AS = "RunAs"; + private const string CONTAINER_TYPE = "ContainerType"; + private const string UNABLE_TO_CHANGE_DCOM_SETTINGS = "Unable to change DCOM settings. To change it manually: run dcomcnfg.exe -> My Computer -> DCOM Config -> QuickTest Professional Automation -> Identity -> and select The Interactive User."; + private const string BYPASS_DCOM_SETTINGS_CHECK = "Bypass DCOM settings check, since the process runs inside a Docker container."; + + #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/folders exist (does not recurse into folders) + public static List ValidateFiles(IEnumerable tests) + { + List validTests = new List(); + string testPath = string.Empty; + + foreach (TestData test in tests) + { + // If for FS tests params are specified, it should like this: separated by one or more spaces, + // we should only validate the path, otherwise failure + testPath = GetTestPathWithoutParams(test.Tests); + + if (!File.Exists(testPath) && !Directory.Exists(testPath)) + { + ConsoleWriter.WriteErrLine(string.Format("File/Folder not found: '{0}'", test.Tests)); + Launcher.ExitCode = Launcher.ExitCodeEnum.Failed; + } + else + { + validTests.Add(test); + } + } + return validTests; + } + + public static string GetTestPathWithoutParams(string test) + { + int quotationMarkIndex = test.IndexOf(" \"", StringComparison.Ordinal); + return quotationMarkIndex == -1 ? test : test.Substring(0, quotationMarkIndex).Trim(); + } + + public static bool FileExists(string filePath) + { + bool isFileValid = true; + if (!File.Exists(filePath)) + { + ConsoleWriter.WriteLine(string.Format(">>>> File not found: '{0}'", filePath)); + isFileValid = false; + Launcher.ExitCode = Launcher.ExitCodeEnum.Failed; + } + + return isFileValid; + } + + /// + /// Checks if test parameters list is valid or not + /// + /// + /// + /// + /// true if parameters the list of parameters is valid, false otherwise + public static bool ValidateInlineParams(string[] @params, out IList paramNames, out IList paramValues) + { + if (@params == null) throw new ArgumentNullException("Parameters are missing"); + paramNames = new List(); + paramValues = new List(); + + if (@params.Any()) + { + foreach (var parameterPair in @params) + { + if (!string.IsNullOrWhiteSpace(parameterPair)) + { + string[] pair = parameterPair.Split(':'); + + string paramName = pair[0].Trim(); + if (!CheckParamFormat(paramName)) + { + ConsoleWriter.WriteLine(string.Format(Resources.MissingQuotesInParamFormat, "parameter name")); + return false; + } + + paramName = NormalizeParam(paramName); + if (string.IsNullOrWhiteSpace(paramName)) + { + ConsoleWriter.WriteLine(Resources.MissingParameterName); + return false; + } + paramNames.Add(paramName); + + string paramValue = pair[1].Trim(); + if (!CheckParamFormat(paramValue)) + { + ConsoleWriter.WriteLine(string.Format(Resources.MissingQuotesInParamFormat, "parameter value")); + return false; + } + + paramValue = NormalizeParam(paramValue); + if (paramValue == null) + { + ConsoleWriter.WriteLine(Resources.MissingParameterValue); + return false; + } + paramValues.Add(paramValue); + } + } + } + + return true; + } + + /// + /// + /// + /// + /// + private static bool CheckParamFormat(string param) + { + long _unused; + if (!string.IsNullOrEmpty(param) && long.TryParse(param, out _unused)) + { + return true; + } + else + { + // must be at least 2 characters wide, containing at least 2 double quotes + if (param.Length < 2) return false; + + // first and at last characters have to be double quotes + if (!param.StartsWith("\"") && !param.EndsWith("\"")) return false; + + return true; + } + } + + /// + /// Normalizes test parameter, by removing the double quotes + /// + /// + /// true if parameter is valid, false otherwise + private static string NormalizeParam(string param) + { + if (!string.IsNullOrWhiteSpace(param)) + { + long n = long.MaxValue; + bool isNumeric = !string.IsNullOrEmpty(param) && long.TryParse(param, out n); + + if (isNumeric) + { + return n.ToString(); + } + else + { + if (param.Length >= 2) + { + return param.Substring(1, param.Length - 2); + } + } + } + + return null; + } + + 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(DirectoryInfo root, ref List results) + { + FileInfo[] files = null; + DirectoryInfo[] subDirs; + + // First, process all the files directly under this folder + try + { + + files = root.GetFiles("*" + STFileExt); + files = files.Union(root.GetFiles("*" + QTPFileExt)).ToArray(); + files = files.Union(root.GetFiles("*" + LoadRunnerFileExt)).ToArray(); + } + catch (Exception) + { + // 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 (FileInfo fi in files) + { + if (fi.Extension == LoadRunnerFileExt) + 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 (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; + } + + public static string GetParallelRunnerDirectory(string parallelRunnerExecutable) + { + if (parallelRunnerExecutable == null) return null; + + var uftFolder = GetSTInstallPath(); + + if (uftFolder == null) return null; + + return uftFolder + @"bin\" + parallelRunnerExecutable; + } + + /// + /// Why we need this? If we run jenkins in a master slave node where there is a jenkins service installed in the slave machine, we need to change the DCOM settings as follow: + /// dcomcnfg.exe -> My Computer -> DCOM Config -> QuickTest Professional Automation -> Identity -> and select The Interactive User + /// + public static void ChangeDCOMSettingToInteractiveUser() + { + if (IsInDocker()) + { + ConsoleWriter.WriteLine(BYPASS_DCOM_SETTINGS_CHECK); + return; + } + try + { + var regKey = GetQuickTestProfessionalAutomationRegKey(RegistryView.Registry32); + + if (regKey == null) + { + regKey = GetQuickTestProfessionalAutomationRegKey(RegistryView.Registry64); + } + + if (regKey == null) + throw new Exception(string.Format("Unable to find in registry key {0}", SOFTWARE_Classes_AppID_A67EB23A)); + + object runAsKey = regKey.GetValue(RUN_AS); + + if (runAsKey == null || !runAsKey.ToString().Equals(INTERACTIVE_USER)) + { + regKey.SetValue(RUN_AS, INTERACTIVE_USER); + } + } + catch (Exception ex) + { + throw new Exception(string.Format("{0}. Error: ", UNABLE_TO_CHANGE_DCOM_SETTINGS, ex.Message)); + } + } + + private static bool IsInDocker() + { + int containerType = 0; + try + { + RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); + regKey = regKey.OpenSubKey(SYSTEM_CURRENTCONTROLSET_CONTROL, false); + containerType = (regKey.GetValue(CONTAINER_TYPE) as int?).GetValueOrDefault(); + } + catch (Exception ex) + { + ConsoleWriter.WriteErrLine(string.Format("IsInDocker() function error: {0}", ex.Message)); + } + return containerType > 0; + } + + public static RegistryKey GetQuickTestProfessionalAutomationRegKey(RegistryView registry32) + { + RegistryKey localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); + localKey = localKey.OpenSubKey(SOFTWARE_Classes_AppID_A67EB23A, true); + + return localKey; + } + + /// + /// Return the path of the available results folder for the parallel runner. + /// + /// The test information. + /// + /// the path to the results folder + /// + public static string GetNextResFolder(string reportPath, string resultFolderName) + { + // since ParallelRunner will store the report as "Res1...ResN" + // we need to know before parallel runner creates the result folder + // what the folder name will be + // so we know which result is ours(or if there was any result) + int resultFolderIndex = 1; + + while (Directory.Exists(Path.Combine(reportPath, resultFolderName + resultFolderIndex))) + { + resultFolderIndex += 1; + } + + return reportPath + "\\" + resultFolderName + resultFolderIndex; + } + + #region Report Related + + /// + /// Set the error for a test when the report path is invalid. + /// + /// The test run results + /// The error reason + /// The test informatio + public static void SetTestReportPathError(TestRunResults runResults, ref string errorReason, TestInfo testInfo) + { + // Invalid path was provided, return useful description + errorReason = string.Format(Resources.InvalidReportPath, runResults.ReportLocation); + + // since the report path is invalid, the test should fail + runResults.TestState = TestState.Error; + runResults.ErrorDesc = errorReason; + + // output the error for the current test run + ConsoleWriter.WriteErrLine(runResults.ErrorDesc); + + // include the error in the summary + ConsoleWriter.ErrorSummaryLines.Add(runResults.ErrorDesc); + + // provide the appropriate exit code for the launcher + Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed; + } + + /// + /// Try to set the custom report path for a given test. + /// + /// The test run results + /// The test information + /// The error reason + /// True if the report path was set, false otherwise + public static bool TrySetTestReportPath(TestRunResults runResults, TestInfo testInfo, ref string errorReason) + { + string testName = testInfo.TestName.Substring(testInfo.TestName.LastIndexOf('\\') + 1) + "_"; + string reportLocation = Helper.GetNextResFolder(testInfo.ReportPath, testName); + + // set the report location for the run results + runResults.ReportLocation = reportLocation; + try + { + Directory.CreateDirectory(runResults.ReportLocation); + } + catch (Exception) + { + SetTestReportPathError(runResults, ref errorReason, testInfo); + return false; + } + + return true; + } + + 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 = string.Empty; + 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) + { + return TestState.Unknown; + } + + } + + public static TestState GetTestStateFromLRReport(TestRunResults runDesc, string[] resultFiles) + { + + foreach (string resultFileFullPath in resultFiles) + { + string desc = string.Empty; + 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 + //if there is parallelrun_results.xml -> ParallelRunner + + 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); + } + + resultFiles = Directory.GetFiles(runDesc.ReportLocation, "parallelrun_results.html", SearchOption.TopDirectoryOnly); + + // the overall status is given by parallel runner + // at the end of the run + if (resultFiles != null && resultFiles.Length > 0) + { + return runDesc.TestState; + } + + //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) + { + return TestState.Unknown; + } + + } + + private static TestState GetTestStateFromLRReport(string resultFileFullPath, out string desc) + { + XmlDocument xdoc = new XmlDocument(); + xdoc.Load(resultFileFullPath); + return CheckNodeStatus(xdoc.DocumentElement, out desc); + } + + private static TestState CheckNodeStatus(XmlNode node, out string desc) + { + desc = string.Empty; + 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 = string.Empty; + string 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) + { + } + 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 static void DeleteDirectory(string dirPath) + { + DirectoryInfo directory = Directory.CreateDirectory(dirPath); + foreach (FileInfo file in directory.GetFiles()) file.Delete(); + foreach (DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true); + Directory.Delete(dirPath); + } + } + + 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/Utils/RunAsUser.cs b/HpToolsLauncher/Utils/RunAsUser.cs new file mode 100644 index 0000000000..857e8ffb7b --- /dev/null +++ b/HpToolsLauncher/Utils/RunAsUser.cs @@ -0,0 +1,70 @@ +/* + * 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.Security; + +namespace HpToolsLauncher.Utils +{ + public class RunAsUser + { + private readonly string _username; + private readonly string _encodedPwd; + private readonly SecureString _pwd; + + public RunAsUser(string username, string encodedPwd) + { + _username = username; + _encodedPwd = encodedPwd; + _pwd = Encoder.Decode(_encodedPwd).ToSecureString(); + } + public RunAsUser(string username, SecureString pwd) + { + _username = username; + _pwd = pwd; + _encodedPwd = Encoder.Encode(_pwd.ToPlainString()); + } + public string Username + { + get { return _username; } + } + + public string EncodedPassword + { + get { return _encodedPwd; } + } + + public SecureString Password + { + get { return _pwd; } + } + } +} \ No newline at end of file diff --git a/HpToolsLauncher/WinUserNativeMethods.cs b/HpToolsLauncher/WinUserNativeMethods.cs deleted file mode 100644 index e8a9778cd2..0000000000 --- a/HpToolsLauncher/WinUserNativeMethods.cs +++ /dev/null @@ -1,68 +0,0 @@ -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/app.config b/HpToolsLauncher/app.config index e365603337..6e39bb5ce6 100644 --- a/HpToolsLauncher/app.config +++ b/HpToolsLauncher/app.config @@ -1,3 +1,7 @@ - - - + + + + + + + \ No newline at end of file diff --git a/HpToolsLauncher/externals/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll b/HpToolsLauncher/externals/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll new file mode 100644 index 0000000000..bc61345fe3 Binary files /dev/null and b/HpToolsLauncher/externals/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll differ diff --git a/HpToolsLauncher/externals/QTObjectModelLib.dll b/HpToolsLauncher/externals/QTObjectModelLib.dll index 6acbfdab00..ccc1676130 100644 Binary files a/HpToolsLauncher/externals/QTObjectModelLib.dll and b/HpToolsLauncher/externals/QTObjectModelLib.dll differ diff --git a/HpToolsLauncher/externals/interop.OTAClient.dll b/HpToolsLauncher/externals/interop.OTAClient.dll index a19cd83554..fa4ae617b8 100644 Binary files a/HpToolsLauncher/externals/interop.OTAClient.dll and b/HpToolsLauncher/externals/interop.OTAClient.dll differ diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..8c3db644b9 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,7 @@ +if (env.JENKINS_URL == 'https://ci.jenkins.io/') { + // Builds the plugin using https://github.com/jenkins-infra/pipeline-library + buildPlugin(platforms: ['windows']) +} +else { + // Do internal build +} diff --git a/LICENSE.txt b/LICENSE.txt index 1657680535..0b6a29434b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,21 +1,31 @@ -MIT License -Copyright (c) 2012 Hewlett-Packard Development Company, L.P. + 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 -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: + Copyright 2012-2023 Open Text -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + 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. -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. + 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. + + ___________________________________________________________________ diff --git a/LRAnalysisLauncher/Helper.cs b/LRAnalysisLauncher/Helper.cs index 0b90dfbaea..010643bb35 100644 --- a/LRAnalysisLauncher/Helper.cs +++ b/LRAnalysisLauncher/Helper.cs @@ -1,4 +1,36 @@ -using System; +/* + * 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.Net; diff --git a/LRAnalysisLauncher/Program.cs b/LRAnalysisLauncher/Program.cs index 547e40b3d3..99ca1494ef 100644 --- a/LRAnalysisLauncher/Program.cs +++ b/LRAnalysisLauncher/Program.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; using System.Collections.Generic; @@ -26,7 +41,9 @@ using Analysis.ApiSL; using Analysis.Api.Dictionaries; using System.Diagnostics; +using System.Globalization; using System.Linq; +using HpToolsLauncher.Utils; namespace LRAnalysisLauncher { @@ -45,9 +62,9 @@ static void log() static void log(string msg) { Console.WriteLine(msg); - // writer.WriteLine(msg); + // writer.WriteLine(msg); } -// static StreamWriter writer = new StreamWriter(new FileStream("c:\\AnalysisLauncherOutput.txt", FileMode.OpenOrCreate, FileAccess.Write)); + // static StreamWriter writer = new StreamWriter(new FileStream("c:\\AnalysisLauncherOutput.txt", FileMode.OpenOrCreate, FileAccess.Write)); //args: lrr location, lra location, html report location [STAThread] static int Main(string[] args) @@ -58,22 +75,25 @@ static int Main(string[] args) int iPassed = (int)Launcher.ExitCodeEnum.Passed;//variable to keep track of whether all of the SLAs passed try { - if (args.Length != 3) + //The app uses 3 default arguments, a 4th optional one can be used to specify the path to an analysis template + if (args.Length != 3 && args.Length != 4) { ShowHelp(); - return (int) Launcher.ExitCodeEnum.Aborted; + return (int)Launcher.ExitCodeEnum.Aborted; } string lrrlocation = args[0]; string lralocation = args[1]; string htmlLocation = args[2]; + string analysisTemplateLocation = (args.Length == 4 ? args[3] : ""); log("creating analysis COM object"); LrAnalysis analysis = new LrAnalysis(); - + Session session = analysis.Session; log("creating analysis session"); - if (session.Create(lralocation, lrrlocation)) + //Apply a template and create LRA folder + if (session.CreateWithTemplateFile(lralocation, lrrlocation, analysisTemplateLocation)) { log("analysis session created"); log("creating HTML reports"); @@ -139,11 +159,11 @@ static int Main(string[] args) // stopper.Start(); // log("Gathering Duration statistics"); // stopper.Start(); - //DateTime startTime = Helper.FromUnixTime(currentRun.StartTime); - //DateTime endTime = Helper.FromUnixTime(currentRun.EndTime); - //durationElement.SetAttribute("End", endTime.ToString()); - //durationElement.SetAttribute("Start", startTime.ToString()); - //durationElement.SetAttribute("Duration", Helper.GetScenarioDuration(currentRun)); + //DateTime startTime = Helper.FromUnixTime(currentRun.StartTime); + //DateTime endTime = Helper.FromUnixTime(currentRun.EndTime); + //durationElement.SetAttribute("End", endTime.ToString()); + //durationElement.SetAttribute("Start", startTime.ToString()); + //durationElement.SetAttribute("Duration", Helper.GetScenarioDuration(currentRun)); //} general.AppendChild(durationElement); @@ -213,6 +233,7 @@ static int Main(string[] args) int iCounter = 0; // set counter log("WholeRunRules : " + slaResult.WholeRunRules.Count); + CultureInfo formatProvider = new CultureInfo("en-US"); foreach (SlaWholeRunRuleResult a in slaResult.WholeRunRules) { log(Resources.DoubleLineSeperator); @@ -224,21 +245,21 @@ static int Main(string[] args) log("Transaction Name : " + b.TransactionName); elem.SetAttribute("TransactionName", b.TransactionName.ToString()); log("Percentile : " + b.Percentage); - elem.SetAttribute("Percentile", b.Percentage.ToString()); + elem.SetAttribute("Percentile", b.Percentage.ToString(formatProvider)); elem.SetAttribute("FullName", b.RuleUiName); log("Full Name : " + b.RuleUiName); log("Measurement : " + b.Measurement); elem.SetAttribute("Measurement", b.Measurement.ToString()); log("Goal Value : " + b.GoalValue); - elem.SetAttribute("GoalValue", b.GoalValue.ToString()); + elem.SetAttribute("GoalValue", b.GoalValue.ToString(formatProvider)); log("Actual value : " + b.ActualValue); - elem.SetAttribute("ActualValue", b.ActualValue.ToString()); + elem.SetAttribute("ActualValue", b.ActualValue.ToString(formatProvider)); log("status : " + b.Status); elem.AppendChild(xmlDoc.CreateTextNode(b.Status.ToString())); if (b.Status.Equals(SlaRuleStatus.Failed)) // 0 = failed { - iPassed = (int) Launcher.ExitCodeEnum.Failed; + iPassed = (int)Launcher.ExitCodeEnum.Failed; } iCounter++; } @@ -250,15 +271,15 @@ static int Main(string[] args) log("Measurement : " + a.Measurement); elem.SetAttribute("Measurement", a.Measurement.ToString()); log("Goal Value : " + a.GoalValue); - elem.SetAttribute("GoalValue", a.GoalValue.ToString()); + elem.SetAttribute("GoalValue", a.GoalValue.ToString(formatProvider)); log("Actual value : " + a.ActualValue); - elem.SetAttribute("ActualValue", a.ActualValue.ToString()); + elem.SetAttribute("ActualValue", a.ActualValue.ToString(formatProvider)); log("status : " + a.Status); elem.AppendChild(xmlDoc.CreateTextNode(a.Status.ToString())); if (a.Status.Equals(SlaRuleStatus.Failed)) // 0 = failed { - iPassed = (int) Launcher.ExitCodeEnum.Failed; + iPassed = (int)Launcher.ExitCodeEnum.Failed; } } root.AppendChild(elem); @@ -288,31 +309,53 @@ static int Main(string[] args) foreach (SlaLoadThreshold slat in b.LoadThresholds) { XmlElement loadThr = xmlDoc.CreateElement("SlaLoadThreshold"); - loadThr.SetAttribute("StartLoadValue", slat.StartLoadValue.ToString()); - loadThr.SetAttribute("EndLoadValue", slat.EndLoadValue.ToString()); - loadThr.SetAttribute("ThresholdValue", slat.ThresholdValue.ToString()); + loadThr.SetAttribute("StartLoadValue", slat.StartLoadValue.ToString(formatProvider)); + loadThr.SetAttribute("EndLoadValue", slat.EndLoadValue.ToString(formatProvider)); + loadThr.SetAttribute("ThresholdValue", slat.ThresholdValue.ToString(formatProvider)); rule.AppendChild(loadThr); } XmlElement timeRanges = xmlDoc.CreateElement("TimeRanges"); log("TimeRanges : " + b.TimeRanges.Count); + int passed = 0; + int failed = 0; + int noData = 0; foreach (SlaTimeRangeInfo slatri in b.TimeRanges) { XmlElement subsubelem = xmlDoc.CreateElement("TimeRangeInfo"); subsubelem.SetAttribute("StartTime", slatri.StartTime.ToString()); subsubelem.SetAttribute("EndTime", slatri.EndTime.ToString()); - subsubelem.SetAttribute("GoalValue", slatri.GoalValue.ToString()); - subsubelem.SetAttribute("ActualValue", slatri.ActualValue.ToString()); - subsubelem.SetAttribute("LoadValue", slatri.LoadValue.ToString()); + subsubelem.SetAttribute("GoalValue", slatri.GoalValue.ToString(formatProvider)); + subsubelem.SetAttribute("ActualValue", slatri.ActualValue.ToString(formatProvider)); + subsubelem.SetAttribute("LoadValue", slatri.LoadValue.ToString(formatProvider)); subsubelem.InnerText = slatri.Status.ToString(); + switch (slatri.Status) + { + case SlaRuleStatus.Failed: + failed++; + break; + case SlaRuleStatus.Passed: + passed++; + break; + case SlaRuleStatus.NoData: + noData++; + break; + default: + break; + } timeRanges.AppendChild(subsubelem); } rule.AppendChild(timeRanges); - log("status : " + b.Status); - rule.AppendChild(xmlDoc.CreateTextNode(b.Status.ToString())); - if (b.Status.Equals(SlaRuleStatus.Failed)) // 0 = failed + SlaRuleStatus currentRuleStatus = b.Status; + if (currentRuleStatus.Equals(SlaRuleStatus.NoData) && (passed > noData)) + { + currentRuleStatus = SlaRuleStatus.Passed; + } + log("status : " + currentRuleStatus); + rule.AppendChild(xmlDoc.CreateTextNode(currentRuleStatus.ToString())); + if (currentRuleStatus.Equals(SlaRuleStatus.Failed)) // 0 = failed { - iPassed = (int) Launcher.ExitCodeEnum.Failed; + iPassed = (int)Launcher.ExitCodeEnum.Failed; } iCounter++; } @@ -329,31 +372,53 @@ static int Main(string[] args) foreach (SlaLoadThreshold slat in a.LoadThresholds) { XmlElement loadThr = xmlDoc.CreateElement("SlaLoadThreshold"); - loadThr.SetAttribute("StartLoadValue", slat.StartLoadValue.ToString()); - loadThr.SetAttribute("EndLoadValue", slat.EndLoadValue.ToString()); - loadThr.SetAttribute("ThresholdValue", slat.ThresholdValue.ToString()); + loadThr.SetAttribute("StartLoadValue", slat.StartLoadValue.ToString(formatProvider)); + loadThr.SetAttribute("EndLoadValue", slat.EndLoadValue.ToString(formatProvider)); + loadThr.SetAttribute("ThresholdValue", slat.ThresholdValue.ToString(formatProvider)); rule.AppendChild(loadThr); } XmlElement timeRanges = xmlDoc.CreateElement("TimeRanges"); log("TimeRanges : " + a.TimeRanges.Count); + int passed = 0; + int failed = 0; + int noData = 0; foreach (SlaTimeRangeInfo slatri in a.TimeRanges) { XmlElement subsubelem = xmlDoc.CreateElement("TimeRangeInfo"); subsubelem.SetAttribute("StartTime", slatri.StartTime.ToString()); subsubelem.SetAttribute("EndTime", slatri.EndTime.ToString()); - subsubelem.SetAttribute("GoalValue", slatri.GoalValue.ToString()); - subsubelem.SetAttribute("ActualValue", slatri.ActualValue.ToString()); - subsubelem.SetAttribute("LoadValue", slatri.LoadValue.ToString()); + subsubelem.SetAttribute("GoalValue", slatri.GoalValue.ToString(formatProvider)); + subsubelem.SetAttribute("ActualValue", slatri.ActualValue.ToString(formatProvider)); + subsubelem.SetAttribute("LoadValue", slatri.LoadValue.ToString(formatProvider)); subsubelem.InnerText = slatri.Status.ToString(); + switch (slatri.Status) + { + case SlaRuleStatus.Failed: + failed++; + break; + case SlaRuleStatus.Passed: + passed++; + break; + case SlaRuleStatus.NoData: + noData++; + break; + default: + break; + } timeRanges.AppendChild(subsubelem); } rule.AppendChild(timeRanges); - log("status : " + a.Status); - rule.AppendChild(xmlDoc.CreateTextNode(a.Status.ToString())); - if (a.Status.Equals(SlaRuleStatus.Failed)) + SlaRuleStatus currentRuleStatus = a.Status; + if (currentRuleStatus.Equals(SlaRuleStatus.NoData) && (passed > noData)) + { + currentRuleStatus = SlaRuleStatus.Passed; + } + log("status : " + currentRuleStatus); + rule.AppendChild(xmlDoc.CreateTextNode(currentRuleStatus.ToString())); + if (currentRuleStatus.Equals(SlaRuleStatus.Failed)) { - iPassed = (int) Launcher.ExitCodeEnum.Failed; + iPassed = (int)Launcher.ExitCodeEnum.Failed; } } @@ -380,7 +445,7 @@ static int Main(string[] args) { log(Resources.CannotCreateSession); - return (int) Launcher.ExitCodeEnum.Aborted; + return (int)Launcher.ExitCodeEnum.Aborted; } log("closing analysis session"); session.Close(); @@ -395,13 +460,13 @@ static int Main(string[] args) log(ex.Message); log(ex.StackTrace); } - return (int) Launcher.ExitCodeEnum.Aborted; + return (int)Launcher.ExitCodeEnum.Aborted; } catch (Exception e) { log(e.Message); log(e.StackTrace); - return (int) Launcher.ExitCodeEnum.Aborted; + return (int)Launcher.ExitCodeEnum.Aborted; } @@ -416,7 +481,7 @@ static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, R { System.Reflection.AssemblyName name = new System.Reflection.AssemblyName(args.Name); if (name.Name.ToLowerInvariant().EndsWith(".resources")) return null; - string installPath = HpToolsLauncher.Helper.getLRInstallPath(); + string installPath = HpToolsLauncher.Utils.Helper.getLRInstallPath(); if (installPath == null) { log(Resources.CannotLocateInstallDir); @@ -428,11 +493,11 @@ static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, R private static void ShowHelp() { - log("HP LoadRunner Analysis Command Line Executer"); + log("Micro Focus LoadRunner Analysis Command Line Executer"); log(); Console.Write("Usage: LRAnalysisLauncher.exe"); Console.ForegroundColor = ConsoleColor.Cyan; - Console.Write("[.lrr file location] [.lra output location] [html report output folder]"); + Console.Write("[.lrr file location] [.lra output location] [html report output folder] [.tem file location(optional)]"); Console.ResetColor(); Environment.Exit((int)Launcher.ExitCodeEnum.Failed); } diff --git a/LRAnalysisLauncher/Properties/AssemblyInfo.cs b/LRAnalysisLauncher/Properties/AssemblyInfo.cs index 948ff1cca9..b8f6b117a5 100644 --- a/LRAnalysisLauncher/Properties/AssemblyInfo.cs +++ b/LRAnalysisLauncher/Properties/AssemblyInfo.cs @@ -1,20 +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/doc/ALM_Integration.md b/doc/ALM_Integration.md new file mode 100644 index 0000000000..d19d70052c --- /dev/null +++ b/doc/ALM_Integration.md @@ -0,0 +1,275 @@ +# ALM Integration + +You can use this plugin to run ALM tests sets and use ALM Lab Management with the Jenkins continuous integration. + +If you are working with Quality Center 10.00 or earlier, and QuickTest Professional 9.x or 10.x, use the [Quality Center Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Quality+Center+Plugin). + +### Table of Contents + +[Configure the connection to ALM](#configure-the-connection-to-alm) + +[Run Test Sets from ALM](#run-test-sets-from-alm) + +[Run Server Side tests using ALM Lab Management](#run-server-side-tests-using-alm-lab-management) + +[Create or update the AUT Environment Configuration using ALM Lab Management](#create-or-update-the-aut-environment-configuration-using-alm-lab-management) + +## Configure the connection to ALM + +To configure the connection to your ALM Server. + +1. Go to the Jenkins Server home page. + +2. Click the **Manage Jenkins** link in the left pane.  + +3. In the Manage Jenkins Page click **Configure System**. + +4. In the Configuration tab, scroll down to the **Application Lifecycle + Management** section. + +5. Click **Add ALM server**, if no server is currently configured. + +6. Specify a meaningful server name and URL. When specifying an ALM + Server URL, use the full string, e.g.: `http:/myserver.mydomain/qcbin`. + +7. Specify global credentials, if you plan to use them within jobs, by clicking **Add credentials** and entering a username and password. To use SSO authentification click **Add SSO credentials** and specify the API Key Client ID and Secret obtained from your ALM site administrator. + - **Note:** *Credentials specified here will be available for all ALM jobs.* + +## Run Test Sets from ALM + +####  **Set up a job** + +1. Go to the Jenkins Server home page. + +2. Click the **New Job** link or select an existing job. + +3. Enter a Job name (for a new job). + +4. Select **Build a free-style software project** and click **OK**. + +5. In the Project Configuration section scroll down to + the **Build** section. + +6. Expand the **Add build** **step** drop-down and select **Execute + functional tests from OpenText ALM**. + +7. Select one of the ALM servers that you configured in the previous + step. + +8. Enter the server credentials by selecting from the **Credential Scope** dropdown the desired credential handling mode. By selecting **System (global) credentials** mode, credentials from the global scope will be available, otherwise by selecting **Job (local) credentials** mode you will have to specify the currently preferred user's identifying information. **Note:** If you are using the ALM scheduler, it will run + under the Jenkins agent user. For example, if Jenkins is running as a **System** user, the scheduler will run the tests as a **System** user. This will not affect test execution.  + +9. Enter the current domain and project in which your tests reside.  + +10. Add the test set folders or specific test sets that you want to include, using the ALM path. To add a specific test, add the test name after the test set path. To add multiple entries, click the down arrow on the right of the field and enter each item on a separate line. See the example below. + +``` + Root\testfolder1\testset_a + Root\testfolder1\testset_b + Root\testlab_folder + Root\testlab_folder\testset_a\test-name +``` +12. Optionally, add test parameters to use for the tests, using the following syntax: + +``` + "":"", "": +``` +- Where: + - **<test or test set path>** is the path to the test or test set. **Note:** If you specify a test, the specified parameters are used for that test only. If you specify a test set, the specified parameters are used for all of the tests in that test set. When the test set runs, each test uses the parameters it requires and ignores any others. + - **<parameter name>** is the name of your test parameter. + - **<string value>** is a string value for your parameter, in quotes. + - **<number value>** is a number value for your parameter, without quotes. +- **Tip:** Specify values for all test parameters required by your tests, or make sure that the parameters have default values defined in UFT One or ALM. + - **Note:** for the limitations of this syntax see [Limitations of Test Parameters syntax](README.md#test-parameters-syntax) + +13. Optionally, indicate a timeout in seconds after which the job will fail. + +14. Optionally, set up a filter for your ALM test set, instructing Jenkins to run only part of the test in the test set. Select **Filter ALM test sets**, and filter the tests to run by name or status or both. + - In **Run tests with names containing**, specify a string to find within the test names. + - In **Run tests with status**, specify the statuses of the tests you want to run. E.g., if you don't want to rerun tests that already passed, don't select the **Passed** status. + +16. Click **Advanced** to indicate a Run mode (local, remote, or planned host) If you specify a remote host mode, specify a host name. This must be a machine with a valid installation of the testing tool. + +17. Click **Apply** to save your changes and continue with more build + steps. Click **Save** when you are finished adding build steps. + + +#### **Set up the Post Build actions** + +In the **Post-build Actions** section, expand the **Add post-build action** drop-down and select **Publish test result**. + +#### Run the job + +Run or schedule the job as you would with any standard Jenkins job.  + +#### Review the results + +1. From the dashboard, click on the job. + +2. Click the Console link to view the ALM information. + +3. Copy the ALM link to your Internet Explorer browser and view the Test Set results from within ALM. + +## Run Server Side Tests Using ALM Lab Management + +If you have Lab Management activated in ALM, you can run server-side tests from functional test sets and build verification suites. After setting up the test sets and build verification suites, you can configure a Jenkins build step to execute your tests. + +#### **Set up a job** + +1. Go to the Jenkins Server home page. + +2. Click the **New Job** link or select an existing job. + +3. Enter a Job name (for a new job). + +4. Select **Build a free-style software project** and click **OK**. + +5. In the Project Configuration section scroll down to the **Build** section. + +6. Expand the **Add build** **step** drop-down and select **Execute tests using ALM Lab Management**. + +7. Select one of the ALM servers that you configured in the previous step. + +8. Enter the server credentials, project, and domain.  + +9. If your ALM server version is 12.60 or higher, enter the **Client type**. + +10. Select a Run Type from the drop down menu (functional test set or build verification suite). + +11. Enter the ID of your run entity (either the test set ID or the build verification suite ID). + +12. **Optional:** Enter a description of the build step. + +13. Enter a duration (in minutes) for the timeslot. The minimum time is 30 minutes. + +14. **Optional**: If you have defined an AUT environment configuration in ALM, you can enter the ID here in order to execute your timeslot with specific AUT parameters. + If you have CDA configured in ALM and want to implement it for this time slot, select the **Use CDA for provisioning and deployment** checkbox and enter your CDA details. + + +#### Set up the Post Build actions + +In the **Post-build Actions** section, expand the **Add post-build action** drop-down and select **Publish test result**. + +#### Run the job + +Run or schedule the job as you would with any standard Jenkins job.  + +#### **Review the results** + +1. From the dashboard, click on the job. + +2. Click the Console link to view the ALM information. + +3. Copy the ALM link to your Internet Explorer browser and view the + Test Set results from within ALM. + +**Note:** For environments with Internet Explorer 9 and ALM version 12.20 or later: The report, normally accessible through a link in the console log, will not be available. + +## Create or update the AUT Environment Configuration using ALM Lab Management + +If you have Lab Management activated in ALM, you can create/update an AUT Environment Configuration for an existing AUT environment in ALM. + +#### **Set up a job** + +1. Go to the Jenkins Server home page. + +2. Click the **New Job** link or select an existing job. + +3. Enter a Job name (for a new job). + +4. Select **Build a free-style software project** and click **OK**. + +5. In the Project Configuration section scroll down to + the **Build** section. + +6. Expand the **Add build** **step** drop-down and select **Execute AUT + Environment preparation using ALM Lab Management**. + +7. Select one of the ALM servers that you configured in the **Configure + the connection to your ALM server** step. + +8. Enter the server credentials, project name, and domain.  + +9. Enter the ID of the environment for which you want to create/update + a configuration. + +10. Select one of the following options to Indicate whether or not to + create a new AUT Environment Configuration or update an existing + one. + + a. For **Create a new configuration named**, enter a name for the + new configuration. + + b. For **Use an existing configuration with ID**, enter the ID of + your AUT Environment Configuration in ALM. + +11. **Optional:** Enter a path for a JSON file that contains values for + the AUT Environment parameters for the relevant configuration. + +12. **Optional:** Enter a name of a build environment parameter in order + to save the ID of the created/updated configuration for future use. + +13. Add the AUT Environment parameters that you want to update for the + created/updated configuration. For each parameter: + + a. Select the type of the parameter from the drop-down menu (Manual, Environment, From JSON). + + b. Enter the full path of the parameter as it appears in ALM. + + c. Enter the value you want to assign to this parameter. + +#### **Run the job** + +Run or schedule the job as you would with any standard Jenkins job.  + +## Upload Test Results to ALM + +You can upload tests running in JUnit, NUnit, or TestNG frameworks to ALM as part as the run job or as a separate job. ALM will create tests and test sets (of External type) corresponding to the executed tests. + +####  **Set up a job** + +1. Go to the Jenkins Server home page. + +2. Click the **New Job** link or select an existing job. + +3. Enter a Job name (for a new job). + +4. Select **Build a free-style software project** and click **OK**. + +#### **Set up the Post Build actions** + +1. In the Project Configuration section, scroll down to + the **Post-build Actions** section. + +2. Expand the **Add post-build action** drop-down and select **Upload + test result to ALM**. + +3. Select one of the ALM servers that you configured in the **Configure + the connection to your ALM server** step. + +4. Enter the server credentials, project name, and domain.  + +5. Select a testing framework from the drop-down list: JUnit, NUnit, or + TestNG. + +6. **Optional:** Enter the name of the Testing Tool name, to be used in the corresponding entity in ALM. + +7. Enter the ALM Test folder path, in which to store the external tests. Do not include the Root test folder (Subject). + +8. Enter the ALM Test Set folder path, in which to store the external test sets. Do not include the Root test sets folder. + +9. Enter the Testing result file condition, relative to the root path of the job. For example, use \*\*/junitResult.xml for Junit Plugin results. + +10. **Optional:** Enter the Jenkins server URL. + +#### **Run the job** + +Run or schedule the job as you would with any standard Jenkins job.  + +#### **Review the results** + +1. From the dashboard, click on the job. + +2. Click the **Console** link to view the ALM information. + +3. Copy the ALM link to Internet Explorer and view the tests, test sets, and test runs that were created within ALM. diff --git a/doc/Jenkins_slave_account.png b/doc/Jenkins_slave_account.png new file mode 100644 index 0000000000..13c83d7dee Binary files /dev/null and b/doc/Jenkins_slave_account.png differ diff --git a/doc/Jenkins_slave_setup.png b/doc/Jenkins_slave_setup.png new file mode 100644 index 0000000000..dad1616f62 Binary files /dev/null and b/doc/Jenkins_slave_setup.png differ diff --git a/doc/LR_Integration.md b/doc/LR_Integration.md new file mode 100644 index 0000000000..beb8fecf27 --- /dev/null +++ b/doc/LR_Integration.md @@ -0,0 +1,175 @@ +# LoadRunner integration + +The Application Automation Tools plugin for the Jenkins continuous integration server provides a mechanism for executing LoadRunner Controller scenarios as part of a build script. This plugin allows you to trigger a performance test as a build step, and present the results in the Jenkin\'s user interface. + +You can only integrate scenarios which have service level agreements (SLAs). This allows you to quickly determine whether the test passed or failed and if performance was affected. + +For additional information, see the [online help](https://admhelp.microfocus.com/lr/en/latest/help/WebHelp/Content/Controller/c_jenkins.htm) or [blog post](https://community.softwaregrp.com/t5/LoadRunner-and-Performance/Continuous-Performance-Testing-Using-Jenkins-CI-CD-Pipelines/ba-p/220264#.WjZnXN-WaUl) about continuous integration with LoadRunner. + +### Table of Contents + +[Prerequisites](#prerequisites) + +[Job types](#job-types) + +[Freestyle jobs](#freestyle-jobs) + +[Pipeline jobs](#pipeline-jobs) + +- [Create a job](#create-a-job) +- [Set up the post-build actions](#set-up-the-post-build-actions) +- [Run the job](#run-the-job) +- [Review the results in the Run Results Viewer](#review-the-results-in-the-run-results-viewer) +- [Review the results in Jenkins](#review-the-results-in-jenkins) + + + +## Prerequisites + +1. Install one of the five latest LTS versions of Jenkins, [(Click here for a list.)](https://jenkins.io/changelog-stable/) + +2. Install the Jenkins [OpenText Application Automation Tools plugin](https://plugins.jenkins.io/hp-application-automation-tools-plugin). + +## Job types + +There are two types of jobs that you can create: **FreeStyle** or **Pipeline**. FreeStyle is more UI friendly and Pipeline is in a form of code which is more flexible. + +1. Go to the Jenkins Server home page. + +2. Click the **New Item **link or select an existing job. + +3. Enter an item name (for a new job). + +## Freestyle jobs + +To set up a Freestyle job: + +1. Select **Free-style project** and click **OK**. + +2. In the Project Configuration section, select **Restrict where this + project can be run**, and select the appropriate node. For details,to [Create an execution + node](README.md#create-an-execution-node). + +3. Scroll down to the **Build** section. + +4. Expand the **Add build step** drop-down and select **Execute OpenText tests from file system**. + +5. Click the **LoadRunner-Specific Settings** button and specify the following settings: + + a. **Controller Polling Interval.** The interval in seconds by which to poll the Controller for the scenario status. The default is 30 seconds. + + b. **Scenario Execution Timeout**. The total time in seconds to allot for the execution of all listed scenarios. After this time, the Controller process will be terminated. + + c. **Errors to Ignore.** You can specify which errors to ignore during the run. For example: *Error: CPU usage for this load generator has exceeded 80%*. Enter each error string on a separate line. + + d. **Analysis Template.** Apply a template for the build (path to a .tem file). Leave it blank in order to use the default template. + + e. **Display Controller.** Display the Controller while the scenario is running. + +6. In the **Tests** box, enter a test with its full absolute path, or a folder or MTB containing one or more tests or LoadRunner scenarios. To specify multiple entries, click the down arrow on the right of the field and enter each test path on a separate line. Make sure that the paths are accessible from all machines in the local network. + +7. Indicate a timeout in seconds after which the job will fail in the **Timeout** box (optional). + +8. Click **Apply** to save your changes and continue with more build steps. Click **Save** when you are finished adding build steps. + +## Pipeline jobs + +To set up a Pipeline job: + +#### Create a job + +1. Select **Pipeline** and click **OK**. + +2. To restrict where this project can run, first refer to [Create an execution + node](README.md#create-an-execution-node) and then see [Controlling your build environment](https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Controlling-your-build-environment). + +3. Scroll down to the **Pipeline** section. + +4. Click **Pipeline Syntax**. + +5. In **Sample Step** select **LoadRunnerTest:** **Run LoadRunner performance scenario tests.** + +6. In the **Tests** box, enter a test with its full absolute path, or a folder or MTB containing one or more tests or LoadRunner scenarios. To specify multiple entries, click the down arrow on the right of the field and enter each test path on a separate line. Make sure that the paths are accessible from all machines in the local network. + +7. In **Report archive mode** follow **Set up the Post Build Actions** section. + +8. Follow the Free Style Job section, steps 5 through 7. + +9. Click **Generate Pipeline Script.** + +10. Copy the output beneath the **Generate Pipeline Script **button. + +11. Go back to the **Pipeline **section. + +12. Paste the copied code into the **Script** block ([read here for how to write + pipeline scripts](https://jenkins.io/doc/book/pipeline/getting-started/)). + +13. Click **Apply** to save your changes and continue with more build steps. Click **Save** when you are finished adding build steps. + +#### Set up the post-build actions + +1. In the **Post-build Actions** section, expand the **Add post-build action** drop-down and select **Publish test result**. + +2. Select an archiving option for the test run results: + + - **Archive test reports for failed tests: **Only save test result reports for failed tests. + - **Always archive test reports:** Always save test result reports. + - **Always archive and publish test reports:** Always save and publish test result reports. + - **Do not archive test reports:** Never save the test results. +#### Run the job + +Run or schedule the job as you would with any standard Jenkins job. + +#### Review the results in the Run Results Viewer + +1. Extract the files from the archive file. When you when you extract the zip file contents, it creates the following folders and files: + +- **LRR folder**- The Controller raw result folder, viewable in LoadRunner Analysis. + - **LRA folder**- The Analysis session folder, viewable in LoadRunner Analysis. + + - **HTML folder**- HTML reports in two subfolders, IE and Netscape, in their respective formats. + +- **SLA.xml** - An XML report showing the status of the SLA in the test. + +2. Open the Run Results Viewer and select **File** \> **Open**. + +3. In the Open dialog box, select\` **Results XML file** and navigate to the *Results.xml* file in the folder that you extracted. + +4. Click **Open** and view the results. + +**Note:** The pass and fail criteria for LoadRunner scenario tests are based on the LoadRunner Service Level Agreement (SLA). If you do not define an SLA, the scenario will fail. For details, see the [LoadRunner Help Center](https://admhelp.microfocus.com/lr/). + +#### Review the results in Jenkins + +You can also view the results from the Jenkins interface, in the following modes: + +- Per job/project + +- Per build/run + +##### **Per Job / Project (cross build / run results)** + +Click **Project performance report** in the left side Job menu. This lets you review the various results from the job, per scenario. You compare the job results using an SLA. + +##### **Per build / run** + +1. Click **Performance report** to examine the performance summary report with its different results. + +2. Click **Transaction summary** to open a detailed view of the transactions statistics taken directly from LoadRunner Analysis report. + +3. Click **Rich Report** to show a high level report of the build run. (This requires you to enable **Rich Reports** in Analysis and generate a PDF. For details, see the [Edit Template dialog box](https://admhelp.microfocus.com/lr/en/latest/help/WebHelp/Content/Analysis/102150_ui_template_dialog.htm). + +4. Click **Simple Junit style SLA result** + + a. Click on "Test result" + + b. Click on "All tests" to see the overview. + + c. Select a scenario by clicking on its name. + + d. Click on **History** in the left panel to compare the results with those from previous runs. + +**Note:** These reports might require you to perform a Security header override. For details, see [Content Security Policy Header](README.md#content-security-policy-header). + +For additional information about the plugin, refer to the [plugin's documentation](README.md). +For general questions, visit our [Google group](https://groups.google.com/forum/#!forum/micro-focus-application-automation-tools-plugin). \ No newline at end of file diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000000..851b3802b7 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,361 @@ +# OpenText Application Automation Tools + + +This [OpenText Application Automation Tools plugin](https://plugins.jenkins.io/hp-application-automation-tools-plugin) integrates OpenText products with Jenkins. Using the plugin, you can create and use virtual services, run LoadRunner Enterprise or LoadRunner Professional tests, run UFT functional tests, run tests in your lab, and run tests on mobile devices. This plugin also lets you upload test results to ALM. In addition, ALM Octane users can track and trigger Jenkins pipelines from within the user interface. + +### Jenkins versions + +This plugin requires one of the five latest [LTS versions](https://jenkins.io/changelog-stable/) of Jenkins. This is a result of the Jenkins policy to no longer support older update centers. Jenkins now requires you to have Java 8 installed on the machine. + +### Submit issues and feedback through JIRA + + +This plugin is open source. If you identify any issues or want to submit enhancement requests, please use [JIRA](https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20component%20%3D%20hp-application-automation-tools-plugin). The component for this plugin is the *hp-application-automation-tools-plugin* component. Your feedback and involvement will allow us to stabilize and enhance the capabilities of the plugin. The latest, early access, beta versions of this plugin are available [here](https://mvnrepository.com/artifact/org.jenkins-ci.plugins/hp-application-automation-tools-plugin). + +A list of known bugs is available [here](https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20not%20in%20(Resolved%2C%20Closed)%20AND%20component%20%3D%20hp-application-automation-tools-plugin%20ORDER%20BY%20votes%20DESC%2C%20watchers%20DESC). + +## Table of Contents + +[New Features and Enhancements](#new-features-and-enhancements) + +[Release notes](#release-notes) + +[Changelog](#changelog) + +[Supported Integrations](#supported-integrations) + +[Prerequisites](#prerequisites) + +[User Guide](#user-guide) + +- [Create an execution node](#create-an-execution-node) +- [Connect an execution node to the Jenkins server](#connect-an-execution-node-to-the-jenkins-server) +- [Support for pipelines](#support-for-pipelines) + +[Enable non-English languages](#enable-non-english-languages) + +[Configuration for Java Web Start clients](#configuration-for-java-web-start-clients) + +[Tips and Troubleshooting](#tips-and-troubleshooting) + +- [Best Practice-Use Slave Machine](#best-practice-use-slave-machine) +- [Content Security Policy Header](#content-security-policy-header) + +- [Integration Issues](#integration-issues) + +- [Workarounds for viewing LoadRunner Performance reports](#workarounds-for-viewing-loadrunner-performance-reports) + +[Limitations](#limitations) + +### Content Security Policy + +Starting with version 1.641 (or 1.625.3), Jenkins introduced the **Content-Security-Policy** header. This causes some of the integration links, such as links to reports, to become inoperable. For details, see [Configuring Content Security Policy](https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy) and [Jenkins Security Advisory ](https://jenkins.io/security/advisory/2015-12-09/). For suggested workarounds until the issue is resolved, see [Content Security Policy Header](#content-security-policy-header). + +## New Features and Enhancements + +Version CE 23.4 introduced the following enhancements and fixes: + +**UFT One** + - Support for access key authentication to run parallel mobile tests. + - Ability to run tests on public devices hosted by ValueEdge Digital Lab. + +**UFT Digital Lab** + - Ability to upload an application to a specific workspace during a Jenkins pipeline cycle. + +**ALM Octane** +- Bug fixes. + +**LoadRunner Enterprise** + - Parameterization support for the Timeslot duration. + +For information about enhancements introduced in previous versions, see [What's new in earlier versions](WhatsNewEarlier.md). + +## Changelog + +The [Changelog ](https://wiki.jenkins.io/display/JENKINS/Changelog)page lists the bug fix changes in the versions of the plugin. + + +- [Version 5.6.2](https://wiki.jenkins.io/display/JENKINS/Changelog#Version5.6.2(Dec19,2018)) + +- [Version 5.6.1](https://wiki.jenkins.io/display/JENKINS/Changelog#Version5.6.1(Dec18,2018)) + +- [Version 5.5.2](https://wiki.jenkins.io/display/JENKINS/Changelog#Version5.5.2Beta(Oct2,2018)) + +- [Version 5.5.1](https://wiki.jenkins.io/display/JENKINS/Changelog#Version5.5.1(Sept12,2018)) + + + +## Supported Integrations + + + +This plugin supports the following OpenText product versions: + +| OpenText tool | Supported versions | Find more information... | +| :-------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ | +| ALM (Application Lifecycle Management) | 12.xx, 15.x, 16.x, 17.x | [ALM Integration page](https://admhelp.microfocus.com/alm/en/latest/online_help/Content/jenkins-integration.htm) | +| ALM Lab Management | 12.xx, 15.x, 16.x, 17.x | [ALM Integration page](https://admhelp.microfocus.com/alm/en/latest/online_help/Content/jenkins-integration.htm#mt-item-3) | +| ALM Octane | 12.53.20 and higher (12.55.4 or later required for direct UFT One integration and for LoadRunner Enterprise integration using pipelines) | [ALM Octane Help Center](https://admhelp.microfocus.com/octane/en/latest/Online/Content/AdminGuide/jenkins-integration.htm) | +| LoadRunner Enterprise | 12.xx (12.53 or higher required for trend reports), 2020 and higher | [LoadRunner Enterprise Help Center](https://admhelp.microfocus.com/lre/en/latest/online_help/Content/PC/Continuous-Integration-Jenkins.htm) | +| LoadRunner Professional | 12.xx, 2020 and higher | [LoadRunner Professional Integration page](https://admhelp.microfocus.com/lr/en/latest/help/WebHelp/Content/Controller/c_jenkins.htm) | +| Model-based Testing | 16.0.300 and higher | [Model-Based Testing Help Center](https://admhelp.microfocus.com/mbt) | +| Service Virtualization | 3.80 and higher | [Service Virtualization Help Center](https://admhelp.microfocus.com/sv/en/latest/Help/Content/UG/c_continuous_integration.htm) | +| UFT Developer | 14.03 and higher | [UFT Developer Help Center](https://admhelp.microfocus.com/uftdev/en/latest/HelpCenter/Content/HowTo/CI_Tools.htm)
Blog: [Integrate LeanFT with Jenkins in just a few simple steps](https://community.microfocus.com/adtd/b/sws-alm/posts/integrating-leanft-with-jenkins-in-just-a-few-simple-steps) | +| Digital Lab (UFT Mobile) | 2.0 and higher | [Digital Lab Integration page](https://admhelp.microfocus.com/digitallab/en/latest/Content/CI_jenkins.htm) | +| UFT One | 12.xx and 14.03 and higher | [UFT One Help Center](https://admhelp.microfocus.com/uft/en/latest/UFT_Help/Content/User_Guide/Jenkins.htm) | +| ValueEdge | | [ValueEdge Help Center](https://admhelp.microfocus.com/valuedge) | + +## Prerequisites + +1. Install one of the five latest LTS versions of Jenkins. For details, see the [LTS Changelog](https://jenkins.io/changelog-stable/). **Note:** The plugin may not operate properly with earlier versions of Jenkins. + +2. **Java version 8 or higher.** To verify your Java version, go to [http://www.java.com/en/download/installed.jsp](http://www.java.com/en/download/installed.jsp). + +3. Install the plugin: + + a. Download the .hpi file for the Jenkins plugin from the [plugin page]( https://updates.jenkins-ci.org/download/plugins/hp-application-automation-tools-plugin/ ). + + b. Navigate to the **Manage Jenkins > Manage Plugins > Advanced** tab. + + c. In the **Upload Plugin** section, upload the .hpi file. +4. **For working with ALM and Quality Center,** make sure the ALM/Quality Center client is installed on the machine that will run the tests. To check if the client installed, follow the instructions on: http://:8080/qcbin/TDConnectivity\_index.html + +5. **For running UFT One tests from ALM** install the ALMClient in common registration mode by accessing the following link from an Internet Explorer browser on the UFT One machine: http://:8080/qcbin/start\_a.jsp?Common=true + +6. **For running file system scenarios with LoadRunner Professional or UFT One** set up a node in Jenkins. For details, see [Create an execution node](#create-an-execution-node). + +7. **For building and tracking pipelines on ALM Octane:** + + * JQuery Plugin 1.7.2-1 or later (Required to enable the integration) + * A plugin that enables publishing test results. For example, JUnit Plugin 1.10 or later, NUnit plugin, and so on (Required to enable ALM Octane to collect your automated test results). + +8. **For ALM Octane integration with UFT One**, make sure you have version 2.4.4 or higher of the Git plugin. + +# User Guide + +You can run client side-or server-side (Default or Functional) test sets and build verification suites from Application Lifecycle Management (ALM) or functional tests from the file system. You can create and configure ALM Octane pipelines from the ALM Octane user interface, or on Jenkins. + + +## Create an execution node + +1. Creating an execution node is only required when running scenarios from LoadRunner Professional or UFT One, that are stored on the file system. You only need to set an execution node if the Jenkins master machine is **not** the executing machine. If you are running LoadRunner Professional or UFT One on the master machine, you do not need to set and select a node. + +2. Go to the Jenkins Server home page. + +3. Click the **Manage Jenkins** link in the left pane. + +4. In the Manage Jenkins Page click **Manage Nodes**. + +5. Click **New Node**. + +6. Enter a **Node name** , select **Permanent Agent** , and then click **OK**. + +7. In the next screen, enter information in the required fields. Enter the full path of the **Remote Root directory** , to which the tests results will be saved. + +8. Provide one or more labels for the node. Separate the values with a space. Through these labels, you will be able to identify the nodes used in the job. + +9. In the **Usage** area, select **Only build jobs with label expressions matching this node**. + +10. Click **Save**. + +11. Connect the execution node to the Jenkins server as described below. + + + +## Connect an execution node to the Jenkins server + +To connect and execution node to the Jenkins machine: + +1. On the computer that you defined as an execution node, open a browser and go to the Jenkins Server home page. + +2. Open **Manage Jenkins** **>** **Manage Nodes**. + +3. If there is a warning mark adjacent to the node you want to connect, click the node's link. You are prompted to connect the agent to Jenkins. + +4. Click **Launch** to download the agent and then run the downloaded agent. Alternatively, use one of the other methods suggested on the screen. + + + +## Support for Pipelines + +### Generate pipeline code + +To set up a pipeline test job for your OpenText testing tool: + + 1. From Jenkins Dashboard. click **New Item** or select an existing one. + + 2. On the page that opens, enter an item name (for a new job), click **Build a Pipeline project** , and click **OK**. + + 3. In the Project Configuration page, scroll down to the **Pipeline** section. + + 4. Enter the **stage** and **node** arguments into the **Script** area. For example, + + ``` + stage('RunUFTTestFromFS'){ // The stage name + node('Test'){// The name of the node in which to run the test. + ``` + + 5. Prepare the code for your testing tool: + + a. Click the **Pipeline Syntax** link. + b. In the Snippet Generator drop down, select the desired step, for example, **uftScenarioLoad: Run UFT scenario**. + c. Fill in the fields as required. Fields marked in red are mandatory. **Note:** For fields that take multiple values, such as in the **Tests** field, separate multiple entries with a line break. + d. If relevant, select one of the [Report archive modes](#report-archive-modes). + e. Click **Generate Pipeline Script**. Copy the code to the clipboard. + +6. Return to the Project Configuration page, and paste the generated Groovy script into the **Script** field in the Pipeline section. + +7. Repeat the above steps to add other commands to your script. + +8. Save the script and run or schedule the job as you would with any standard Jenkins job. + +9. After the test run, click the **Console** link on the dashboard to see a link to your results. Copy the link to your browser (Internet Explorer required to view ALM test sets in ALM). + + + +### Supported Pipeline job types + +The available Pipeline job types are: loadRunnerTest, uftScenarioLoad, runFromFSBuilder, runFromAlmBuilder, sseBuild, sseBuildAndPublish, pcBuild, svChangeModeStep, svDeployStep, svExportStep, svUndeployStep, and publishMFTestResults + +| Product | Pipeline step name | Description | +| ---------------------- | ---------------------------- | ------------------------------------------------------------------ | +| LoadRunner Professional| loadRunnerTest | Run LoadRunner Professional tests from a file system scenario file.| +| UFT One | uftScenarioLoad | Run a UFT scenario. **Deprecated**, but backwards compatibility exists.| +| UFT One | runFromFSBuilder | Execute UFT One Tests from the file system. | +| ALM | runFromAlmBuilder | Execute functional tests from ALM. | +| ALM Lab Management | sseBuild | Execute tests using ALM Lab Management. | +| ALM Lab Management | sseBuildAndPublish | Execute tests using ALM Lab Management and publish test results. | +| LoadRunner Enterprise | pcBuild | Execute tests using LoadRunner Enterprise. | +| Service Virtualization | svChangeModeStep | Change the mode of a virtual service. | +| Service Virtualization | svDeployStep | Deploy a virtual service. | +| Service Virtualization | svExportStep | Export a virtual service. | +| Service Virtualization | svUndeployStep | Undeploy a virtual service. | +| UFT One, ALM, ALM LM | publishMicroFocusTestResults | Publish Test Results for FS, ALM and ALM Lab Management executions. | | + +Pipeline jobs are not supported for Digital Lab (formerly UFT Mobile) uploads, ALM test uploader, and ALM AUT job types. + + + +### Report archive modes + +The available archive modes are: + +- Archive test report for failed tests + +- Always archive test reports + +- Always archive and publish test reports (LRP only) + +- Do not archive test reports + + + +## Enable Non-English Languages + +In order to allow the add-in to support non-English languages, make the following changes to your Jenkins Master and nodes configuration: + +### Master configuration + +1. Open the **Jenkins.xml** file in the Jenkins installation folder, for example: c:\Jenkins\Jenkins.xml. + +2. Go to the \ -> \ section and add the **-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8** flags after the **-jar** flag. + +### Slave configuration + +1. Open the **jenkins-slave.xml** file on the Jenkins slave (node) machine in the folder that you designated. + +2. Go to the \ -> \ section and add the **-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8** flags after the **-jar** flag. + +For example: + +``` + +jenkinsslave-c__jkns +jenkinsslave-c__jkns +This service runs a slave for Jenkins continuous integration system. + +C:\Program Files (x86)\Java\jre1.8.0_91\bin\java.exe +-Xrs -jar "%BASE%\slave.jar" -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 -jnlpUrl http://xxx.xxx.xxx.xxx:8080/jenkins/computer/VM112233/slave-agent.jnlp -secret xyzabc + +rotate + + +``` +## Configuration for Java Web Start clients + +1. On the Jenkins master machine, go to **Manage Jenkins --> Manage Nodes**. Click the relevant node or slave. and select **Slave --> Configure --> Advanced**. +2. Add the following to the JVM options text box: **"-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8"**. +3. Restart your Jenkins master, node, and slave. +4. Verify that your changes took effect: + a. For the Master: Go to **Manage Jenkins --> System information --> "file.encoding", "sun.jnu.encoding"**. The value should be "UTF-8". + b. For the node/slave: On the master machine, go to **Manage Jenkins --> Manage Nodes**. + c. Click on the relevant node or slave and select **System information --> "file.encoding", "sun.jnu.encoding"**. The value should be "UTF-8". + +**Workaround:** If you find that the slave machine still does not support localized encoding, launch the slave from the command line as shown in the image below: + +For example: + +![Jenkins_slave_command_line](Jenkins_slave_setup.png) + +## Tips and Troubleshooting + +### Best Practice-Use Slave Machine + +For best performance, it is recommended to install the testing tools and ALM/QC as nodes on slave machines, and not directly on the Jenkins server. For instructions on configuring nodes, see the [Step by step guide to set up master and agent machines in Windows]( https://wiki.jenkins.io/display/JENKINS/Step+by+step+guide+to+set+up+master+and+agent+machines+on+Windows ). + +On the Jenkins slave machine, make sure the the Jenkins Slave service is not logged in with the **Local System account**. To function properly, it should log in with an account the has administrator privileges. + +![Jenkins_slave_account](Jenkins_slave_account.png) + + + +### Content Security Policy Header + +Starting with version 1.641 (or 1.625.3), Jenkins introduced the **Content-Security-Policy** header. This prevents some of the links that appear in the integration to become inoperable. For example, the links to the LoadRunner Performance and UFT One HTML reports will not work. + +For workarounds to enable viewing UFT One HTML Reports, see the [UFT One Help Center](https://admhelp.microfocus.com/uft/en/latest/UFT_Help/Content/User_Guide/Jenkins.htm#mt-item-5). + + + +### Integration Issues + +- If your job includes UFT One, QTP, or Service Test tests running on a remote ALM/QC machine (run mode = Run Remotely), you should manually stop the test execution. + +- When UFT is installed on the slave machine (node), the LoadRunner test job will fail in the **Analyze Result** stage. **Workaround:** Add the path of the LoadRunner **bin** folder ( **%LR\_PATH%/bin** ) to the **PATH** environment variable. + + + +### Workarounds for viewing LoadRunner Performance reports + +Follow these workarounds to enable the viewing LoadRunner Performance reports: + +- View the reports locally on the slave machine, in your Jenkins results folder under the relevant build ID, or on the master machine in the Jenkins builds folder. Go to the **%jenkins% \jobs\\\builds\\PerformanceReport** folder. For example, **C:\Program Files (x86)\Jenkins\jobs\Plug\_Debug\builds\5\PerformanceReport\index.html**. + +- Click **Manage Jenkins > Script Console** , and run one of the following scripts from the console: + + - Type the following line and press **Run**. + `System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")` + + - Alternatively, type the following line and press **Run**. + `System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox; default-src 'none'; img-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; child-src 'self';")` + + - Another option that is more secure, but it disables the left pane menu and embedded Javascript: + `System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox; default-src 'none'; img-src 'self'; style-src 'self'; script-src 'self'; child-src 'self';")` + +## Limitations + +### Test Parameters syntax + +The following limitations apply to the inline parameter specification feature of the **Test Sets** input field: + + - The double quote and space character sequence (` "`) is used to separate the path and parameter list specification. As a result, if you specify the test set path with double quotes, the line won't parse correctly. **Tip:** never specify paths with double quotes when using inline parameters. **Note:** If the path contains whitespaces, the path will be parsed correctly without the quotes. + - The parameter list's delimiter is a comma. Therefore, neither the path, nor the parameter names or values should contain commas. **Tip:** if you have a complex parameter value (e.g. `"param1"="value1,value2"`), specify separate parameters for this within the respective UFT One test. + - The parameter-value key-value pair is separated by a colon. Therefore, neither the parameter name, nor the value should contain a colon. **Note:** Currently, due to this limitation, **links** cannot be used in the inline parameter definitions. + +**Note**: If any of the above limitations appears within your inline parameter definition, the line will not be parsed correctly, resulting in unexpected behavior in the job execution. diff --git a/doc/UFT_Mobile_Integration.md b/doc/UFT_Mobile_Integration.md new file mode 100644 index 0000000000..10cee6dc68 --- /dev/null +++ b/doc/UFT_Mobile_Integration.md @@ -0,0 +1,83 @@ +# Digital Lab integration + +The Application Automation Tools plugin for the Jenkins continuous integration server provides a mechanism for uploading apps to the Digital Lab lab console. + +First you define the Digital Lab server within Jenkins, and then you add build steps to upload your mobile apps with .apk (Android) or .ipa (iOS) file extensions. + +For additional information, see the [Digital Lab Help Center](https://admhelp.microfocus.com/digitallab/en/). + +### Table of Contents + +[Prerequisites](#prerequisites) + +[Define the Digital Lab server](#define-the-digital-lab-server) + +[Use Digital Lab with SSL](#use-digital-lab-with-ssl) + +[Upload apps to Digital Lab](#upload-apps-to-digital-lab) + + + +## Prerequisites + +1. Install one of the five latest LTS versions of Jenkins, [(Click here for a list.)](https://jenkins.io/changelog-stable/) + +2. Install the Jenkins [Micro Focus Application Automation Tools plugin](https://plugins.jenkins.io/hp-application-automation-tools-plugin). + + + +## Define the Digital Lab server + +Before using Jenkins with Digital Lab, you need to configure Jenkins to recognize the Digital Lab server. + +To configure Jenkins to integrate with Digital Lab: + +1. On the Jenkins Server home page, click **Manage Jenkins > Configure System**. + +2. Go to the **Digital Lab** section, and click **Add Digital Lab server**. + +3. Enter a name for the Digital Lab server that you will be using, and its URL. + +4. Repeat the last two steps for each of the Digital Lab servers that you will be accessing. + +5. For running functional tests where UFT and Jenkins are hosted on separate machines, you need to create an execution node for the functional test: + + a. Select **Manage Jenkins > Manage Nodes and Clouds > New Node**. + + b. Give the node a name, and select the **Permanent Agent** option. + + c. Enter the details for the UFT machine. + + d. Save your changes. + +## Use Digital Lab with SSL + +If you need to use Digital Lab securely, with SSL, you must first install the UFTM server certificate. + +1. Copy the UFTM server certificate to the Jenkins server machine. +2. Import the UFTM server certificate on the Jenkins server machine using the following command: + ``` + keytool.exe -import -file "\.cer" + -keystore "C:\Program Files (x86)\Jenkins\jre\lib\security\cacerts" + -alias mc -storepass changeit -noprompt +3. Restart the Jenkins service. + +## Upload apps to Digital Lab + +The **Application Automation Tools** Jenkins plugin provides a standalone builder for uploading apps to Digital Lab. If you want to create a job that runs a UFT One functional test with Mobile devices, see the [UFT One Help Center](https://admhelp.microfocus.com/uft/en/latest/UFT_Help/Content/MC/mobile_on_UFT_Jenkins_integ.htm). + +1. Make sure you have added your Digital Lab server to the Jenkins configuration as described in [Define the Digital Lab server](#define-the-digital-lab-server). +2. Copy your application package file, with **.apk** or **.ipa** extensions, to the Jenkins machine. +3. On the Jenkins Server home page, click **New Item**. +4. Enter an item name for the project. +5. Select **Free style project** and click **OK** in the bottom left corner. +6. In the **General** tab, scroll down to the **Build** section. +7. Expand the **Add build step** drop-down and select **Upload app to Digital Lab**. +8. Select your Digital Lab server from the drop-down list of servers. +9. Provide your login credentials. If your server has the multiple share spaces enabled, you must also include the nine-digit project ID in the **Tenant ID** field. If the feature is not enabled, you must leave this field empty. +10. If you are connecting to a Digital Lab server through a proxy, select **Use proxy settings** and provide the relevant information. +11. Click **Add Application** and enter the full path of the **.apk** or **.ipa** package file of the app you want to upload to the Digital Lab server. Repeat this step for each app you want to upload. +12. Click **Apply** to save your changes and continue with more build steps. +13. Click **Save** when you are finished adding build steps. +14. Run or trigger the job as you would with any standard Jenkins job. +15. To troubleshoot, check the log file on the Digital Lab server for issues such as connectivity and security. diff --git a/doc/WhatsNewEarlier.md b/doc/WhatsNewEarlier.md new file mode 100644 index 0000000000..18d0f5af9a --- /dev/null +++ b/doc/WhatsNewEarlier.md @@ -0,0 +1,385 @@ +# What's new in earlier versions + + +This page shows a history of the enhancements made to the OpenText Application Automation Tools Jenkins plugin. + +See the [Changelog ](https://wiki.jenkins.io/display/JENKINS/Changelog)for information about beta versions and recent patches. + +[What's New in version 23.3.0 ](#what's-new-in-version-23.3.0) + +[What's New in version 8.0 ](#what's-new-in-version-8.0) + +[What's New in versions 7.7 and 7.8 ](#what's-new-in-versions-7.7-and-7'8) + +[What's New in version 7.6 ](#what's-new-in-version-7.6) + +[What's New in version 7.5 ](#what's-new-in-version-7.5) + +[What's New in version 7.4 ](#what's-new-in-version-7.4) + +[What's New in version 7.3 ](#what's-new-in-version-7.3) + +[What's New in version 7.2 ](#what's-new-in-version-7.2) + +[What's New in version 7.1 ](#what's-new-in-version-7.1) + +[What's New in version 7.0 ](#what's-new-in-version-7.0) + +[What's New in version 6.9 ](#what's-new-in-version-6.9) + +[What's New in versions 6.7 and 6.8 ](#what's-new-in-versions-6.7-and-6'8) + +[What's New in version 6.6 ](#what's-new-in-version-6.6) + +[What's New in version 6.5 ](#what's-new-in-version-6.5) + +[What's New in version 6.4 ](#what's-new-in-version-6.4) + +[What's New in version 6.3 ](#what's-new-in-version-6.3) + +[What's New in version 6.0 ](#what's-new-in-version-6.0) + +[What's New in version 5.9 ](#what's-new-in-version-5.9) + +## What's New in version 23.3.0 + +Version 23.3.0 introduced the following enhancements and fixes: + +**ALM Octane** +- Bug fixes. + +**UFT One** + - Company name rebranded to OpenText. + - UFT Mobile renamed to Digital Lab. + - Enhancement of File System jobs to work correctly inside Docker. + - Bug fixes and optimizations. + + +## What's New in version 8.0 + +Version 8.0 introduced the following enhancements and fixes: + +**ALM Octane** + +- Support for Active choice parameters with Jenkins. +- Bug fixes. + +For information about enhancements introduced in previous versions, see [What's new in earlier versions](WhatsNewEarlier.md). + +## What's New in versions 7.7 and 7.8 + +Versions 7.7 and 7.8 introduced the following enhancements and fixes: + +**ALM Octane** + +- Support for environment variables in auto actions. +- Bug fixes. + +**ALM** + +- 'Ability to use the Jenkins proxy settings to open a connection when verifying the ALM URL. + +**UFT One** + +- Support running UFT One as a different user. +- Release UFT One license safely when aborting Jenkins builds. +- Bug fixes and optimizations. + +## What's New in version 7.6 + +Version 7.6 introduced the following enhancements and fixes: + +**UFT One** + +- Implementation of the **Password** type for the Table of Parameters (for ALM and File System jobs) +- A job level option to hide the logging of parameters (for File System jobs) +- The ability to transfer parameters from one test to another through a batch command (using MTBX, for File System jobs) +- Layout bug fixes and optimizations + +**ALM Octane** + +- Abilitiy to enable the **ALM Octane pipeline** action for multi-branch projects +- HTTPS support for the Security tool +- Defect fixes + +## What's New in version 7.5 + +Version 7.5 introduced the following enhancements and fixes: + +**ALM** + +- For the **Upload test result to ALM using field mapping** build step: + - You can now search for a test set by its name in a specific folder instead of all folders. + - Defect fix: The check for the test map name is suppressed if no new test is being created. + +**UFT One** + +- Layout fixes that were broken in Jenkins 2.346.1 LTS latest version. + +## What's New in version 7.4 + +Version 7.4 introduced the following enhancements: + +**ALM Octane** + +- Added the **Default branches** setting. This allows ALM Octane to enable the selection of parameters for multi-branch CI jobs used in the *Run CI Job* auto action. This change allows ALM Octane to validate the branch name used for the multi-branch CI job. +- The log4j version was updated from 2.17.1 to 2.17.2. +- Defect fixes. + +**UFT One** + +- Enhanced data security in UFT One’s Jenkins tasks. A public-private key pair is used to encrypt and decrypt sensitive data on each execution node. +- Access Key authentication support for UFT Mobile (supported from UFT One 2021 R1 Patch1) +- Support for the Java 11 JAXB dependency. +- Ability to specify the UFT Report timestamp format, by defining a date format on the Jenkins configuration page. (Manage Jenkins > Configure System, Run Result (UFT Report) timestamp format string section). +- Console Output text encoding configuration on the job level. +- Layout improvements. + +## Release notes + +Pipeline scripts are empty in the script editor from within job configurations. You can view scripts in the config.xml file for each job. This issue does not affect the functionality of the plugin. **Note:** This limitation only applies to version 7.4. A fix was provided in version 7.4.1 Beta. + +## What's New in version 7.3 + +Version 7.3 introduced the following enhancements: + +**ALM Octane** + +- Code improvements for MBT, model-based testing. +- Support for Codeless text executions. +- Defect fixes. + +**Model-Based Testing** + +- Code improvements. +- Support for Windows and Linux upper case/lower case strings. +- Defect fixes. + +**UFT One** + +- Partial test result reporting for aborted Jenkins jobs, for file system executions. When a Jenkins job execution is aborted or cancelled, all the test results until that point, will be available in the build. +- Improved parameter configuration for UFT One tests using a new parameter table, for file system and ALM execution. You can now add different types of parameters, for both GUI and API tests. +- Improvements in the re-run option for failed scenarios in file system executions, where tests finished with a Warning status. +- Improved reporting for UFT One tests with same name, but different locations. +- Enhancements to secure log4j issues. + +**Service Virtualization** + +- Ability to switch virtual services to OFFLINE mode. + +## What's New in version 7.2 + +Version 7.2 introduced the following enhancements: + +**General** + +- Updated plugin to handle log4j security issue. + +**UFT One** + +- Parsing of UFT test names by Jenkins. + +## What's New in version 7.1 + +Version 7.1 introduced the following enhancements: + +**General** + +- More user-friendly layout + +**LoadRunner Entrerprise** + +- Security fix: Beginning with Jenkins version 2.303.3, the LoadRunner Enterprise build step requires the security fix introduced in this release + +**ALM Octane** + +- Support execution of BDD tests in testing framework +- UFT One test runner can inject Octane details as test parameters. (This requires you to define the global parameter ADD_GLOBAL_PARAMETERS_TO_TESTS.) +- Support for the Fortify SSC plugin version 21.1.36 +- Supports triggering test suites from Jenkins, from the Execute tests build step + +**UFT One** + +- Parsing test parameters enhancement for UFT One Tests through Jenkins, for file system executions. For limitations, see [Limitations in Test Parameters syntax](#test-parameters-syntax). +- The **Warning** test status is now handled for tests executed from ALM +- Final job status improvements for jobs exceeding the specified timeout +- More secure credential handling with the introduction of Job level and Global level credential handling +- Defect fix: Handling of special characters and the NULL value for test parameters +- Defect fix: Non-existent test sets are now handled and taken into consideration in the job execution + +## What's New in version 7.0 + +Version 7.0 introduced the following enhancements: + +**ALM Octane** + +- Support for pipeline stop +- Support for BDD scenarios in test runners +- Support for version 21.1.36 of the Fortify SSC plugin +- Defect fix - Octane builds no longer point to obsolete UFTOne run results + +**UFT One** + +- Ability to use the Micro Focus plugin on an air-gap network (not connected to the Internet) for ALM executions +- Run Results enhancements, including the use of MTBX files for test execution +- Defect fix - Layout issues were handled + +**LoadRunner Enterprise** + +- Defect fix - It is now possible to browse for the Test ID in the Jenkins plugin. + +## What's New in version 6.9 + +Version 6.9 introduced the following enhancements: + +**ALM Octane** + +- Enabled branch publisher +- Support added for Java 11 + +**Workarounds** + +- For running UFTM tests from UFT One: If UFTM tests fail in UFT One after changing the UFTM server version in the Jenkins configuration, manually restart UFT One and run the test again. + +## What's New in versions 6.7 and 6.8 + +Versions 6.7 and 6.8 introduced the following enhancements: + +**General** + +- Security fixes: Security issues noted in the *Jenkins Security Advisory 2021-04-07* were addressed. For details, search for SECURITY-2132, SECURITY-2175, and SECURITY-2176 in the [Jenkins Security Advisory 2021-04-07 page](https://www.jenkins.io/security/advisory/2021-04-07/). (Version 6.8) +- Added support for the FOD plugin version 6.1.0. +- SonarQube integration: A new option was added to the Sonar pre-build step to skip automatic webhook configuration. (This allows you to run the integration without admin permissions.) + - Added XSRF protection for running with Lab, Upload result, and Common result upload for compatibility with new versions of ALM. + +**ALM Octane – UFT Integration** + +- Reduced the length of the folder name for checkout of auto-generated execution jobs. +- [Bug fix] Ability to execute UFT tests not located in job workspace. To show the test name correctly in ALM Octane, define the "UFT_CHECKOUT_FOLDER" parameter. +- [Bug fix] For the Spanish Windows slave: The duration of a UFT test in Jenkins now displays correctly, in seconds. + +**ALM Octane** + +- Added the option to inject pull requests to ALM Octane with repository in SSH format. +- Auto-fill: After injection of pull-requests, templates related to SCM repositories are auto-filled in ALM Octane (Settings > Spaces-> DevOps > SCM Repositories). + +**LRE (LoadRunner Enterprise)** + +- The build step “Execute performance test using LoadRunner Enterprise” can authenticate to LoadRunner Enterprise using an access key (available from LoadRunner Enterprise 2021 R1). + +## What's New in version 6.6 + +Version 6.6 introduced the following enhancements: + +**General** + +- Compliance with the new Jenkins version 2.264 form layout +- Certified for Jenkins version 2.264.1 + +## What's New in version 6.5 + +Version 6.5 introduced the following enhancements: + +**General** + +- “github-branch-source” dependency was removed. +- Certified for Jenkins version 2.263.1. + +**ALM Octane** + +- New option to cache the job list for pipeline creation in ALM Octane +- Caching of Octane pipeline roots, to avoid sending non-relevant events/tasks/logs to ALM Octane +- Added ability to execute UFT tests with parameters from ALM Octane +- Bug fix: UFT test descriptions are properly formatted in ALM Octane + +## What's New in version 6.4 + +Version 6.4 introduced the following enhancements: + +**General** + +- Multiple dependencies updated. You can verify your Jenkins plugins compatibility with the [plugin dependencies](https://plugins.jenkins.io/hp-application-automation-tools-plugin/#dependencies). +- Certified for Jenkins version 2.249.1. + +**ALM Octane** + +- Ability to configure folder for UFT Test Runner creation +- Ability to create auto-generated UFT jobs with SSH credentials +- Reduced name length of UFT auto-generated Test Runner jobs +- Added support for Configuration-as-code plugin to ALM Octane configuration +- collectPullRequestsToAlmOctane pipeline step – now supports environment parameters for all fields (including credentialsId) + +**UFT One** + +- Migration of ALM credentials from the Task configuration page to global configuration + +## What's New in version 6.3 + +Version 6.3 introduced the following enhancements: + +**ALM Octane** + +- Ability to disable configuration + +- Ability to configure jenkinsUser per ALM Octane workspace and to restrict job visibility during new pipeline creation + +- Ability to configure ALM Octane allowed storage for logs + +- Support for base64 encoding for jobIds (relevant for ALM Octane behind an Apache server) + +- New icons indicating the connected workspaces + +- Bug fix: The UFT Discovery job now populates the description of UFT API tests. + +- Bug fix: Connectivity issue where ALM indicated that Jenkins was not connected, was resolved. + +- Bug fix: CI pipeline jobs are automatically updated when you rename or move jobs. + +**UFT One** + +- Support for defining the number of iterations for UFT tests + +## What's New in version 6.0 + +Version 6.0 introduced the following enhancements: + +**ALM Octane** + +- You can now SET/GET milestones on ALM Octane Pipeline configurations. + + +## What's New in version 5.9 + +Version 5.9 introduced the following enhancements: + +**ALM Octane** + +- Support for custom converters to test frameworks + +- Improvements in logs + +- Support for additional versions of the Sonarqube scanner plugin (2.6.1, 2.8.1, 2.9) + +- Bug fixes + +**UFT Mobile (Mobile Center)** + +- Rebrand from "Mobile Center" to "UFT Mobile" + +**ALM** + +- Improvements in the logic of parsing test case status. + +https://issues.jenkins-ci.org/browse/JENKINS-58134 + +**UFT** + +- Support for ALM 15.0 with SSO + +- Refactoring of HpToolsLauncher + +- Bug fixes + +Note: This version of the plugin does not work with UFT Mobile 3.3 and UFT 14.03. + + diff --git a/pom.xml b/pom.xml index 7f70605330..9d7d16b9bf 100644 --- a/pom.xml +++ b/pom.xml @@ -1,579 +1,664 @@ - - 4.0.0 - - org.jenkins-ci.plugins - plugin - 2.14 - - - - hp-application-automation-tools-plugin - 5.1 - hpi - HP Application Automation Tools - The plugin integrates Jenkins with the following HPE products - Service Virtualization, LoadRunner, Performance Center, Unified Functional Testing, QuickTest Professional, Service Test, Mobile Center, Application Lifecycle Management and Application Lifecycle Management Octane. - https://wiki.jenkins-ci.org/display/JENKINS/HP+Application+Automation+Tools - - - - MIT License - http://www.opensource.org/licenses/mit-license.php - repo - - - - - 1 - C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe - Release - 1.642.4 - 2.2 - 1.0.2 - false - - - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/releases - - - maven.jenkins-ci.org - https://repo.jenkins-ci.org/snapshots - - - - - scm:git:ssh://github.com/hpsa/hp-application-automation-tools-plugin.git - scm:git:ssh://git@github.com/hpsa/hp-application-automation-tools-plugin.git - - https://github.com/hpsa/hp-application-automation-tools-plugin - HEAD - - - JIRA - https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20component%20%3D%20hp-application-automation-tools-plugin - - - - HPE - http://www.hpe.com - - - - - YafimK - Fima (Yafim) Kazak - kazak@hpe.com - - Global owner and Load Runner Dev - - - - mseldin - Michael Seldin - michael.seldin@hpe.com - - ALM Octane - - - - Rlu - Roy Lu - li.lu@hpe.com - - ALM Lab managment - - - - pavelchuchma - Pavel Chuchma - pavel.chuchma@hpe.com - - Service Virtualization - - - - imrman - Avishai Moshka - avishai.moshka@hp.com - - LoadRunner - - - - amitb - Amit Bezalel - amit.bezalel@hpe.com - - UFT - - - - bamh - Hanan Bem - hanan.bem@hpe.com - - Performance Center - - - - michaelhpe - Weimin Jing - weimin.jing@hpe.com - - Mobile Center - - - - JackyZhuHPE - Chunjiang Zhu (Jacky) - chun-jiang.zhu@hpe.com - - ALM/Upload test result to ALM (External Test) - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - exec-maven-plugin - [1.2.1,) - - java - exec - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - - org.apache.maven.plugins - maven-javadoc-plugin - - -Xdoclint:none - - - - org.codehaus.mojo - findbugs-maven-plugin - - - none - - - - true - - - - - org.codehaus.mojo - exec-maven-plugin - 1.4.0 - - ${msbuild.exe} - ${basedir}/HpToolsLauncher - ${maven.exec.skip} - - - - InstallPlugin - "${project.artifactId}" - install - - exec - - - - false - java - - -jar - ${env.JENKINS_HOME}war\WEB-INF\jenkins-cli.jar - -s - http://localhost:8080 - install-plugin - ${project.build.directory}\${project.build.finalName}.${project.packaging} - -name - "${project.artifactId}" - - -restart - --password-file ${id_rsa_file} - - - - - clean HPToolsLauncher - clean - - exec - - - - /t:Clean - /p:Configuration=${msbuild.configuration} - - - - - creating HPToolsLauncher - generate-resources - - exec - - - - /t:Rebuild - /p:Configuration=${msbuild.configuration} - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - - **/ConfigApiTest.java - **/ConfigurationServiceTest.java - **/JUnitResultsTest.java - **/TestApiTest.java - **/TestDispatcherTest.java - **/BuildActionsFreeStyleTest.java - **/GherkinResultsTest.java - **/TestNGExtensionTest.java - - - - - - - - - - - - - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - - central - http://repo1.maven.org/maven2 - - - hp-application-automation-tools-plugin-mvn-repo - https://raw.github.com/HpeServiceVirtualization/3g/mvn-repo/ - - - bintray-adm-maven - bintray - http://dl.bintray.com/adm/maven - - - - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - - - - - org.jenkins-ci.plugins.workflow - workflow-aggregator - ${workflow.version} - - - org.apache.httpcomponents - httpclient - 4.5.2 - - - org.apache.httpcomponents - httpcore - 4.4.4 - - - com.jayway.jsonpath - json-path - 1.1.0 - - - org.jenkins-ci.plugins - matrix-project - 1.6 - - - org.jenkins-ci.plugins.workflow - workflow-step-api - ${workflow.version} - - - org.jenkins-ci.plugins.workflow - workflow-step-api - ${workflow.version} - tests - test - - - - org.jenkins-ci.plugins.workflow - workflow-cps - 2.6 - - - - org.jenkins-ci.plugins - pipeline-build-step - 2.2 - - - - org.jenkins-ci.plugins - structs - 1.4 - - - org.jenkins-ci - symbol-annotation - 1.4 - - - org.jenkins-ci.plugins - credentials - 2.1.4 - - - com.hp.sv - SVConfigurator - 3.82.1.45909 - - - commons-io - commons-io - - - - - org.jenkins-ci.plugins - junit - 1.19 - - - - - - - - integrations-sdk - com.hpe.alm.octane.plugins - 1.0 - - - - - mqm-rest-client - com.hpe.alm.octane.plugins - 1.0 - - - - - org.jenkins-ci.main - maven-plugin - 2.6 - - - - org.jenkins-ci.plugins - branch-api - 1.10 - true - - - - org.jenkins-ci.plugins - ssh-credentials - 1.13 - - - - org.jenkins-ci.plugins - git-server - 1.7 - true - - - - org.jenkins-ci.plugins.pipeline-stage-view - pipeline-rest-api - 1.7 - true - - - - org.jenkins-ci.plugins - git - 2.4.4 - true - - - - org.jenkins-ci.plugins - token-macro - 1.12 - true - - - - org.jenkins-ci.plugins - mailer - 1.16 - - - - org.jenkins-ci.plugins - jenkins-multijob-plugin - 1.15 - true - - - org.jenkins-ci.plugins - parameterized-trigger - 2.25 - true - - - - org.jenkins-ci.plugins - extended-choice-parameter - 0.34 - true - - - - org.jenkins-ci.plugins - random-string-parameter - 1.0 - true - - - - org.jenkins-ci.plugins - nodelabelparameter - 1.5.0 - true - - - - org.jenkins-ci.plugins - jquery - 1.7.2-1 - true - - - - org.jenkins-ci.plugins - subversion - 2.5 - true - - - - - com.squareup - tape - 1.2.3 - - - - - org.apache.poi - poi - 3.7 - - - - com.seitenbau.jenkins.plugins - dynamicparameter - 0.2.0 - true - - - - - - org.json - json - 20090211 - - - - org.eclipse.jetty - jetty-server - 9.2.6.v20141205 - test - - - - org.mockito - mockito-all - 1.10.19 - test - - - - org.jdom - jdom2 - 2.0.4 - - - - - com.hp.bdi - bdi-sdk - ${bdi.version} - - - - org.jenkins-ci.main - jenkins-test-harness-tools - 2.0 - test - - - - - - + + + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.31 + + + + hp-application-automation-tools-plugin + ${revision}${changelist} + hpi + OpenText Application Automation Tools + The plugin integrates Jenkins with the following OpenText products - Service Virtualization, + LoadRunner, LoadRunner Enterprise, Unified Functional Testing, QuickTest Professional, Service Test, Unified Functional Testing Mobile, + Application Lifecycle Management and Application Lifecycle Management Octane. + + https://github.com/jenkinsci/hpe-application-automation-tools-plugin/blob/latest/doc/README.md + + + + MIT License + https://opensource.org/licenses/MIT + repo + + + + + 23.4 + -SNAPSHOT + jenkinsci/${project.artifactId} + 1 + C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe + Release + 2.375.1 + false + 8 + 2.55 + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/releases + + + maven.jenkins-ci.org + https://repo.jenkins-ci.org/snapshots + + + + + scm:git:https://github.com/${gitHubRepo}.git + scm:git:git@github.com:${gitHubRepo}.git + https://github.com/${gitHubRepo} + ${scmTag} + + + + JIRA + + https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20component%20%3D%20hp-application-automation-tools-plugin + + + + + OpenText + https://www.opentext.com/ + + + + + PTofan + Tofan Paul-Adrian + paul-adrian.tofan@microfocus.com + + Global Owner + + + + radislavB + Radislav Berkovich + radislav.berkovich@microfocus.com + + ALM Octane + + + + Rlu + Roy Lu + li.lu@microfocus.com + + ALM Lab management + + + + pavelchuchma + Pavel Chuchma + pavel.chuchma@microfocus.com + + Service Virtualization + + + + rolandomihaivlad + Vlad, Rolando-Mihai + rolando-mihai.vlad@microfocus.com + + LoadRunner + + + + tamasflorin + Tamas, Ionut Florin + ionut-florin.tamas@hpe.com + + UFT + + + + danieldanan + Daniel Danan + daniel.danan@microfocus.com + + LoadRunner Enterprise + + + + janezhang + Zhang, Xiao-Jing + xiao-jing.zhang2@microfocus.com + + UFT Mobile + + + + gullerya + Yuri Guller + gullerya@gmail.com + MicroFocus - ALM Octane + + + gront + Daniel Gront + daniel.gront@microfocus.com + + Global Owner (retired) + + + + YafimK + Fima (Yafim) Kazak + + Global owner and LoadRunner Dev (retired) + + + + paul-murray-mf + Paul Murray + + ALM Octane Starteam support + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + exec-maven-plugin + [1.2.1,) + + java + exec + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + com.github.spotbugs + spotbugs-maven-plugin + + + none + + + + true + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + none + + + + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.4.0 + + ${msbuild.exe} + ${basedir}/HpToolsLauncher + ${maven.exec.skip} + + + + InstallPlugin - "${project.artifactId}" + install + + exec + + + + true + java + + -jar + + ${env.JENKINS_HOME}war\WEB-INF\jenkins-cli.jar + -s + http://localhost:8080 + install-plugin + ${project.build.directory}\${project.build.finalName}.${project.packaging} + + -name + "${project.artifactId}" + + -restart + + password-file ${id_rsa_file} + + + + + clean HPToolsLauncher + clean + + exec + + + + /t:Clean + /p:Configuration=${msbuild.configuration} + + + + + creating HPToolsLauncher + generate-resources + + exec + + + + /t:Rebuild + /p:Configuration=${msbuild.configuration} + + + + + + + + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + + + io.jenkins.tools.bom + bom-2.375.x + 2198.v39c76fc308ca + pom + import + + + + + + + org.jenkins-ci.plugins + apache-httpcomponents-client-4-api + + + com.jayway.jsonpath + json-path + 2.7.0 + + + + org.ow2.asm + asm + + + + org.slf4j + slf4j-api + + + + org.slf4j + slf4j-jdk14 + + + + + + org.jenkins-ci.plugins.workflow + workflow-step-api + + + org.jenkins-ci.plugins.workflow + workflow-api + + + org.jenkins-ci.plugins.workflow + workflow-support + + + org.jenkins-ci.plugins.workflow + workflow-cps + + + org.jenkins-ci.plugins.workflow + workflow-job + + + org.jenkins-ci.plugins.workflow + workflow-multibranch + + + org.jenkins-ci.plugins.workflow + workflow-scm-step + + + org.jenkins-ci.plugins + pipeline-build-step + + + org.jenkins-ci.plugins + pipeline-input-step + + + org.jenkinsci.plugins + pipeline-model-definition + true + + + org.jenkins-ci.plugins + structs + + + org.jenkins-ci.plugins + scm-api + + + org.jenkins-ci.plugins + script-security + test + + + + + + org.jenkins-ci + symbol-annotation + 1.4 + + + org.jenkins-ci.plugins + credentials + + + com.microfocus.sv + SVConfigurator + 5.8 + + + + commons-io + commons-io + + + + commons-codec + commons-codec + + + + org.slf4j + slf4j-api + + + + org.slf4j + slf4j-jdk14 + + + + + org.jenkins-ci.plugins + junit + + + + + + + integrations-sdk + com.hpe.adm.octane.ciplugins + 2.24.1.2 + + + + + org.jenkins-ci.plugins + parameterized-trigger + 2.44 + true + + + org.jenkins-ci.plugins + conditional-buildstep + 1.4.1 + true + + + maven-plugin + org.jenkins-ci.main + 3.15.1 + + + matrix-project + org.jenkins-ci.plugins + + + jenkins-multijob-plugin + org.jenkins-ci.plugins + 1.30 + true + + + + + git + org.jenkins-ci.plugins + true + + + org.jenkins-ci.plugins + subversion + 2.15.4 + true + + + + + extended-choice-parameter + org.jenkins-ci.plugins + 346.vd87693c5a_86c + true + + + random-string-parameter + org.jenkins-ci.plugins + 1.0 + true + + + nodelabelparameter + org.jenkins-ci.plugins + 1.10.3.1 + true + + + + + token-macro + org.jenkins-ci.plugins + 267.vcdaea6462991 + true + + + org.jenkins-ci.plugins + jquery + 1.12.4-1 + true + + + org.jenkins-ci.plugins + mailer + true + + + + + sonar + org.jenkins-ci.plugins + 2.14 + true + + + + com.microfocus.adm.performancecenter + plugins-common + 1.1.11 + + + com.fasterxml.jackson.core + jackson-databind + + + + + org.jenkins-ci.plugins + jackson2-api + 2.13.2.20220328-273.v11d70a_b_a_1a_52 + + + io.jenkins.plugins + snakeyaml-api + 1.30.1 + + + + + org.mockito + mockito-core + test + + + org.jenkins-ci.main + jenkins-test-harness-tools + 2.2 + test + + + io.jenkins.plugins + javax-activation-api + 1.2.0-3 + + + + io.jenkins.plugins + jaxb + 2.3.6-1 + + + + + + + diff --git a/readme.md b/readme.md index c2ff0335c8..21901d31d9 100644 --- a/readme.md +++ b/readme.md @@ -1,21 +1,30 @@ -![HPE LOGO](https://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Hewlett_Packard_Enterprise_logo.svg/200px-Hewlett_Packard_Enterprise_logo.svg.png) +![OpenText Logo](https://upload.wikimedia.org/wikipedia/commons/1/1b/OpenText_logo.svg) +# OpenText automation plugin for Jenkins CI -# HPE automation plugin for Jenkins CI -##### The plugin provides the ability to run HPE products with Jenkins during builds. +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8ec4415bffe94fda8ae40415388c063e)](https://www.codacy.com/app/HPEbot/hp-application-automation-tools-plugin?utm_source=github.com&utm_medium=referral&utm_content=hpsa/hp-application-automation-tools-plugin&utm_campaign=badger) -## Relevent links -- **Download the most recent LTS version of the plugin** at [offical plugin Wiki page](https://wiki.jenkins-ci.org/display/JENKINS/HP+Application+Automation+Tools) -- **Check the open issues (and add new issues)** at [Jenkins plugin jira](https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20component%20%3D%20hp-application-automation-tools-plugin) -- **View the plugin’s usage statistics** at [Jenkins.io plugin stats](http://stats.jenkins.io/plugin-installation-trend/hp-application-automation-tools-plugin.stats.json). +Project status: +[![Build status](https://ci.appveyor.com/api/projects/status/gqd0x8ov1ebqjjcu?svg=true)](https://ci.appveyor.com/project/HPEbot/hp-application-automation-tools-plugin) + +Latest release branch status: +[![Build status](https://ci.appveyor.com/api/projects/status/gqd0x8ov1ebqjjcu/branch/latest?svg=true)](https://ci.appveyor.com/project/HPEbot/hp-application-automation-tools-plugin/branch/latest) + + +##### The plugin provides the ability to run OpenText products with Jenkins during builds. + +## Relevant links +- **Download the most recent LTS version of the plugin** at [Official plugin Wiki page](https://wiki.jenkins.io/display/JENKINS/Micro+Focus+Application+Automation+Tools) +- **Check the open issues (and add new issues)** at [Jenkins plugin Jira](https://issues.jenkins-ci.org/issues/?jql=project%20%3D%20JENKINS%20AND%20component%20%3D%20hp-application-automation-tools-plugin) +- **View the plugin’s usage statistics** at [Jenkins.io plugin statistics](http://stats.jenkins.io/pluginversions/hp-application-automation-tools-plugin.html) ## Development & release timeline -####LTS release branch +#### LTS release branch - Once in 3 to 4 months, we will release an LTS version. - After a rigid QA cycle, the version will be released to the main Jenkins update center. - Each release will have feature freeze and code freeze dates that will be published at our Jira. After this dates, We will accept only fixes to issues discovered during the QA to the current release. -####Current release branches -- Each pull request merge that will pass module owner QA cycle will trigger a stable release to Jenkins exprimental update center. +#### Current release branches +- Each pull request merge that will pass module owner QA cycle will trigger a stable release to Jenkins experimental update center. - Additional releases handled by the standard pull request process followed by a basic QA cycle of the related module. - Release to the Jenkins experimental update center (More information below). @@ -39,9 +48,9 @@ #### Guidelines - Document your code – it enables others to continue the great work you did on the code and update it. -- SonarLint your code – we use sonarQube with its basic built-in rule set. In the future, we will provide direct online access to test with a custom rule set. +- SonarLint your code – we use SonarQube with its basic built-in rule set. In the future, we will provide direct online access to test with a custom rule set. -###Feel free to contact us on any question related to contributions - hpsauth-[at]-gmail-dot-com +### Feel free to contact us on any question related to contributions - hpsauth-[at]-gmail-dot-com diff --git a/sonar-project.properties b/sonar-project.properties index 136fd1b003..86846b8273 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,38 @@ -sonar.projectKey=org.jenkins-ci.plugins:hp-application-automation-tools-plugin -sonar.projectVersion=5.0.1-beta-SNAPSHOT -sonar.projectName=hp application automation tools plugin +# +# 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. +# ___________________________________________________________________ +# + +sonar.projectKey=org.jenkins-ci.plugins:hpe-application-automation-tools-plugin +sonar.projectVersion=5.2.0.1-beta-SNAPSHOT +sonar.projectName=hpe application automation tools plugin # Set modules IDs sonar.modules=module1,HpToolsLauncher,LRAnalysisLauncher,HpToolsAborter @@ -19,7 +51,7 @@ module1.sonar.sources=src\\main\\java module1.sonar.projectName=JenkinsPlugin module1.sonar.tests=src\\test\\java module1.sonar.language=java -module1.sonar.java.source=1.7 +module1.sonar.java.source=1.8 # Module 2 CS - HpToolsLauncher HpToolsLauncher.sonar.sources=.\\ diff --git a/src/main/java/com/hp/application/automation/tools/AlmToolsUtils.java b/src/main/java/com/hp/application/automation/tools/AlmToolsUtils.java deleted file mode 100644 index 3b74a6ff3d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/AlmToolsUtils.java +++ /dev/null @@ -1,110 +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. - -package com.hp.application.automation.tools; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.BuildListener; -import hudson.model.Hudson; -import hudson.model.Result; -import hudson.model.AbstractBuild; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.util.ArgumentListBuilder; -import jenkins.model.Jenkins; - -import java.io.IOException; -import java.io.PrintStream; -import java.net.URL; - -@SuppressWarnings("squid:S1160") -public class AlmToolsUtils { - - - private AlmToolsUtils() { - } - - public static void runOnBuildEnv( - Run build, - Launcher launcher, - TaskListener listener, - FilePath file, - String paramFileName) throws IOException, InterruptedException { - - ArgumentListBuilder args = new ArgumentListBuilder(); - PrintStream out = listener.getLogger(); - - // Use script to run the cmdLine and get the console output - args.add(file); - args.add("-paramfile"); - args.add(paramFileName); - - // Run the script on node - // Execution result should be 0 - int returnCode = launcher.launch().cmds(args).stdout(out).pwd(file.getParent()).join(); - - if (returnCode != 0) { - if (returnCode == -1) { - build.setResult(Result.FAILURE); - } else if (returnCode == -2) { - build.setResult(Result.UNSTABLE); - } else if (returnCode == -3) { - build.setResult(Result.ABORTED); - } - } - } - - public static void runHpToolsAborterOnBuildEnv( - AbstractBuild build, - Launcher launcher, - BuildListener listener, - String paramFileName) throws IOException, InterruptedException { - - runHpToolsAborterOnBuildEnv(build, launcher, listener, paramFileName, build.getWorkspace()); - } - - @SuppressWarnings("squid:S2259") - public static void runHpToolsAborterOnBuildEnv( - Run build, - Launcher launcher, - TaskListener listener, - String paramFileName, FilePath runWorkspace) throws IOException, InterruptedException { - - ArgumentListBuilder args = new ArgumentListBuilder(); - PrintStream out = listener.getLogger(); - - String hpToolsAborter_exe = "HpToolsAborter.exe"; - - URL hpToolsAborterUrl = Jenkins.getInstance().pluginManager.uberClassLoader.getResource("HpToolsAborter.exe"); - FilePath hpToolsAborterFile = runWorkspace.child(hpToolsAborter_exe); - - args.add(hpToolsAborterFile); - args.add(paramFileName); - - hpToolsAborterFile.copyFrom(hpToolsAborterUrl); - - int returnCode = launcher.launch().cmds(args).stdout(out).pwd(hpToolsAborterFile.getParent()).join(); - - try { - hpToolsAborterFile.delete(); - } catch (Exception e) { - listener.error("failed copying HpToolsAborter" + e); - } - - - if (returnCode != 0) { - if (returnCode == 1) { - build.setResult(Result.FAILURE); - } else if (returnCode == 2) { - build.setResult(Result.UNSTABLE); - } else if (returnCode == 3) { - build.setResult(Result.ABORTED); - } - } - } - - -} diff --git a/src/main/java/com/hp/application/automation/tools/EncryptionUtils.java b/src/main/java/com/hp/application/automation/tools/EncryptionUtils.java deleted file mode 100644 index 07e9c8efdd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/EncryptionUtils.java +++ /dev/null @@ -1,56 +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. - -package com.hp.application.automation.tools; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; - -public class EncryptionUtils { - - static String _secretkey = "EncriptionPass4Java"; - - public static String Decrypt(String text, String key) throws Exception { - - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - byte[] keyBytes = new byte[16]; - byte[] b = key.getBytes("UTF-8"); - int len = b.length; - if (len > keyBytes.length) - len = keyBytes.length; - System.arraycopy(b, 0, keyBytes, 0, len); - SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); - IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); - byte[] results = cipher.doFinal(Base64.decodeBase64(text)); - - return new String(results, "UTF-8"); - } - - public static String Encrypt(String text, String key) throws Exception { - - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - byte[] keyBytes = new byte[16]; - byte[] b = key.getBytes("UTF-8"); - int len = b.length; - if (len > keyBytes.length) - len = keyBytes.length; - System.arraycopy(b, 0, keyBytes, 0, len); - SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); - IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); - byte[] results = cipher.doFinal(text.getBytes("UTF-8")); - - return Base64.encodeBase64String(results); - } - - public static String getSecretKey() { - - return _secretkey; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/common/ALMRESTVersionUtils.java b/src/main/java/com/hp/application/automation/tools/common/ALMRESTVersionUtils.java deleted file mode 100644 index 4fa63def89..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/ALMRESTVersionUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hp.application.automation.tools.common; - -import com.hp.application.automation.tools.model.ALMVersion; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import java.io.ByteArrayInputStream; - -/** - * @author Effi Bar-She'an - */ -public class ALMRESTVersionUtils { - - public static ALMVersion toModel(byte[] xml) { - - ALMVersion ret = null; - try { - JAXBContext context = JAXBContext.newInstance(ALMVersion.class); - Unmarshaller unMarshaller = context.createUnmarshaller(); - ret = (ALMVersion) unMarshaller.unmarshal(new ByteArrayInputStream(xml)); - } catch (Exception e) { - throw new SSEException("Failed to convert XML to ALMVersion", e); - } - - return ret; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/common/Func.java b/src/main/java/com/hp/application/automation/tools/common/Func.java deleted file mode 100644 index 3b45f40d36..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/Func.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.hp.application.automation.tools.common; - -public interface Func { - - public TResult execute(); -} diff --git a/src/main/java/com/hp/application/automation/tools/common/Pair.java b/src/main/java/com/hp/application/automation/tools/common/Pair.java deleted file mode 100644 index 9004671964..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/Pair.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hp.application.automation.tools.common; - -public class Pair { - - private final TFirst _first; - private final TSecond _second; - - public Pair(TFirst first, TSecond second) { - - _first = first; - _second = second; - } - - public TFirst getFirst() { - - return _first; - } - - public TSecond getSecond() { - - return _second; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/common/PcException.java b/src/main/java/com/hp/application/automation/tools/common/PcException.java deleted file mode 100644 index 61c636be01..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/PcException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.hp.application.automation.tools.common; - -public class PcException extends Exception { - - private static final long serialVersionUID = -4036530091360617367L; - - public PcException(String message) { - - super(message); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/common/RuntimeUtils.java b/src/main/java/com/hp/application/automation/tools/common/RuntimeUtils.java deleted file mode 100644 index 924cc0a69d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/RuntimeUtils.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.hp.application.automation.tools.common; - -public class RuntimeUtils { - - @SuppressWarnings("unchecked") - public static T cast(Object obj) { - - return (T) obj; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/common/SSEException.java b/src/main/java/com/hp/application/automation/tools/common/SSEException.java deleted file mode 100644 index bc7295dba0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/common/SSEException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.common; - -public class SSEException extends RuntimeException { - - private static final long serialVersionUID = -5386355008323770858L; - - public SSEException(Throwable cause) { - - super(cause); - } - - public SSEException(String message) { - - super(message); - } - - public SSEException(String message, Throwable cause) { - - super(message, cause); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/mc/Constants.java b/src/main/java/com/hp/application/automation/tools/mc/Constants.java deleted file mode 100644 index e4fe779185..0000000000 --- a/src/main/java/com/hp/application/automation/tools/mc/Constants.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hp.application.automation.tools.mc; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 5/13/16 - * Time: 2:07 PM - * To change this template use File | Settings | File Templates. - */ -public class Constants { - public final static String BOUNDARYSTR = "randomstring"; - public final static String DATA = "data"; - public final static String APP_UPLOAD = "/rest/apps/upload"; - public final static String CONTENT_TYPE_DOWNLOAD_VALUE = "multipart/form-data; boundary=----"; - public final static String FILENAME = "filename"; - public static final String LOGIN_SECRET = "x-hp4msecret"; - public static final String SPLIT_COMMA = ";"; - public static final String JSESSIONID = "JSESSIONID"; - public static final String ACCEPT = "Accept"; - public static final String CONTENT_TYPE = "Content-Type"; - public static final String COOKIE = "Cookie"; - public static final String SET_COOKIE = "Set-Cookie"; - public static final String EQUAL = "="; - public static final String LOGIN_URL = "/rest/client/login"; - public static final String CREATE_JOB_URL = "/rest/job/createTempJob"; - public static final String GET_JOB_UEL = "/rest/job/"; - public final static String ICON = "icon"; - public final static String JESEEIONEQ = "JSESSIONID="; -} diff --git a/src/main/java/com/hp/application/automation/tools/mc/HttpResponse.java b/src/main/java/com/hp/application/automation/tools/mc/HttpResponse.java deleted file mode 100644 index 468fcb075d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/mc/HttpResponse.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.hp.application.automation.tools.mc; - -import net.minidev.json.JSONObject; - -import java.util.List; -import java.util.Map; - -public class HttpResponse { - - private Map> headers; - private JSONObject jsonObject; - - public HttpResponse() { - - } - - public HttpResponse(Map> headers, JSONObject jsonObject) { - this.headers = headers; - this.jsonObject = jsonObject; - } - - public void setHeaders(Map> headers) { - this.headers = headers; - } - - public void setJsonObject(JSONObject jsonObject) { - this.jsonObject = jsonObject; - } - - public Map> getHeaders() { - return headers; - } - - public JSONObject getJsonObject() { - return jsonObject; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/mc/HttpUtils.java b/src/main/java/com/hp/application/automation/tools/mc/HttpUtils.java deleted file mode 100644 index 213e035a1e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/mc/HttpUtils.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.hp.application.automation.tools.mc; - -import net.minidev.json.JSONObject; -import net.minidev.json.JSONValue; - -import java.io.*; -import java.net.*; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class HttpUtils { - - public static final String POST = "POST"; - public static final String GET = "GET"; - - private HttpUtils() { - - } - - public static HttpResponse post(ProxyInfo proxyInfo, String url, Map headers, byte[] data) { - - HttpResponse response = null; - - try { - response = doHttp(proxyInfo, POST, url, null, headers, data); - } catch (Exception e) { - e.printStackTrace(); - } - return response; - } - - public static HttpResponse get(ProxyInfo proxyInfo, String url, Map headers, String queryString) { - - HttpResponse response = null; - try { - response = doHttp(proxyInfo, GET, url, queryString, headers, null); - } catch (Exception e) { - e.printStackTrace(); - } - return response; - } - - - private static HttpResponse doHttp(ProxyInfo proxyInfo, String requestMethod, String connectionUrl, String queryString, Map headers, byte[] data) throws IOException { - HttpResponse response = new HttpResponse(); - - if ((queryString != null) && !queryString.isEmpty()) { - connectionUrl += "?" + queryString; - } - - URL url = new URL(connectionUrl); - - - HttpURLConnection connection = (HttpURLConnection) openConnection(proxyInfo, url); - - connection.setRequestMethod(requestMethod); - - setConnectionHeaders(connection, headers); - - if (data != null && data.length > 0) { - connection.setDoOutput(true); - try { - OutputStream out = connection.getOutputStream(); - out.write(data); - out.flush(); - out.close(); - } catch (Throwable cause) { - cause.printStackTrace(); - } - } - - connection.connect(); - - - int responseCode = connection.getResponseCode(); - - if (responseCode == HttpURLConnection.HTTP_OK) { - InputStream inputStream = connection.getInputStream(); - JSONObject jsonObject = convertStreamToJSONObject(inputStream); - Map> headerFields = connection.getHeaderFields(); - response.setHeaders(headerFields); - response.setJsonObject(jsonObject); - } - - connection.disconnect(); - - return response; - } - - private static URLConnection openConnection(final ProxyInfo proxyInfo, URL _url) throws IOException { - - Proxy proxy = null; - - if (proxyInfo != null && proxyInfo._host != null && proxyInfo._port != null && !proxyInfo._host.isEmpty() && !proxyInfo._port.isEmpty()) { - - try { - int port = Integer.parseInt(proxyInfo._port.trim()); - proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyInfo._host, port)); - - } catch (Exception e) { - e.printStackTrace(); - } - - } - - if (proxy != null && proxyInfo._userName != null && proxyInfo._password != null && !proxyInfo._password.isEmpty() && !proxyInfo._password.isEmpty()) { - Authenticator authenticator = new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(proxyInfo._userName, proxyInfo._password.toCharArray()); //To change body of overridden methods use File | Settings | File Templates. - } - }; - - - Authenticator.setDefault(authenticator); - } - - if (proxy == null) { - return _url.openConnection(); - } - - - return _url.openConnection(proxy); - } - - - private static void setConnectionHeaders(HttpURLConnection connection, Map headers) { - - if (connection != null && headers != null && headers.size() != 0) { - Iterator> headersIterator = headers.entrySet().iterator(); - while (headersIterator.hasNext()) { - Map.Entry header = headersIterator.next(); - connection.setRequestProperty(header.getKey(), header.getValue()); - } - } - - } - - private static JSONObject convertStreamToJSONObject(InputStream inputStream) { - JSONObject obj = null; - - if (inputStream != null) { - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - StringBuffer res = new StringBuffer(); - String line; - while ((line = reader.readLine()) != null) { - res.append(line); - } - obj = (JSONObject) JSONValue.parseStrict(res.toString()); - } catch (Exception e) { - e.printStackTrace(); - } - } - return obj; - } - - - public static ProxyInfo setProxyCfg(String host, String port, String userName, String password) { - - return new ProxyInfo(host, port, userName, password); - } - - public static ProxyInfo setProxyCfg(String host, String port) { - - ProxyInfo proxyInfo = new ProxyInfo(); - - proxyInfo._host = host; - proxyInfo._port = port; - - return proxyInfo; - } - - public static ProxyInfo setProxyCfg(String address, String userName, String password) { - ProxyInfo proxyInfo = new ProxyInfo(); - - if (address != null) { - if (address.endsWith("/")) { - int end = address.lastIndexOf("/"); - address = address.substring(0, end); - } - - int index = address.lastIndexOf(':'); - if (index > 0) { - proxyInfo._host = address.substring(0, index); - proxyInfo._port = address.substring(index + 1, address.length()); - } else { - proxyInfo._host = address; - proxyInfo._port = "80"; - } - } - proxyInfo._userName = userName; - proxyInfo._password = password; - - return proxyInfo; - } - - static class ProxyInfo { - String _host; - String _port; - String _userName; - String _password; - - public ProxyInfo() { - - } - - public ProxyInfo(String host, String port, String userName, String password) { - _host = host; - _port = port; - _userName = userName; - _password = password; - } - - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/mc/JobConfigurationProxy.java b/src/main/java/com/hp/application/automation/tools/mc/JobConfigurationProxy.java deleted file mode 100644 index ab903317bb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/mc/JobConfigurationProxy.java +++ /dev/null @@ -1,409 +0,0 @@ -package com.hp.application.automation.tools.mc; - -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; -import net.minidev.json.JSONValue; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * communicate with MC servers, login to MC, upload application to MC server, create job, get job details. - */ -public class JobConfigurationProxy { - - private static JobConfigurationProxy instance = null; - - private JobConfigurationProxy() { - } - - public static JobConfigurationProxy getInstance(){ - if(instance == null){ - instance = new JobConfigurationProxy(); - } - return instance; - } - //Login to MC - public JSONObject loginToMC(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUsername, String proxyPassword) { - - JSONObject returnObject = new JSONObject(); - try { - Map headers = new HashMap(); - headers.put(Constants.ACCEPT, "application/json"); - headers.put(Constants.CONTENT_TYPE, "application/json;charset=UTF-8"); - - JSONObject sendObject = new JSONObject(); - sendObject.put("name", mcUserName); - sendObject.put("password", mcPassword); - sendObject.put("accountName", "default"); - HttpResponse response = HttpUtils.post(HttpUtils.setProxyCfg(proxyAddress, proxyUsername, proxyPassword), mcUrl + Constants.LOGIN_URL, headers, sendObject.toJSONString().getBytes()); - - if (response != null && response.getHeaders() != null) { - Map> headerFields = response.getHeaders(); - List hp4mSecretList = headerFields.get(Constants.LOGIN_SECRET); - String hp4mSecret = null; - if (hp4mSecretList != null && hp4mSecretList.size() != 0) { - hp4mSecret = hp4mSecretList.get(0); - } - List setCookieList = headerFields.get(Constants.SET_COOKIE); - String setCookie = null; - if (setCookieList != null && setCookieList.size() != 0) { - setCookie = setCookieList.get(0); - for(String str : setCookieList){ - if(str.contains(Constants.JSESSIONID) && str.startsWith(Constants.JSESSIONID)){ - setCookie = str; - break; - } - } - } - String jsessionId = getJSESSIONID(setCookie); - returnObject.put(Constants.JSESSIONID, jsessionId); - returnObject.put(Constants.LOGIN_SECRET, hp4mSecret); - returnObject.put(Constants.COOKIE, Constants.JESEEIONEQ + jsessionId); - } - - } catch (Exception e) { - e.printStackTrace(); - } - return returnObject; - } - - //upload app to MC - public JSONObject upload(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUsername, String proxyPassword, String appPath) throws Exception { - - JSONObject json = null; - String hp4mSecret = null; - String jsessionId = null; - - File appFile = new File(appPath); - - String uploadUrl = mcUrl + Constants.APP_UPLOAD; - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - StringBuffer content = new StringBuffer(); - content.append("\r\n").append("------").append(Constants.BOUNDARYSTR).append("\r\n"); - content.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + appFile.getName() + "\"\r\n"); - content.append("Content-Type: application/octet-stream\r\n\r\n"); - - outputStream.write(content.toString().getBytes()); - - FileInputStream in = new FileInputStream(appFile); - byte[] b = new byte[1024]; - int i = 0; - while ((i = in.read(b)) != -1) { - outputStream.write(b, 0, i); - } - in.close(); - - outputStream.write(("\r\n------" + Constants.BOUNDARYSTR + "--\r\n").getBytes()); - - byte[] bytes = outputStream.toByteArray(); - - outputStream.close(); - - JSONObject loginJson = loginToMC(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUsername, proxyPassword); - - if (loginJson != null) { - hp4mSecret = (String) loginJson.get(Constants.LOGIN_SECRET); - jsessionId = (String) loginJson.get(Constants.JSESSIONID); - } - Map headers = new HashMap(); - headers.put(Constants.LOGIN_SECRET, hp4mSecret); - headers.put(Constants.COOKIE, Constants.JESEEIONEQ + jsessionId); - headers.put(Constants.CONTENT_TYPE, Constants.CONTENT_TYPE_DOWNLOAD_VALUE + Constants.BOUNDARYSTR); - headers.put(Constants.FILENAME, appFile.getName()); - - HttpUtils.ProxyInfo proxyInfo = HttpUtils.setProxyCfg(proxyAddress, proxyUsername, proxyPassword); - HttpResponse response = HttpUtils.post(proxyInfo, uploadUrl, headers, bytes); - - if (response != null && response.getJsonObject() != null) { - json = response.getJsonObject(); - } - return json; - } - - //create one temp job - public String createTempJob(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUserName, String proxyPassword) { - JSONObject job = null; - String jobId = null; - String hp4mSecret = null; - String jsessionId = null; - - String loginJson = loginToMC(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUserName, proxyPassword).toJSONString(); - try { - if (loginJson != null) { - JSONObject jsonObject = (JSONObject) JSONValue.parseStrict(loginJson); - hp4mSecret = (String) jsonObject.get(Constants.LOGIN_SECRET); - jsessionId = (String) jsonObject.get(Constants.JSESSIONID); - } - } catch (Exception e) { - e.printStackTrace(); - } - - boolean isValid = argumentsCheck(hp4mSecret, jsessionId); - - if (isValid) { - try { - Map headers = new HashMap(); - headers.put(Constants.LOGIN_SECRET, hp4mSecret); - headers.put(Constants.COOKIE, Constants.JESEEIONEQ + jsessionId); - HttpResponse response = HttpUtils.get(HttpUtils.setProxyCfg(proxyAddress,proxyUserName,proxyPassword), mcUrl + Constants.CREATE_JOB_URL, headers, null); - - if (response != null && response.getJsonObject() != null) { - job = response.getJsonObject(); - if(job != null && job.get("data") != null){ - JSONObject data = (JSONObject)job.get("data"); - jobId = data.getAsString("id"); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return jobId; - } - - //get one job by id - public JSONObject getJobById(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUsername, String proxyPassword, String jobUUID) { - JSONObject jobJsonObject = null; - String hp4mSecret = null; - String jsessionId = null; - - String loginJson = loginToMC(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUsername, proxyPassword).toJSONString(); - try { - if (loginJson != null) { - JSONObject jsonObject = (JSONObject) JSONValue.parseStrict(loginJson); - hp4mSecret = (String) jsonObject.get(Constants.LOGIN_SECRET); - jsessionId = (String) jsonObject.get(Constants.JSESSIONID); - } - } catch (Exception e) { - e.printStackTrace(); - } - - boolean b = argumentsCheck(jobUUID, hp4mSecret, jsessionId); - - if (b) { - try { - Map headers = new HashMap(); - headers.put(Constants.LOGIN_SECRET, hp4mSecret); - headers.put(Constants.COOKIE, Constants.JESEEIONEQ + jsessionId); - HttpResponse response = HttpUtils.get(HttpUtils.setProxyCfg(proxyAddress, proxyUsername, proxyPassword), mcUrl + Constants.GET_JOB_UEL + jobUUID, headers, null); - - if (response != null && response.getJsonObject() != null) { - jobJsonObject = response.getJsonObject(); - } - if(jobJsonObject != null){ - jobJsonObject = (JSONObject)jobJsonObject.get(Constants.DATA); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return removeIcon(jobJsonObject); - } - - //parse one job.and get the data we want - public JSONObject getJobJSONData(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUserName, String proxyPassword, String jobUUID) { - JSONObject jobJSON = getJobById(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUserName, proxyPassword, jobUUID); - - JSONObject returnJSON = new JSONObject(); - - //Device Capabilities - if (jobJSON != null) { - JSONObject returnDeviceCapabilityJSON = new JSONObject(); - - JSONObject detailJSON = (JSONObject) jobJSON.get("capableDeviceFilterDetails"); - if (detailJSON != null) { - String osType = (String) detailJSON.get("platformName"); - String osVersion = (String) detailJSON.get("platformVersion"); - String manufacturerAndModel = (String) detailJSON.get("deviceName"); - String targetLab = (String) detailJSON.get("source"); - - returnDeviceCapabilityJSON.put("OS", osType + osVersion); - returnDeviceCapabilityJSON.put("manufacturerAndModel", manufacturerAndModel); - returnDeviceCapabilityJSON.put("targetLab", targetLab); - } - - JSONObject returnDeviceJSON = new JSONObject(); - //specific device - JSONArray devices = (JSONArray) jobJSON.get("devices"); - - if (devices != null) { - JSONObject deviceJSON = (JSONObject) devices.get(0); - if (deviceJSON != null) { - String deviceID = deviceJSON.getAsString("deviceID"); - String osType = deviceJSON.getAsString("osType"); - String osVersion = deviceJSON.getAsString("osVersion"); - String manufacturerAndModel = deviceJSON.getAsString("model"); - - returnDeviceJSON.put("deviceId", deviceID); - returnDeviceJSON.put("OS", osType + " " + osVersion); - returnDeviceJSON.put("manufacturerAndModel", manufacturerAndModel); - } - } - //Applications under test - JSONArray returnExtraJSONArray = new JSONArray(); - StringBuilder extraApps = new StringBuilder(); - JSONArray extraAppJSONArray = (JSONArray) jobJSON.get("extraApps"); - - if (extraAppJSONArray != null) { - Iterator iterator = extraAppJSONArray.iterator(); - - while (iterator.hasNext()) { - - JSONObject extraAPPJSON = new JSONObject(); - - JSONObject nextJSONObject = (JSONObject) iterator.next(); - String extraAppName = (String) nextJSONObject.get("name"); - Boolean instrumented = (Boolean) nextJSONObject.get("instrumented"); - - extraAPPJSON.put("extraAppName", extraAppName); - extraAPPJSON.put("instrumented", instrumented ? "Packaged" : "Not Packaged"); - if(extraApps.length() > 1){ - extraApps.append(";\n"); - } - extraApps.append(extraAppName).append("\t\t").append(instrumented ? "Packaged" : "Not Packaged"); - - returnExtraJSONArray.add(extraAPPJSON); - } - } - //Test Definitions - JSONObject returnDefinitionJSON = new JSONObject(); - - JSONObject applicationJSON = (JSONObject) jobJSON.get("application"); - - if (applicationJSON != null) { - String launchApplicationName = (String) applicationJSON.get("name"); - Boolean instrumented = (Boolean) applicationJSON.get("instrumented"); - - returnDefinitionJSON.put("launchApplicationName", launchApplicationName); - returnDefinitionJSON.put("instrumented", instrumented ? "Packaged" : "Not Packaged"); - } - - //Device metrics,Install Restart - String headerStr = (String) jobJSON.get("header"); - JSONObject headerJSON = parseJSONString(headerStr); - if (headerJSON != null) { - JSONObject configurationJSONObject = (JSONObject) headerJSON.get("configuration"); - Boolean restart = (Boolean) configurationJSONObject.get("restartApp"); - Boolean install = (Boolean) configurationJSONObject.get("installAppBeforeExecution"); - Boolean uninstall = (Boolean) configurationJSONObject.get("deleteAppAfterExecution"); - - StringBuffer sb = new StringBuffer(""); - - if (restart) { - sb.append("Restart;"); - } - if (install) { - sb.append("Install;"); - } - if (uninstall) { - sb.append("Uninstall;"); - } - JSONObject collectJSON = (JSONObject) headerJSON.get("collect"); - StringBuffer deviceMetricsSb = new StringBuffer(""); - //device metrics - if (collectJSON != null) { - Boolean useCPU = (Boolean) collectJSON.get("cpu"); - Boolean useMemory = (Boolean) collectJSON.get("memory"); - Boolean useLogs = (Boolean) collectJSON.get("logs"); - Boolean useScreenshot = (Boolean) collectJSON.get("screenshot"); - Boolean useFreeMemory = (Boolean) collectJSON.get("freeMemory"); - if (useCPU) { - deviceMetricsSb.append("CPU;"); - } - if (useMemory) { - deviceMetricsSb.append("Memory;"); - } - if (useLogs) { - deviceMetricsSb.append("Log;"); - } - if (useScreenshot) { - deviceMetricsSb.append("Screenshot;"); - } - if (useFreeMemory) { - deviceMetricsSb.append("FreeMomery;"); - } - } - returnDefinitionJSON.put("autActions", removeLastSemicolon(sb)); - returnDefinitionJSON.put("deviceMetrics", removeLastSemicolon(deviceMetricsSb)); - } - returnJSON.put("deviceCapability", returnDeviceCapabilityJSON); - returnJSON.put("extraApps", extraApps.toString()); - returnJSON.put("extraApps2", returnExtraJSONArray); - returnJSON.put("definitions", returnDefinitionJSON); - returnJSON.put("jobUUID", jobUUID); - returnJSON.put("deviceJSON", returnDeviceJSON); - } - return returnJSON; - } - - private JSONObject parseJSONString(String jsonString) { - JSONObject jsonObject = null; - try { - jsonObject = (JSONObject) JSONValue.parseStrict(jsonString); - } catch (Exception e) { - e.printStackTrace(); - } - return jsonObject; - } - - private String getJSESSIONID(String setCookie) { - String id = null; - String[] cookies = setCookie.split(Constants.SPLIT_COMMA); - for (int i = 0; i < cookies.length; i++) { - if (cookies[i].contains(Constants.JSESSIONID)) { - int index = cookies[i].indexOf(Constants.EQUAL); - id = cookies[i].substring(index + 1); - break; - } - } - return id; - } - - private boolean argumentsCheck(String... args) { - - for (String arg : args) { - if (arg == null || arg == "" || arg.length() == 0) { - return false; - } - } - return true; - } - - private String removeLastSemicolon(StringBuffer sb) { - String result = sb.toString(); - int indexOf = result.lastIndexOf(";"); - if(indexOf > 0){ - result = result.substring(0, indexOf); - } - return result; - } - - private JSONObject removeIcon(JSONObject jobJSON){ - JSONArray extArr = null; - if (jobJSON != null) { - if (jobJSON != null) { - JSONObject applicationJSONObject = (JSONObject) jobJSON.get("application"); - if (applicationJSONObject != null) { - applicationJSONObject.remove(Constants.ICON); - } - extArr = (JSONArray) jobJSON.get("extraApps"); - if (extArr != null) { - Iterator iterator = extArr.iterator(); - while (iterator.hasNext()) { - JSONObject extAppJSONObject = (JSONObject) iterator.next(); - extAppJSONObject.remove(Constants.ICON); - } - } - } - } - return jobJSON; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/ALMVersion.java b/src/main/java/com/hp/application/automation/tools/model/ALMVersion.java deleted file mode 100644 index 685253f828..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/ALMVersion.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hp.application.automation.tools.model; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * @author Effi Bar-She'an - */ -@XmlRootElement(name = "SiteVersions") -public class ALMVersion { - - @XmlElement(name = "MajorVersion") - private String _majorVersion; - @XmlElement(name = "MinorVersion") - private String _minorVersion; - - public String getMajorVersion() { - - return _majorVersion; - } - - public void setMajorVersion(String majorVersion) { - - _majorVersion = majorVersion; - } - - public String getMinorVersion() { - - return _minorVersion; - } - - public void setMinorVersion(String minorVersion) { - - _minorVersion = minorVersion; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentModelResolver.java b/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentModelResolver.java deleted file mode 100644 index b50e79db80..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentModelResolver.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.hp.application.automation.tools.model; - -import hudson.Util; -import hudson.util.VariableResolver; - -/** - * Created by barush on 09/11/2014. - */ -public class AUTEnvironmentModelResolver { - - public static AUTEnvironmentResolvedModel resolveModel( - AutEnvironmentModel autEnvironmentModel, - VariableResolver buildResolver) { - - String resolvedUserName = - Util.replaceMacro(autEnvironmentModel.getAlmUserName(), buildResolver); - String resolvedAlmDomain = - Util.replaceMacro(autEnvironmentModel.getAlmDomain(), buildResolver); - String resolvedAlmProject = - Util.replaceMacro(autEnvironmentModel.getAlmProject(), buildResolver); - String resolvedAutEnvironmentId = - Util.replaceMacro(autEnvironmentModel.getAutEnvironmentId(), buildResolver); - String resolvedAutEnvConfId = - Util.replaceMacro(autEnvironmentModel.getExistingAutEnvConfId(), buildResolver); - String resolvedAutEnvConfName = - Util.replaceMacro(autEnvironmentModel.getNewAutEnvConfName(), buildResolver); - String resolvedJsonPath = - Util.replaceMacro(autEnvironmentModel.getPathToJsonFile(), buildResolver); - - return new AUTEnvironmentResolvedModel( - autEnvironmentModel.getAlmServerName(), - autEnvironmentModel.getAlmServerUrl(), - resolvedUserName, - autEnvironmentModel.getAlmPassword(), - resolvedAlmDomain, - resolvedAlmProject, - resolvedAutEnvironmentId, - autEnvironmentModel.isUseExistingAutEnvConf(), - resolvedAutEnvConfId, - autEnvironmentModel.isCreateNewAutEnvConf(), - resolvedAutEnvConfName, - autEnvironmentModel.getAutEnvironmentParameters(), - resolvedJsonPath, - autEnvironmentModel.getOutputParameter()); - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentResolvedModel.java b/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentResolvedModel.java deleted file mode 100644 index e05e5b9cec..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AUTEnvironmentResolvedModel.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.List; - -/** - * Created by barush - */ -public class AUTEnvironmentResolvedModel { - - private String almServerName; - private String almServerUrl; - private String almUserName; - private String almPassword; - private String almDomain; - private String almProject; - - private String autEnvironmentId; - private boolean useExistingAutEnvConf; - private String existingAutEnvConfId; - private boolean createNewAutEnvConf; - private String newAutEnvConfName; - - private List autEnvironmentParameters; - - private String pathToJsonFile; - private String outputParameter; - - public AUTEnvironmentResolvedModel( - String almServerName, - String almServerUrl, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String autEnvironmentId, - boolean useExistingAutEnvConf, - String existingAutEnvConfId, - boolean createNewAutEnvConf, - String newAutEnvConfName, - List autEnvironmentParameters, - String pathToJsonFile, - String outputParameter) { - - this.almServerName = almServerName; - this.almServerUrl = almServerUrl; - this.almUserName = almUserName; - this.almPassword = almPassword; - this.almDomain = almDomain; - this.almProject = almProject; - this.autEnvironmentId = autEnvironmentId; - this.useExistingAutEnvConf = useExistingAutEnvConf; - this.existingAutEnvConfId = existingAutEnvConfId; - this.createNewAutEnvConf = createNewAutEnvConf; - this.newAutEnvConfName = newAutEnvConfName; - this.autEnvironmentParameters = autEnvironmentParameters; - this.pathToJsonFile = pathToJsonFile; - this.outputParameter = outputParameter; - } - - public String getAlmServerName() { - return almServerName; - } - - public String getAlmServerUrl() { - return almServerUrl; - } - - public String getAlmUserName() { - return almUserName; - } - - public String getAlmPassword() { - return almPassword.toString(); - } - - public String getAlmDomain() { - return almDomain; - } - - public String getAlmProject() { - return almProject; - } - - public String getAutEnvironmentId() { - return autEnvironmentId; - } - - public boolean isUseExistingAutEnvConf() { - return useExistingAutEnvConf; - } - - public String getExistingAutEnvConfId() { - return existingAutEnvConfId; - } - - public boolean isCreateNewAutEnvConf() { - return createNewAutEnvConf; - } - - public String getNewAutEnvConfName() { - return newAutEnvConfName; - } - - public List getAutEnvironmentParameters() { - return autEnvironmentParameters; - } - - public String getPathToJsonFile() { - return pathToJsonFile; - } - - public String getOutputParameter() { - return outputParameter; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AbstractSvRunModel.java b/src/main/java/com/hp/application/automation/tools/model/AbstractSvRunModel.java deleted file mode 100644 index 2b341aa987..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AbstractSvRunModel.java +++ /dev/null @@ -1,38 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import org.apache.commons.lang.StringUtils; - -public class AbstractSvRunModel { - /** - * Name of SvServerSettingsModel instance - */ - protected final String serverName; - /** - * Force operation regardless virtual service is locked - */ - protected final boolean force; - protected final SvServiceSelectionModel serviceSelection; - - public AbstractSvRunModel(String serverName, boolean force, SvServiceSelectionModel serviceSelection) { - this.serverName = serverName; - this.force = force; - this.serviceSelection = serviceSelection; - } - - public String getServerName() { - return (StringUtils.isNotBlank(serverName)) ? serverName : null; - } - - public boolean isForce() { - return force; - } - - public SvServiceSelectionModel getServiceSelection() { - return serviceSelection; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AlmServerSettingsModel.java b/src/main/java/com/hp/application/automation/tools/model/AlmServerSettingsModel.java deleted file mode 100644 index 2837165289..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AlmServerSettingsModel.java +++ /dev/null @@ -1,52 +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. - -package com.hp.application.automation.tools.model; - -import java.util.Properties; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -public class AlmServerSettingsModel { - - private final String _almServerName; - private final String _almServerUrl; - - @DataBoundConstructor - public AlmServerSettingsModel(String almServerName, String almServerUrl) { - - _almServerName = almServerName; - _almServerUrl = almServerUrl; - } - - /** - * @return the almServerName - */ - public String getAlmServerName() { - - return _almServerName; - } - - /** - * @return the almServerUrl - */ - public String getAlmServerUrl() { - - return _almServerUrl; - } - - public Properties getProperties() { - - Properties prop = new Properties(); - if (!StringUtils.isEmpty(_almServerUrl)) { - prop.put("almServerUrl", _almServerUrl); - } else { - prop.put("almServerUrl", ""); - } - - return prop; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentModel.java b/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentModel.java deleted file mode 100644 index fbd5a8386d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentModel.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.model.Hudson; -import hudson.util.FormValidation; - -/** - * Created by barush on 21/10/2014. - */ -public class AutEnvironmentModel extends AbstractDescribableImpl { - - private final String almServerName; - private String almServerUrl; - private final String almUserName; - private final SecretContainer almPassword; - private final String almDomain; - private final String almProject; - - private final String autEnvironmentId; - private final boolean useExistingAutEnvConf; - private final String existingAutEnvConfId; - private final boolean createNewAutEnvConf; - private final String newAutEnvConfName; - - private List autEnvironmentParameters; - - private final String pathToJsonFile; - private final String outputParameter; - - @DataBoundConstructor - public AutEnvironmentModel( - String almServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String autEnvironmentId, - boolean useExistingAutEnvConf, - String existingAutEnvConfId, - boolean createNewAutEnvConf, - String newAutEnvConfName, - List autEnvironmentParameters, - String pathToJsonFile, - String outputParameter) { - - this.almServerName = almServerName; - this.almUserName = almUserName; - this.almPassword = setPassword(almPassword); - this.almDomain = almDomain; - this.almProject = almProject; - this.autEnvironmentId = autEnvironmentId; - this.useExistingAutEnvConf = useExistingAutEnvConf; - this.existingAutEnvConfId = existingAutEnvConfId; - this.createNewAutEnvConf = createNewAutEnvConf; - this.newAutEnvConfName = newAutEnvConfName; - this.autEnvironmentParameters = autEnvironmentParameters; - this.pathToJsonFile = pathToJsonFile; - this.outputParameter = outputParameter; - - } - - protected SecretContainer setPassword(String almPassword) { - - SecretContainer secretContainer = new SecretContainerImpl(); - secretContainer.initialize(almPassword); - - return secretContainer; - } - - public String getPathToJsonFile() { - return pathToJsonFile; - } - - public boolean isCreateNewAutEnvConf() { - return createNewAutEnvConf; - } - - public boolean isUseExistingAutEnvConf() { - return useExistingAutEnvConf; - } - - public String getAlmServerName() { - - return almServerName; - } - - public String getAlmServerUrl() { - - return almServerUrl; - } - - public void setAlmServerUrl(String almServerUrl) { - - this.almServerUrl = almServerUrl; - } - - public String getAlmUserName() { - - return almUserName; - } - - public String getAlmPassword() { - - return almPassword.toString(); - } - - public String getAlmDomain() { - - return almDomain; - } - - public String getAlmProject() { - - return almProject; - } - - public String getOutputParameter() { - return outputParameter; - } - - public String getAutEnvironmentId() { - return autEnvironmentId; - } - - public String getExistingAutEnvConfId() { - return existingAutEnvConfId; - } - - public String getNewAutEnvConfName() { - return newAutEnvConfName; - } - - public List getAutEnvironmentParameters() { - return autEnvironmentParameters; - } - - @Extension - public static class DescriptorImpl extends Descriptor { - - public String getDisplayName() { - return "AUT Env"; - } - - public AlmServerSettingsModel[] getAlmServers() { - - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - } - - public FormValidation doCheckAlmUserName(@QueryParameter String value) { - - return generalCheckWithError(value, "User name must be set"); - } - - public FormValidation doCheckAlmDomain(@QueryParameter String value) { - - return generalCheckWithError(value, "Domain must be set"); - } - - public FormValidation doCheckAlmProject(@QueryParameter String value) { - - return generalCheckWithError(value, "Project must be set"); - } - - public FormValidation doCheckAutEnvironmentId(@QueryParameter String value) { - - return generalCheckWithError(value, "AUT Environment ID must be set"); - } - - public FormValidation doCheckAlmPassword(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.warning("Password for ALM server is empty"); - } - - return ret; - } - - public FormValidation doCheckOutputParameter(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = - FormValidation.warning("AUT Environment Configuration ID isn't assigned to any environment variable"); - } - - return ret; - } - - private FormValidation generalCheckWithError(String value, String errorMessage) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error(errorMessage); - } - - return ret; - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentParameterModel.java b/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentParameterModel.java deleted file mode 100644 index 3fbd0d3d35..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/AutEnvironmentParameterModel.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.util.FormValidation; - -/** - * Created by barush on 21/10/2014. - */ -public class AutEnvironmentParameterModel extends - AbstractDescribableImpl { - - private final String name; - private final String value; - private final String paramType; - private final boolean shouldGetOnlyFirstValueFromJson; - private String resolvedValue; - - public static final List parametersTypes = Arrays.asList( - AutEnvironmentParameterType.USER_DEFINED.value(), - AutEnvironmentParameterType.ENVIRONMENT.value(), - AutEnvironmentParameterType.EXTERNAL.value()); - - @DataBoundConstructor - public AutEnvironmentParameterModel( - String name, - String value, - String paramType, - boolean shouldGetOnlyFirstValueFromJson) { - - this.name = name; - this.value = value; - this.paramType = paramType; - this.shouldGetOnlyFirstValueFromJson = shouldGetOnlyFirstValueFromJson; - } - - public boolean isShouldGetOnlyFirstValueFromJson() { - return shouldGetOnlyFirstValueFromJson; - } - - public String getParamType() { - return paramType; - } - - public String getValue() { - return value; - } - - public String getName() { - return name; - } - - public String getResolvedValue() { - return resolvedValue; - } - - public void setResolvedValue(String resolvedValue) { - this.resolvedValue = resolvedValue; - } - - public enum AutEnvironmentParameterType { - - UNDEFINED(""), ENVIRONMENT("Environment"), EXTERNAL("From JSON"), USER_DEFINED("Manual"); - - private String value; - - private AutEnvironmentParameterType(String value) { - - this.value = value; - } - - public String value() { - - return value; - } - - public static AutEnvironmentParameterType get(String val) { - for (AutEnvironmentParameterType parameterType : AutEnvironmentParameterType.values()) { - if (val.equals(parameterType.value())) - return parameterType; - } - return UNDEFINED; - } - } - - @Extension - public static class DescriptorImpl extends Descriptor { - - public String getDisplayName() { - return "AUT Parameter"; - } - - public List getParametersTypes() { - return AutEnvironmentParameterModel.parametersTypes; - } - - public FormValidation doCheckName(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("Parameter name must be set"); - } - - return ret; - } - - public FormValidation doCheckValue(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.warning("You didn't assign any value to this parameter"); - } - - return ret; - } - - public String getRandomName(@QueryParameter String prefix) { - return prefix + UUID.randomUUID(); - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/model/CdaDetails.java b/src/main/java/com/hp/application/automation/tools/model/CdaDetails.java deleted file mode 100644 index 3c24ef0727..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/CdaDetails.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.Arrays; -import java.util.List; - -import org.kohsuke.stapler.DataBoundConstructor; - -import com.hp.application.automation.tools.sse.common.StringUtils; - -public class CdaDetails { - - private final String _deploymentAction; - private final String _deployedEnvironmentName; - private final String _deprovisioningAction; - - private final static EnumDescription _deploymentActionUseDeployed = new EnumDescription( - "", - "Use Deployed"); - private final static EnumDescription _deploymentActionProvisionDeploy = new EnumDescription( - "Provision;Deploy", - "Provision and Deploy"); - private final static EnumDescription _deploymentActionRedeploy = new EnumDescription( - "Deploy", - "Redeploy"); - private final static List _deploymentActions = Arrays.asList( - _deploymentActionUseDeployed, - _deploymentActionProvisionDeploy, - _deploymentActionRedeploy); - - private final static EnumDescription _deprovisioningActionLeaveDeployed = new EnumDescription( - "", - "Leave environment deployed"); - private final static EnumDescription _deprovisioningActionDeprovision = new EnumDescription( - "Deprovision", - "Deprovision at end"); - private final static List _deprovisioningActions = Arrays.asList( - _deprovisioningActionLeaveDeployed, - _deprovisioningActionDeprovision); - - @DataBoundConstructor - public CdaDetails( - String deploymentAction, - String deployedEnvironmentName, - String deprovisioningAction) { - - _deploymentAction = deploymentAction; - _deployedEnvironmentName = deployedEnvironmentName; - _deprovisioningAction = deprovisioningAction; - } - - public static List getDeploymentActions() { - - return _deploymentActions; - } - - public static List getDeprovisioningActions() { - - return _deprovisioningActions; - } - - public String getTopologyAction() { - - String ret = _deploymentAction; - if (!StringUtils.isNullOrEmpty(_deprovisioningAction)) { - ret = String.format("%s;%s", ret, _deprovisioningAction); - } - - return ret; - } - - public String getDeploymentAction() { - - return _deploymentAction; - } - - public String getDeployedEnvironmentName() { - - return _deployedEnvironmentName; - } - - public String getDeprovisioningAction() { - - return _deprovisioningAction; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/EnumDescription.java b/src/main/java/com/hp/application/automation/tools/model/EnumDescription.java deleted file mode 100644 index b79e7da23e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/EnumDescription.java +++ /dev/null @@ -1,25 +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. - -package com.hp.application.automation.tools.model; - -public class EnumDescription { - - public EnumDescription(String value, String description) { - this.value = value; - this.description = description; - } - - private String description; - private String value; - - public String getDescription() { - return description; - } - - public String getValue() { - return value; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/MCServerSettingsModel.java b/src/main/java/com/hp/application/automation/tools/model/MCServerSettingsModel.java deleted file mode 100644 index 3ddd9fa5db..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/MCServerSettingsModel.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.hp.application.automation.tools.model; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -import java.util.Properties; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 10/13/15 - * Time: 11:06 AM - * To change this template use File | Settings | File Templates. - */ -public class MCServerSettingsModel { - - private final String _mcServerName; - private final String _mcServerUrl; - - @DataBoundConstructor - public MCServerSettingsModel(String mcServerName, String mcServerUrl) { - - _mcServerName = mcServerName; - _mcServerUrl = mcServerUrl; - } - - /** - * @return the mcServerName - */ - public String getMcServerName() { - - return _mcServerName; - } - - /** - * @return the mcServerUrl - */ - public String getMcServerUrl() { - - return _mcServerUrl; - } - - public Properties getProperties() { - - Properties prop = new Properties(); - if (!StringUtils.isEmpty(_mcServerUrl)) { - prop.put("MobileHostAddress", _mcServerUrl); - } else { - prop.put("MobileHostAddress", ""); - } - - return prop; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/OctaneServerSettingsModel.java b/src/main/java/com/hp/application/automation/tools/model/OctaneServerSettingsModel.java deleted file mode 100644 index a69e6e4e53..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/OctaneServerSettingsModel.java +++ /dev/null @@ -1,93 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import hudson.util.Secret; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -import java.util.Date; - -public class OctaneServerSettingsModel { - - private String identity; - private Long identityFrom; - - private String uiLocation; - private String username; - private Secret password; - private String impersonatedUser; - - // inferred from uiLocation - private String location; - private String sharedSpace; - - - public OctaneServerSettingsModel() { - - } - - @DataBoundConstructor - public OctaneServerSettingsModel(String uiLocation, String username, Secret password, String impersonatedUser) { - this.uiLocation = StringUtils.trim(uiLocation); - this.username = username; - this.password = password; - this.impersonatedUser = impersonatedUser; - } - - - public String getUiLocation() { - return uiLocation; - } - - public String getUsername() { - return username; - } - - public Secret getPassword() { - return password; - } - - public String getImpersonatedUser() { - return impersonatedUser; - } - - public String getIdentity() { - return identity; - } - - public void setIdentity(String identity) { - if (StringUtils.isEmpty(identity)) { - throw new IllegalArgumentException("Empty identity is not allowed"); - } - this.identity = identity; - this.setIdentityFrom(new Date().getTime()); - } - - public Long getIdentityFrom() { - return identityFrom; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getSharedSpace() { - return sharedSpace; - } - - public void setSharedSpace(String sharedSpace) { - this.sharedSpace = sharedSpace; - } - - public void setIdentityFrom(Long identityFrom) { - this.identityFrom = identityFrom; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/PcModel.java b/src/main/java/com/hp/application/automation/tools/model/PcModel.java deleted file mode 100644 index aca6d8cdb4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/PcModel.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.Arrays; -import java.util.List; - -import org.kohsuke.stapler.DataBoundConstructor; - -public class PcModel { - - public static final String COLLATE = "Collate Results"; - public static final String COLLATE_ANALYZE = "Collate And Analyze"; - public static final String DO_NOTHING = "Do Not Collate"; - - private final String pcServerName; - private final String almUserName; - private final SecretContainer almPassword; - private final String almDomain; - private final String almProject; - private final String testId; - private final String testInstanceId; - private final TimeslotDuration timeslotDuration; - private final PostRunAction postRunAction; - private final boolean vudsMode; - private final String description; - private final boolean addRunToTrendReport; - private final String trendReportId; - - @DataBoundConstructor - public PcModel(String pcServerName, String almUserName, String almPassword, String almDomain, String almProject, - String testId, String testInstanceId, String timeslotDurationHours, String timeslotDurationMinutes, - PostRunAction postRunAction, boolean vudsMode, String description, boolean addRunToTrendReport, String trendReportId) { - - this.pcServerName = pcServerName; - this.almUserName = almUserName; - this.almPassword = setPassword(almPassword); - this.almDomain = almDomain; - this.almProject = almProject; - this.testId = testId; - this.testInstanceId = testInstanceId; - this.timeslotDuration = new TimeslotDuration(timeslotDurationHours, timeslotDurationMinutes); - this.postRunAction = postRunAction; - this.vudsMode = vudsMode; - this.description = description; - this.addRunToTrendReport = addRunToTrendReport; - this.trendReportId = trendReportId; - } - - protected SecretContainer setPassword(String almPassword) { - - SecretContainer secretContainer = new SecretContainerImpl(); - secretContainer.initialize(almPassword); - return secretContainer; - } - - public String getPcServerName() { - - return this.pcServerName; - } - - public String getAlmUserName() { - - return this.almUserName; - } - - public SecretContainer getAlmPassword() { - - return this.almPassword; - } - - public String getAlmDomain() { - - return this.almDomain; - } - - public String getAlmProject() { - - return this.almProject; - } - - public String getTestId() { - - return this.testId; - } - - public String getTestInstanceId() { - - return this.testInstanceId; - } - - public TimeslotDuration getTimeslotDuration() { - - return this.timeslotDuration; - } - - public boolean isVudsMode() { - - return this.vudsMode; - } - - public PostRunAction getPostRunAction() { - - return this.postRunAction; - } - - public String getDescription() { - - return this.description; - } - - - - public static List getPostRunActions() { - return Arrays.asList(PostRunAction.values()); - } - - @Override - public String toString() { - - return String.format("[PCServer='%s', User='%s', %s", runParamsToString().substring(1)); - } - - public String runParamsToString() { - - String vudsModeString = (vudsMode) ? ", VUDsMode='true'" : ""; - String trendString = (addRunToTrendReport) ? String.format(", TrendReportID = '%s'",trendReportId) : ""; - - return String.format("[Domain='%s', Project='%s', TestID='%s', " + - "TestInstanceID='%s', TimeslotDuration='%s', PostRunAction='%s'%s%s]", - - almDomain, almProject, testId, testInstanceId, - timeslotDuration, postRunAction.getValue(), vudsModeString, trendString); - } - - - public String getTrendReportId() { - return trendReportId; - } - - public boolean isAddRunToTrendReport() { - return addRunToTrendReport; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/PostRunAction.java b/src/main/java/com/hp/application/automation/tools/model/PostRunAction.java deleted file mode 100644 index e1e84de1b9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/PostRunAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hp.application.automation.tools.model; - -public enum PostRunAction { - - COLLATE("Collate Results"), - COLLATE_AND_ANALYZE("Collate And Analyze"), - DO_NOTHING("Do Not Collate"); - - private String value; - - private PostRunAction(String value) { - this.value = value; - } - - public String getValue() { - return value; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/ProxySettings.java b/src/main/java/com/hp/application/automation/tools/model/ProxySettings.java deleted file mode 100644 index 1293fbbabd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/ProxySettings.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.hp.application.automation.tools.model; - -import hudson.util.Secret; -import org.kohsuke.stapler.DataBoundConstructor; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 3/30/16 - * Time: 1:37 PM - * To change this template use File | Settings | File Templates. - */ -public class ProxySettings { - private boolean fsUseAuthentication; - private String fsProxyAddress; - private String fsProxyUserName; - private Secret fsProxyPassword; - - @DataBoundConstructor - public ProxySettings(boolean fsUseAuthentication, String fsProxyAddress, String fsProxyUserName, Secret fsProxyPassword) { - this.fsUseAuthentication = fsUseAuthentication; - this.fsProxyAddress = fsProxyAddress; - this.fsProxyUserName = fsProxyUserName; - this.fsProxyPassword = fsProxyPassword; - } - - public boolean isFsUseAuthentication() { - return fsUseAuthentication; - } - - public String getFsProxyAddress() { - return fsProxyAddress; - } - - public String getFsProxyUserName() { - return fsProxyUserName; - } - - public String getFsProxyPassword() { - return fsProxyPassword.getPlainText(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/ResultsPublisherModel.java b/src/main/java/com/hp/application/automation/tools/model/ResultsPublisherModel.java deleted file mode 100644 index 757d0b90ba..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/ResultsPublisherModel.java +++ /dev/null @@ -1,45 +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. - -package com.hp.application.automation.tools.model; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.List; - -import org.kohsuke.stapler.DataBoundConstructor; - -public class ResultsPublisherModel implements Serializable { - - private static final long serialVersionUID = 1L; - - public final static EnumDescription dontArchiveResults = new EnumDescription("DONT_ARCHIVE_TEST_REPORT", "Do not archive HP test reports"); - public final static EnumDescription alwaysArchiveResults = new EnumDescription("ALWAYS_ARCHIVE_TEST_REPORT", "Always archive HP test reports"); - public final static EnumDescription ArchiveFailedTestsResults = new EnumDescription("ONLY_ARCHIVE_FAILED_TESTS_REPORT", "Archive HP test report for failed tests "); - public final static EnumDescription CreateHtmlReportResults = new EnumDescription("PUBLISH_HTML_REPORT", "Always archive and publish HP test reports (LR only)"); - public final static List archiveModes = - Arrays.asList(ArchiveFailedTestsResults, alwaysArchiveResults, - CreateHtmlReportResults, dontArchiveResults); - - private String archiveTestResultsMode; - - @DataBoundConstructor - public ResultsPublisherModel(String archiveTestResultsMode) { - - this.archiveTestResultsMode=archiveTestResultsMode; - - if (this.archiveTestResultsMode.isEmpty()){ - this.archiveTestResultsMode=dontArchiveResults.getValue(); - } - } - - public String getArchiveTestResultsMode() { - return archiveTestResultsMode; - } - -} - - - diff --git a/src/main/java/com/hp/application/automation/tools/model/RunFromAlmModel.java b/src/main/java/com/hp/application/automation/tools/model/RunFromAlmModel.java deleted file mode 100644 index e15c148940..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/RunFromAlmModel.java +++ /dev/null @@ -1,172 +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. - -package com.hp.application.automation.tools.model; - -import hudson.EnvVars; -import hudson.Util; -import hudson.util.VariableResolver; -import java.util.Arrays; -import java.util.List; -import hudson.util.Secret; -import java.util.Properties; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -public class RunFromAlmModel { - - public final static EnumDescription runModeLocal = new EnumDescription( - "RUN_LOCAL", "Run locally"); - public final static EnumDescription runModePlannedHost = new EnumDescription( - "RUN_PLANNED_HOST", "Run on planned host"); - public final static EnumDescription runModeRemote = new EnumDescription( - "RUN_REMOTE", "Run remotely"); - public final static List runModes = Arrays.asList( - runModeLocal, runModePlannedHost, runModeRemote); - public final static int DEFAULT_TIMEOUT = 36000; // 10 hrs - public final static String ALM_PASSWORD_KEY = "almPassword"; - - private String almServerName; - private String almUserName; - private Secret almPassword; - private String almDomain; - private String almProject; - private String almTestSets; - private String almRunResultsMode; - private String almTimeout; - private String almRunMode; - private String almRunHost; - - @DataBoundConstructor - public RunFromAlmModel(String almServerName, String almUserName, - String almPassword, String almDomain, String almProject, - String almTestSets, String almRunResultsMode, String almTimeout, - String almRunMode, String almRunHost) { - - this.almServerName = almServerName; - this.almUserName = almUserName; - this.almPassword = Secret.fromString(almPassword); - this.almDomain = almDomain; - this.almProject = almProject; - this.almTestSets = almTestSets; - - if (!this.almTestSets.contains("\n")) { - this.almTestSets += "\n"; - } - - this.almRunResultsMode = almRunResultsMode; - - this.almTimeout = almTimeout; - this.almRunMode = almRunMode; - - if (this.almRunMode.equals(runModeRemote.getValue())) { - this.almRunHost = almRunHost; - } else { - this.almRunHost = ""; - } - - if (almRunHost == null) { - this.almRunHost = ""; - } - } - - public String getAlmUserName() { - return almUserName; - } - - public String getAlmDomain() { - return almDomain; - } - - public String getAlmPassword() { - return almPassword.getPlainText(); - } - - public String getAlmProject() { - return almProject; - } - - public String getAlmTestSets() { - return almTestSets; - } - - public String getAlmRunResultsMode() { - return almRunResultsMode; - } - - public String getAlmTimeout() { - return almTimeout; - } - - public String getAlmRunHost() { - return almRunHost; - } - - public String getAlmRunMode() { - return almRunMode; - } - - public String getAlmServerName() { - return almServerName; - } - - public Properties getProperties(EnvVars envVars, - VariableResolver varResolver) { - return CreateProperties(envVars, varResolver); - } - - public Properties getProperties() { - return CreateProperties(null, null); - } - - private Properties CreateProperties(EnvVars envVars, - VariableResolver varResolver) { - Properties props = new Properties(); - - if (envVars == null) { - props.put("almUserName", almUserName); - props.put(ALM_PASSWORD_KEY, almPassword); - props.put("almDomain", almDomain); - props.put("almProject", almProject); - } else { - props.put("almUserName", - Util.replaceMacro(envVars.expand(almUserName), varResolver)); - props.put(ALM_PASSWORD_KEY, almPassword); - props.put("almDomain", - Util.replaceMacro(envVars.expand(almDomain), varResolver)); - props.put("almProject", - Util.replaceMacro(envVars.expand(almProject), varResolver)); - } - - if (!StringUtils.isEmpty(this.almTestSets)) { - - String[] testSetsArr = this.almTestSets.replaceAll("\r", "").split( - "\n"); - - int i = 1; - - for (String testSet : testSetsArr) { - if (!StringUtils.isBlank(testSet)) { - props.put("TestSet" + i, - Util.replaceMacro(envVars.expand(testSet), varResolver)); - i++; - } - } - } else { - props.put("almTestSets", ""); - } - - if (StringUtils.isEmpty(almTimeout)) { - props.put("almTimeout", "-1"); - } else { - props.put("almTimeout", almTimeout); - } - - props.put("almRunMode", almRunMode); - props.put("almRunHost", almRunHost); - - return props; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/RunFromFileSystemModel.java b/src/main/java/com/hp/application/automation/tools/model/RunFromFileSystemModel.java deleted file mode 100644 index 1c6bbf76fd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/RunFromFileSystemModel.java +++ /dev/null @@ -1,653 +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. - -package com.hp.application.automation.tools.model; - -import com.hp.application.automation.tools.mc.JobConfigurationProxy; -import hudson.EnvVars; -import hudson.util.Secret; -import hudson.util.VariableResolver; -import net.minidev.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -import javax.annotation.Nullable; -import java.util.Properties; - -/** - * Holds the data for RunFromFile build type. - */ -public class RunFromFileSystemModel { - - public static final String MOBILE_PROXY_SETTING_PASSWORD_FIELD = "MobileProxySetting_Password"; - public static final String MOBILE_PROXY_SETTING_USER_NAME = "MobileProxySetting_UserName"; - public static final String MOBILE_PROXY_SETTING_AUTHENTICATION = "MobileProxySetting_Authentication"; - public static final String MOBILE_USE_SSL = "MobileUseSSL"; - private String fsTests; - private String fsTimeout; - private String controllerPollingInterval; - private String perScenarioTimeOut; - private String ignoreErrorStrings; - private String mcServerName; - private String fsUserName; - private Secret fsPassword; - - private String fsDeviceId; - private String fsOs; - private String fsManufacturerAndModel; - private String fsTargetLab; - private String fsAutActions; - private String fsLaunchAppName; - private String fsInstrumented; - private String fsDevicesMetrics; - private String fsExtraApps; - private String fsJobId; - private ProxySettings proxySettings; - private boolean useSSL; - - /** - * Instantiates a new Run from file system model. - * - * @param fsTests the fs tests path - * @param fsTimeout the fs timeout in minutes for tests in seconds - * @param controllerPollingInterval the controller polling interval in minutes - * @param perScenarioTimeOut the per scenario time out in minutes - * @param ignoreErrorStrings the ignore error strings - * @param mcServerName the mc server name - * @param fsUserName the fs user name - * @param fsPassword the fs password - * @param fsDeviceId the fs device id - * @param fsTargetLab the fs target lab - * @param fsManufacturerAndModel the fs manufacturer and model - * @param fsOs the fs os - * @param fsAutActions the fs aut actions - * @param fsLaunchAppName the fs launch app name - * @param fsDevicesMetrics the fs devices metrics - * @param fsInstrumented the fs instrumented - * @param fsExtraApps the fs extra apps - * @param fsJobId the fs job id - * @param proxySettings the proxy settings - * @param useSSL the use ssl - */ - @SuppressWarnings("squid:S00107") - public RunFromFileSystemModel(String fsTests, String fsTimeout, String controllerPollingInterval,String perScenarioTimeOut, - String ignoreErrorStrings, String mcServerName, String fsUserName, String fsPassword, - String fsDeviceId, String fsTargetLab, String fsManufacturerAndModel, String fsOs, - String fsAutActions, String fsLaunchAppName, String fsDevicesMetrics, String fsInstrumented, - String fsExtraApps, String fsJobId, ProxySettings proxySettings, boolean useSSL) { - - this.setFsTests(fsTests); - - this.fsTimeout = fsTimeout; - - - this.perScenarioTimeOut = perScenarioTimeOut; - this.controllerPollingInterval = controllerPollingInterval; - this.ignoreErrorStrings = ignoreErrorStrings; - - this.mcServerName = mcServerName; - this.fsUserName = fsUserName; - this.fsPassword = Secret.fromString(fsPassword); - - - this.fsDeviceId = fsDeviceId; - this.fsOs = fsOs; - this.fsManufacturerAndModel = fsManufacturerAndModel; - this.fsTargetLab = fsTargetLab; - this.fsAutActions = fsAutActions; - this.fsLaunchAppName = fsLaunchAppName; - this.fsAutActions = fsAutActions; - this.fsDevicesMetrics = fsDevicesMetrics; - this.fsInstrumented = fsInstrumented; - this.fsExtraApps = fsExtraApps; - this.fsJobId = fsJobId; - this.proxySettings = proxySettings; - this.useSSL = useSSL; - - } - - - /** - * Instantiates a new file system model. - * - * @param fsTests the fs tests - */ - @DataBoundConstructor - public RunFromFileSystemModel(String fsTests) { - this.setFsTests(fsTests); - - //Init default vals - this.fsTimeout = ""; - this.controllerPollingInterval = "30"; - this.perScenarioTimeOut = "10"; - this.ignoreErrorStrings = ""; - } - - - /** - * Sets fs tests. - * - * @param fsTests the fs tests - */ - public void setFsTests(String fsTests) { - this.fsTests = fsTests.trim(); - - if (!this.fsTests.contains("\n")) { - this.fsTests += "\n"; - } - } - - /** - * Sets fs timeout. - * - * @param fsTimeout the fs timeout - */ - public void setFsTimeout(String fsTimeout) { - this.fsTimeout = fsTimeout; - } - - /** - * Sets mc server name. - * - * @param mcServerName the mc server name - */ - public void setMcServerName(String mcServerName) { - this.mcServerName = mcServerName; - } - - /** - * Sets fs user name. - * - * @param fsUserName the fs user name - */ - public void setFsUserName(String fsUserName) { - this.fsUserName = fsUserName; - } - - /** - * Sets fs password. - * - * @param fsPassword the fs password - */ - public void setFsPassword(String fsPassword) { - this.fsPassword = Secret.fromString(fsPassword); - } - - /** - * Sets fs device id. - * - * @param fsDeviceId the fs device id - */ - public void setFsDeviceId(String fsDeviceId) { - this.fsDeviceId = fsDeviceId; - } - - /** - * Sets fs os. - * - * @param fsOs the fs os - */ - public void setFsOs(String fsOs) { - this.fsOs = fsOs; - } - - /** - * Sets fs manufacturer and model. - * - * @param fsManufacturerAndModel the fs manufacturer and model - */ - public void setFsManufacturerAndModel(String fsManufacturerAndModel) { - this.fsManufacturerAndModel = fsManufacturerAndModel; - } - - /** - * Sets fs target lab. - * - * @param fsTargetLab the fs target lab - */ - public void setFsTargetLab(String fsTargetLab) { - this.fsTargetLab = fsTargetLab; - } - - /** - * Sets fs aut actions. - * - * @param fsAutActions the fs aut actions - */ - public void setFsAutActions(String fsAutActions) { - this.fsAutActions = fsAutActions; - } - - /** - * Sets fs launch app name. - * - * @param fsLaunchAppName the fs launch app name - */ - public void setFsLaunchAppName(String fsLaunchAppName) { - this.fsLaunchAppName = fsLaunchAppName; - } - - /** - * Sets fs instrumented. - * - * @param fsInstrumented the fs instrumented - */ - public void setFsInstrumented(String fsInstrumented) { - this.fsInstrumented = fsInstrumented; - } - - /** - * Sets fs devices metrics. - * - * @param fsDevicesMetrics the fs devices metrics - */ - public void setFsDevicesMetrics(String fsDevicesMetrics) { - this.fsDevicesMetrics = fsDevicesMetrics; - } - - /** - * Sets fs extra apps. - * - * @param fsExtraApps the fs extra apps - */ - public void setFsExtraApps(String fsExtraApps) { - this.fsExtraApps = fsExtraApps; - } - - /** - * Sets fs job id. - * - * @param fsJobId the fs job id - */ - public void setFsJobId(String fsJobId) { - this.fsJobId = fsJobId; - } - - /** - * Sets proxy settings. - * - * @param proxySettings the proxy settings - */ - public void setProxySettings(ProxySettings proxySettings) { - this.proxySettings = proxySettings; - } - - /** - * Sets use ssl. - * - * @param useSSL the use ssl - */ - public void setUseSSL(boolean useSSL) { - this.useSSL = useSSL; - } - - /** - * Gets fs tests. - * - * @return the fs tests - */ - public String getFsTests() { - return fsTests; - } - - /** - * Gets fs timeout. - * - * @return the fs timeout - */ - public String getFsTimeout() { - return fsTimeout; - } - - /** - * Gets mc server name. - * - * @return the mc server name - */ - public String getMcServerName() { - return mcServerName; - } - - /** - * Gets fs user name. - * - * @return the fs user name - */ - public String getFsUserName() { - return fsUserName; - } - - /** - * Gets fs password. - * - * @return the fs password - */ - public String getFsPassword() { - //Temp fix till supported in pipeline module in LR - if(fsPassword == null) - { - return null; - } - return fsPassword.getPlainText(); - } - /** - * Gets fs device id. - * - * @return the fs device id - */ - public String getFsDeviceId() { - return fsDeviceId; - } - - /** - * Gets fs os. - * - * @return the fs os - */ - public String getFsOs() { - return fsOs; - } - - /** - * Gets fs manufacturer and model. - * - * @return the fs manufacturer and model - */ - public String getFsManufacturerAndModel() { - return fsManufacturerAndModel; - } - - /** - * Gets fs target lab. - * - * @return the fs target lab - */ - public String getFsTargetLab() { - return fsTargetLab; - } - - /** - * Gets fs aut actions. - * - * @return the fs aut actions - */ - public String getFsAutActions() { - return fsAutActions; - } - - /** - * Gets fs launch app name. - * - * @return the fs launch app name - */ - public String getFsLaunchAppName() { - return fsLaunchAppName; - } - - /** - * Gets fs instrumented. - * - * @return the fs instrumented - */ - public String getFsInstrumented() { - return fsInstrumented; - } - - /** - * Gets fs devices metrics. - * - * @return the fs devices metrics - */ - public String getFsDevicesMetrics() { - return fsDevicesMetrics; - } - - /** - * Gets fs extra apps. - * - * @return the fs extra apps - */ - public String getFsExtraApps() { - return fsExtraApps; - } - - /** - * Gets fs job id. - * - * @return the fs job id - */ - public String getFsJobId() { - return fsJobId; - } - - /** - * Is use proxy boolean. - * - * @return the boolean - */ - public boolean isUseProxy() { - return proxySettings != null; - } - - /** - * Is use authentication boolean. - * - * @return the boolean - */ - public boolean isUseAuthentication() { - return proxySettings != null && StringUtils.isNotBlank(proxySettings.getFsProxyUserName()); - } - - /** - * Gets proxy settings. - * - * @return the proxy settings - */ - public ProxySettings getProxySettings() { - return proxySettings; - } - - /** - * Is use ssl boolean. - * - * @return the boolean - */ - public boolean isUseSSL() { - return useSSL; - } - - - /** - * Gets controller polling interval. - * - * @return the controllerPollingInterval - */ - public String getControllerPollingInterval() { - return controllerPollingInterval; - } - - /** - * Sets controller polling interval. - * - * @param controllerPollingInterval the controllerPollingInterval to set - */ - public void setControllerPollingInterval(String controllerPollingInterval) { - this.controllerPollingInterval = controllerPollingInterval; - } - - /** - * Gets ignore error strings. - * - * @return the ignoreErrorStrings - */ - public String getIgnoreErrorStrings() { - return ignoreErrorStrings; - } - - - /** - * Sets ignore error strings. - * - * @param ignoreErrorStrings the ignoreErrorStrings to set - */ - public void setIgnoreErrorStrings(String ignoreErrorStrings) { - this.ignoreErrorStrings = ignoreErrorStrings; - } - - - /** - * Gets per scenario time out. - * - * @return the perScenarioTimeOut - */ - public String getPerScenarioTimeOut() { - return perScenarioTimeOut; - } - - /** - * Sets per scenario time out. - * - * @param perScenarioTimeOut the perScenarioTimeOut to set - */ - public void setPerScenarioTimeOut(String perScenarioTimeOut) { - this.perScenarioTimeOut = perScenarioTimeOut; - } - - - /** - * Gets properties. - * - * @param envVars the env vars - * @return the properties - */ - @Nullable - public Properties getProperties(EnvVars envVars, - VariableResolver varResolver) { - return createProperties(envVars, varResolver); - } - - private Properties createProperties(EnvVars envVars, - VariableResolver varResolver) { - - return createProperties(envVars); - } - - /** - * Gets properties. - * - * @param envVars the env vars - * @return the properties - */ - @Nullable - public Properties getProperties(EnvVars envVars) { - return createProperties(envVars); - } - - /** - * Gets properties. - * - * @return the properties - */ - public Properties getProperties() { - return createProperties(null); - } - - private Properties createProperties(EnvVars envVars) { - Properties props = new Properties(); - - if (!StringUtils.isEmpty(this.fsTests)) { - String expandedFsTests = envVars.expand(fsTests); - String[] testsArr = expandedFsTests.replaceAll("\r", "").split("\n"); - - int i = 1; - - for (String test : testsArr) { - test = test.trim(); - props.put("Test" + i, test); - i++; - } - } else { - props.put("fsTests", ""); - } - - - if (StringUtils.isEmpty(fsTimeout)){ - props.put("fsTimeout", "-1"); - } - else{ - props.put("fsTimeout", "" + fsTimeout); - } - - - if (StringUtils.isEmpty(controllerPollingInterval)){ - props.put("controllerPollingInterval", "30"); - } - else{ - props.put("controllerPollingInterval", "" + controllerPollingInterval); - } - - if (StringUtils.isEmpty(perScenarioTimeOut)){ - props.put("PerScenarioTimeOut", "10"); - } - else{ - props.put("PerScenarioTimeOut", ""+ perScenarioTimeOut); - } - - if (!StringUtils.isEmpty(ignoreErrorStrings.replaceAll("\\r|\\n", ""))){ - props.put("ignoreErrorStrings", ""+ignoreErrorStrings.replaceAll("\r", "")); - } - - if (StringUtils.isNotBlank(fsUserName)){ - props.put("MobileUserName", fsUserName); - } - - if(isUseProxy()){ - props.put("MobileUseProxy", "1"); - props.put("MobileProxyType","2"); - props.put("MobileProxySetting_Address", proxySettings.getFsProxyAddress()); - if(isUseAuthentication()){ - props.put(MOBILE_PROXY_SETTING_AUTHENTICATION,"1"); - props.put(MOBILE_PROXY_SETTING_USER_NAME,proxySettings.getFsProxyUserName()); - props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD, proxySettings.getFsProxyPassword()); - }else{ - props.put(MOBILE_PROXY_SETTING_AUTHENTICATION,"0"); - props.put(MOBILE_PROXY_SETTING_USER_NAME,""); - props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD,""); - } - }else{ - props.put("MobileUseProxy", "0"); - props.put("MobileProxyType","0"); - props.put(MOBILE_PROXY_SETTING_AUTHENTICATION,"0"); - props.put("MobileProxySetting_Address", ""); - props.put(MOBILE_PROXY_SETTING_USER_NAME,""); - props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD,""); - } - - if(useSSL){ - props.put(MOBILE_USE_SSL,"1"); - }else{ - props.put(MOBILE_USE_SSL,"0"); - } - - return props; - } - - /** - * Get proxy details json object. - * - * @param mcUrl the mc url - * @param proxyAddress the proxy address - * @param proxyUserName the proxy user name - * @param proxyPassword the proxy password - * @return the json object - */ - public JSONObject getJobDetails(String mcUrl, String proxyAddress, String proxyUserName, String proxyPassword){ - if(StringUtils.isBlank(fsUserName) || StringUtils.isBlank(fsPassword.getPlainText())){ - return null; - } - return JobConfigurationProxy.getInstance().getJobById(mcUrl, fsUserName, fsPassword.getPlainText(), proxyAddress, proxyUserName, proxyPassword, fsJobId); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/model/RunMode.java b/src/main/java/com/hp/application/automation/tools/model/RunMode.java deleted file mode 100644 index 1a6d66fdee..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/RunMode.java +++ /dev/null @@ -1,25 +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. - -package com.hp.application.automation.tools.model; - -public class RunMode { - - public RunMode(String value, String description) { - this.value = value; - this.description = description; - } - - private String description; - private String value; - - public String getDescription() { - return description; - } - - public String getValue() { - return value; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SecretContainer.java b/src/main/java/com/hp/application/automation/tools/model/SecretContainer.java deleted file mode 100644 index 45b6079bf1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SecretContainer.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.hp.application.automation.tools.model; - -public interface SecretContainer { - - void initialize(String secret); -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SecretContainerImpl.java b/src/main/java/com/hp/application/automation/tools/model/SecretContainerImpl.java deleted file mode 100644 index d6d0aeaf7b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SecretContainerImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hp.application.automation.tools.model; - -import hudson.util.Secret; - -public class SecretContainerImpl implements SecretContainer { - - private Secret _secret; - - public void initialize(String secret) { - - _secret = Secret.fromString(secret); - } - - @Override - public String toString() { - - return _secret.getPlainText(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SseModel.java b/src/main/java/com/hp/application/automation/tools/model/SseModel.java deleted file mode 100644 index 0be819442c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SseModel.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.hp.application.automation.tools.model; - -import java.util.Arrays; -import java.util.List; - -import org.kohsuke.stapler.DataBoundConstructor; - -/** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class SseModel { - - public static final String TEST_SET = "TEST_SET"; - public static final String BVS = "BVS"; - public static final String PC = "PC"; - - public static final String COLLATE = "Collate"; - public static final String COLLATE_ANALYZE = "CollateAndAnalyze"; - public static final String DO_NOTHING = "DoNothing"; - - private final String _almServerName; - private String _almServerUrl; - private final String _almUserName; - private final SecretContainer _almPassword; - private final String _almDomain; - private final String _almProject; - private final String _timeslotDuration; - private final String _description; - private final String _runType; - private final String _almEntityId; - private final String _postRunAction; - private final String _environmentConfigurationId; - private final CdaDetails _cdaDetails; - private final SseProxySettings _proxySettings; - - private final static EnumDescription _runTypeTestSet = - new EnumDescription(TEST_SET, "Test Set"); - private final static EnumDescription _runTypeBVS = new EnumDescription( - BVS, - "Build Verification Suite"); - private final static List _runTypes = Arrays.asList( - _runTypeTestSet, - _runTypeBVS); - - private final static EnumDescription _postRunActionCollate = new EnumDescription( - COLLATE, - "Collate"); - private final static EnumDescription _postRunActionCollateAnalyze = new EnumDescription( - COLLATE_ANALYZE, - "CollateAndAnalyze"); - private final static EnumDescription _postRunActionDoNothing = new EnumDescription( - DO_NOTHING, - "DoNothing"); - private final static List _postRunActions = Arrays.asList( - _postRunActionCollate, - _postRunActionCollateAnalyze, - _postRunActionDoNothing); - - @DataBoundConstructor - public SseModel( - String almServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String runType, - String almEntityId, - String timeslotDuration, - String description, - String postRunAction, - String environmentConfigurationId, - CdaDetails cdaDetails, - SseProxySettings proxySettings) { - - _almServerName = almServerName; - _almDomain = almDomain; - _almProject = almProject; - _timeslotDuration = timeslotDuration; - _almEntityId = almEntityId; - _almUserName = almUserName; - _almPassword = setPassword(almPassword); - _runType = runType; - _description = description; - _postRunAction = postRunAction; - _environmentConfigurationId = environmentConfigurationId; - _cdaDetails = cdaDetails; - _proxySettings = proxySettings; - - } - - protected SecretContainer setPassword(String almPassword) { - - SecretContainer secretContainer = new SecretContainerImpl(); - secretContainer.initialize(almPassword); - - return secretContainer; - } - - public String getAlmServerName() { - - return _almServerName; - } - - public String getAlmServerUrl() { - - return _almServerUrl; - } - - public void setAlmServerUrl(String almServerUrl) { - - _almServerUrl = almServerUrl; - } - - public String getAlmUserName() { - - return _almUserName; - } - - public String getAlmPassword() { - - return _almPassword.toString(); - } - - public String getAlmDomain() { - - return _almDomain; - } - - public String getAlmProject() { - - return _almProject; - } - - public String getTimeslotDuration() { - - return _timeslotDuration; - } - - public String getAlmEntityId() { - - return _almEntityId; - } - - public String getRunType() { - return _runType; - } - - public String getDescription() { - - return _description; - } - - public String getEnvironmentConfigurationId() { - - return _environmentConfigurationId; - } - - public static List getRunTypes() { - - return _runTypes; - } - - public static List getPostRunActions() { - - return _postRunActions; - } - - public CdaDetails getCdaDetails() { - - return _cdaDetails; - } - - public String getPostRunAction() { - - return _postRunAction; - } - - public SseProxySettings getProxySettings() { - return _proxySettings; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SseProxySettings.java b/src/main/java/com/hp/application/automation/tools/model/SseProxySettings.java deleted file mode 100644 index 3e1753773e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SseProxySettings.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.hp.application.automation.tools.model; - -import org.kohsuke.stapler.DataBoundConstructor; - -import hudson.util.Secret; - -/** - * This model is for sse build step's proxy setting. - * It's different from the class ProxySettings. Here we use credentials instead of name/password. - * @author llu4 - * - */ -public class SseProxySettings { - private String fsProxyAddress; - private String fsProxyCredentialsId; - - /** - * To store the user name which get from the credentials. - * Is set in sseBuilder while performing. - */ - private String fsProxyUserName; - - /** - * To store the password which get from the credentials. - * Is set in sseBuilder while performing. - */ - private Secret fsProxyPassword; - - /** - * These two variables are set directly by the jelly form. - */ - @DataBoundConstructor - public SseProxySettings(String fsProxyAddress, String fsProxyCredentialsId) { - this.fsProxyAddress = fsProxyAddress; - this.fsProxyCredentialsId = fsProxyCredentialsId; - } - - public String getFsProxyAddress() { - return fsProxyAddress; - } - - public String getFsProxyCredentialsId() { - return fsProxyCredentialsId; - } - - public String getFsProxyUserName() { - return fsProxyUserName; - } - - public void setFsProxyUserName(String fsProxyUserName) { - this.fsProxyUserName = fsProxyUserName; - } - - public Secret getFsProxyPassword() { - return fsProxyPassword; - } - - public void setFsProxyPassword(Secret fsProxyPassword) { - this.fsProxyPassword = fsProxyPassword; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SvChangeModeModel.java b/src/main/java/com/hp/application/automation/tools/model/SvChangeModeModel.java deleted file mode 100644 index 421109bad7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvChangeModeModel.java +++ /dev/null @@ -1,39 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import com.hp.sv.jsvconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvChangeModeModel extends AbstractSvRunModel { - - private static final SvDataModelSelection NONE_DATA_MODEL = new SvDataModelSelection(SvDataModelSelection.SelectionType.NONE, null); - private static final SvPerformanceModelSelection NONE_PERFORMANCE_MODEL = new SvPerformanceModelSelection(SvPerformanceModelSelection.SelectionType.NONE, null); - private final ServiceRuntimeConfiguration.RuntimeMode mode; - private final SvDataModelSelection dataModel; - private final SvPerformanceModelSelection performanceModel; - - @DataBoundConstructor - public SvChangeModeModel(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, - SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { - super(serverName, force, serviceSelection); - this.mode = mode; - this.dataModel = dataModel; - this.performanceModel = performanceModel; - } - - public ServiceRuntimeConfiguration.RuntimeMode getMode() { - return mode; - } - - public SvDataModelSelection getDataModel() { - return (mode == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY) ? NONE_DATA_MODEL : dataModel; - } - - public SvPerformanceModelSelection getPerformanceModel() { - return (mode == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY) ? NONE_PERFORMANCE_MODEL : performanceModel; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/SvDataModelSelection.java b/src/main/java/com/hp/application/automation/tools/model/SvDataModelSelection.java deleted file mode 100644 index 3680521a43..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvDataModelSelection.java +++ /dev/null @@ -1,107 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import javax.annotation.Nonnull; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.util.FormValidation; -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvDataModelSelection extends AbstractDescribableImpl { - - protected final SelectionType selectionType; - protected final String dataModel; - - @DataBoundConstructor - public SvDataModelSelection(SelectionType selectionType, String dataModel) { - this.selectionType = selectionType; - this.dataModel = StringUtils.trim(dataModel); - } - - public static void validateField(FormValidation result) { - if (!result.equals(FormValidation.ok())) { - throw new IllegalArgumentException(StringEscapeUtils.unescapeXml(result.getMessage())); - } - } - - @SuppressWarnings("unused") - public SelectionType getSelectionType() { - return selectionType; - } - - public String getDataModel() { - return (StringUtils.isNotBlank(dataModel)) ? dataModel : null; - } - - @SuppressWarnings("unused") - public boolean isSelected(String type) { - return SelectionType.valueOf(type) == this.selectionType; - } - - public boolean isNoneSelected() { - return selectionType == SelectionType.NONE; - } - - public boolean isDefaultSelected() { - return selectionType == SelectionType.DEFAULT; - } - - @Override - public String toString() { - switch (selectionType) { - case BY_NAME: - return dataModel; - case NONE: - return ""; - case DEFAULT: - default: - return ""; - } - } - - public String getSelectedModelName() { - switch (selectionType) { - case BY_NAME: - DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); - validateField(descriptor.doCheckDataModel(dataModel)); - return dataModel; - default: - return null; - } - } - - public enum SelectionType { - BY_NAME, - NONE, - /** - * Default means first model in alphabetical order by model name - */ - DEFAULT, - } - - @Extension - public static class DescriptorImpl extends Descriptor { - - @Nonnull - public String getDisplayName() { - return "Data model Selection"; - } - - @SuppressWarnings("unused") - public FormValidation doCheckDataModel(@QueryParameter String dataModel) { - if (StringUtils.isBlank(dataModel)) { - return FormValidation.error("Data model cannot be empty if 'Specific' model is selected"); - } - return FormValidation.ok(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SvDeployModel.java b/src/main/java/com/hp/application/automation/tools/model/SvDeployModel.java deleted file mode 100644 index b3795baacd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvDeployModel.java +++ /dev/null @@ -1,35 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvDeployModel extends AbstractSvRunModel { - - protected final boolean firstAgentFallback; - - @DataBoundConstructor - public SvDeployModel(String serverName, boolean force, String service, String projectPath, String projectPassword, boolean firstAgentFallback) { - super(serverName, force, new SvServiceSelectionModel(SvServiceSelectionModel.SelectionType.DEPLOY, service, projectPath, projectPassword)); - this.firstAgentFallback = firstAgentFallback; - } - - public String getService() { - return (serviceSelection != null) ? serviceSelection.getService() : null; - } - - public String getProjectPath() { - return (serviceSelection != null) ? serviceSelection.getProjectPath() : null; - } - - public String getProjectPassword() { - return (serviceSelection != null) ? serviceSelection.getProjectPassword() : null; - } - - public boolean isFirstAgentFallback() { - return firstAgentFallback; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/SvExportModel.java b/src/main/java/com/hp/application/automation/tools/model/SvExportModel.java deleted file mode 100644 index b0203042da..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvExportModel.java +++ /dev/null @@ -1,37 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvExportModel extends AbstractSvRunModel { - - private final String targetDirectory; - private final boolean cleanTargetDirectory; - private final boolean switchToStandByFirst; - - @DataBoundConstructor - public SvExportModel(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, - SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst) { - super(serverName, force, serviceSelection); - this.targetDirectory = StringUtils.trim(targetDirectory); - this.cleanTargetDirectory = cleanTargetDirectory; - this.switchToStandByFirst = switchToStandByFirst; - } - - public String getTargetDirectory() { - return (StringUtils.isNotBlank(targetDirectory)) ? targetDirectory : null; - } - - public boolean isCleanTargetDirectory() { - return cleanTargetDirectory; - } - - public boolean isSwitchToStandByFirst() { - return switchToStandByFirst; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/SvPerformanceModelSelection.java b/src/main/java/com/hp/application/automation/tools/model/SvPerformanceModelSelection.java deleted file mode 100644 index 31b2cbf80c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvPerformanceModelSelection.java +++ /dev/null @@ -1,105 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import javax.annotation.Nonnull; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.util.FormValidation; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvPerformanceModelSelection extends AbstractDescribableImpl { - - protected final SelectionType selectionType; - protected final String performanceModel; - - @DataBoundConstructor - public SvPerformanceModelSelection(SelectionType selectionType, String performanceModel) { - this.selectionType = selectionType; - this.performanceModel = StringUtils.trim(performanceModel); - } - - @SuppressWarnings("unused") - public SelectionType getSelectionType() { - return selectionType; - } - - @SuppressWarnings("unused") - public String getPerformanceModel() { - return (StringUtils.isNotBlank(performanceModel)) ? performanceModel : null; - } - - @SuppressWarnings("unused") - public boolean isSelected(String type) { - return SelectionType.valueOf(type) == this.selectionType; - } - - public boolean isNoneSelected() { - return selectionType == SelectionType.NONE; - } - - public boolean isDefaultSelected() { - return selectionType == SelectionType.DEFAULT; - } - - @Override - public String toString() { - switch (selectionType) { - case BY_NAME: - return performanceModel; - case NONE: - return ""; - case OFFLINE: - return ""; - default: - return ""; - } - } - - public String getSelectedModelName() { - switch (selectionType) { - case BY_NAME: - DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); - SvDataModelSelection.validateField(descriptor.doCheckPerformanceModel(performanceModel)); - return performanceModel; - case OFFLINE: - return "Offline"; - default: - return null; - } - } - - public enum SelectionType { - BY_NAME, - NONE, - OFFLINE, - /** - * Default means first model in alphabetical order by model name - */ - DEFAULT, - } - - @Extension - public static class DescriptorImpl extends Descriptor { - - @Nonnull - public String getDisplayName() { - return "Performance Model Selection"; - } - - @SuppressWarnings("unused") - public FormValidation doCheckPerformanceModel(@QueryParameter String performanceModel) { - if (StringUtils.isBlank(performanceModel)) { - return FormValidation.error("Performance model cannot be empty if 'Specific' model is selected"); - } - return FormValidation.ok(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SvServerSettingsModel.java b/src/main/java/com/hp/application/automation/tools/model/SvServerSettingsModel.java deleted file mode 100644 index 539b50c83c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvServerSettingsModel.java +++ /dev/null @@ -1,57 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import java.net.MalformedURLException; -import java.net.URL; - -import com.hp.sv.jsvconfigurator.core.impl.processor.Credentials; -import hudson.util.Secret; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvServerSettingsModel { - - private final String name; - private final String url; - private final String username; - private final Secret password; - - @DataBoundConstructor - public SvServerSettingsModel(String name, String url, String username, Secret password) { - this.name = StringUtils.trim(name); - this.url = StringUtils.trim(url); - this.username = username; - this.password = password; - } - - public String getName() { - return name; - } - - public String getUrl() { - return url; - } - - public URL getUrlObject() throws MalformedURLException { - return new URL(url); - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password.getPlainText(); - } - - public Credentials getCredentials() { - if (StringUtils.isBlank(username) || password == null) { - return null; - } - return new Credentials(username, password.getPlainText()); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/SvServiceSelectionModel.java b/src/main/java/com/hp/application/automation/tools/model/SvServiceSelectionModel.java deleted file mode 100644 index f14b6bac43..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvServiceSelectionModel.java +++ /dev/null @@ -1,100 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import javax.annotation.Nonnull; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.util.FormValidation; -import hudson.util.Secret; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.Validate; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvServiceSelectionModel extends AbstractDescribableImpl { - - protected final SelectionType selectionType; - protected final String service; - protected final String projectPath; - protected final Secret projectPassword; - - @DataBoundConstructor - public SvServiceSelectionModel(SelectionType selectionType, String service, String projectPath, String projectPassword) { - Validate.notNull(selectionType, "SelectionType must be specified"); - this.selectionType = selectionType; - this.service = StringUtils.trim(service); - this.projectPath = StringUtils.trim(projectPath); - this.projectPassword = Secret.fromString(projectPassword); - } - - public SelectionType getSelectionType() { - return selectionType; - } - - public String getService() { - return (StringUtils.isNotBlank(service)) ? service : null; - } - - public String getProjectPath() { - return (StringUtils.isNotBlank(projectPath)) ? projectPath : null; - } - - public String getProjectPassword() { - return (projectPassword != null) ? projectPassword.getPlainText() : null; - } - - @SuppressWarnings("unused") - public boolean isSelected(String selectionType) { - return SelectionType.valueOf(selectionType) == this.selectionType; - } - - public enum SelectionType { - /** - * Select service by name or id - */ - SERVICE, - /** - * Select all services from project - */ - PROJECT, - /** - * Select all deployed services - */ - ALL_DEPLOYED, - /** - * Specific case for deployment. Uses project & optionally service names. - */ - DEPLOY - } - - @Extension - public static class DescriptorImpl extends Descriptor { - - @Nonnull - public String getDisplayName() { - return "Service Selection"; - } - - @SuppressWarnings("unused") - public FormValidation doCheckService(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Service name or id must be set"); - } - return FormValidation.ok(); - } - - @SuppressWarnings("unused") - public FormValidation doCheckProjectPath(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Project path cannot be empty"); - } - return FormValidation.ok(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/SvUndeployModel.java b/src/main/java/com/hp/application/automation/tools/model/SvUndeployModel.java deleted file mode 100644 index ea5333ae0c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/SvUndeployModel.java +++ /dev/null @@ -1,23 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.model; - -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvUndeployModel extends AbstractSvRunModel { - - protected final boolean continueIfNotDeployed; - - @DataBoundConstructor - public SvUndeployModel(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { - super(serverName, force, serviceSelection); - this.continueIfNotDeployed = continueIfNotDeployed; - } - - public boolean isContinueIfNotDeployed() { - return continueIfNotDeployed; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/model/TimeslotDuration.java b/src/main/java/com/hp/application/automation/tools/model/TimeslotDuration.java deleted file mode 100644 index 1e6f2b82d7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/TimeslotDuration.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hp.application.automation.tools.model; - -public class TimeslotDuration { - - private int Hours; - - private int Minutes; - - public TimeslotDuration(int hours, int minutes) { - - Hours = hours + minutes / 60; - Minutes = minutes % 60; - } - - public TimeslotDuration(String hours, String minutes) { - - try{ - int m = Integer.parseInt(minutes); - int h = Integer.parseInt(hours) + m / 60; - if (h < 480) { - Hours = h; - Minutes = m % 60; - } else { - Hours = 480; - Minutes = 0; - } - } catch (Exception e) { - Hours = 0; - Minutes = 0; - } - } - - public TimeslotDuration(int minutes) { - - this(0, minutes); - } - - public int getHours() { - - return Hours; - } - - public int getMinutes() { - - return Minutes; - } - - public int toMinutes() { - - return Hours * 60 + Minutes; - } - - @Override - public String toString() { - - return String.format("%d:%02d(h:mm)", Hours, Minutes); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/model/UploadAppModel.java b/src/main/java/com/hp/application/automation/tools/model/UploadAppModel.java deleted file mode 100644 index 9e147a07ef..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/UploadAppModel.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hp.application.automation.tools.model; - -import hudson.util.Secret; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 5/17/16 - * Time: 4:43 PM - * To change this template use File | Settings | File Templates. - */ -public class UploadAppModel { - private String mcServerName; - private String mcUserName; - private Secret mcPassword; - private ProxySettings proxySettings; - private List applicationPaths; - - @DataBoundConstructor - public UploadAppModel(String mcServerName, String mcUserName, String mcPassword, ProxySettings proxySettings, List applicationPaths) { - this.mcServerName = mcServerName; - this.mcUserName = mcUserName; - this.mcPassword = Secret.fromString(mcPassword); - this.proxySettings = proxySettings; - this.applicationPaths = applicationPaths; - } - - public String getMcServerName() { - return mcServerName; - } - - public String getMcUserName() { - return mcUserName; - } - - public String getMcPassword() { - return mcPassword.getPlainText(); - } - - public ProxySettings getProxySettings() { - return proxySettings; - } - - public boolean isUseProxy() { - return proxySettings != null; - } - - public boolean isUseAuthentication() { - return proxySettings != null && StringUtils.isNotBlank(proxySettings.getFsProxyUserName()); - } - - public List getApplicationPaths() { - return applicationPaths; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/UploadAppPathModel.java b/src/main/java/com/hp/application/automation/tools/model/UploadAppPathModel.java deleted file mode 100644 index 8133837be5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/UploadAppPathModel.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hp.application.automation.tools.model; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import org.kohsuke.stapler.DataBoundConstructor; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 5/20/16 - * Time: 2:52 PM - * To change this template use File | Settings | File Templates. - */ -public class UploadAppPathModel extends AbstractDescribableImpl { - private String mcAppPath; - - @DataBoundConstructor - public UploadAppPathModel(String mcAppPath) { - this.mcAppPath = mcAppPath; - } - - public String getMcAppPath() { - return mcAppPath; - } - - @Extension - public static class DescriptorImpl extends Descriptor { - public String getDisplayName() { - return ""; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/model/UploadTestResultToAlmModel.java b/src/main/java/com/hp/application/automation/tools/model/UploadTestResultToAlmModel.java deleted file mode 100644 index a7d4644e73..0000000000 --- a/src/main/java/com/hp/application/automation/tools/model/UploadTestResultToAlmModel.java +++ /dev/null @@ -1,212 +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. - -package com.hp.application.automation.tools.model; - -import hudson.EnvVars; -import hudson.Util; -import hudson.util.Secret; -import hudson.util.VariableResolver; - -import java.util.Arrays; -import java.util.List; -import java.util.Properties; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; - -public class UploadTestResultToAlmModel { - - - public final static int DEFAULT_TIMEOUT = 36000; // 10 hrs - public final static String ALM_PASSWORD_KEY = "almPassword"; - - public final static EnumDescription testingFrameworkJunit = new EnumDescription( - "JUnit", "JUnit"); - public final static EnumDescription testingFrameworkTestNG = new EnumDescription( - "TestNG", "TestNG"); - public final static EnumDescription testingFrameworkNUnit = new EnumDescription( - "NUnit", "NUnit"); - public final static List testingFrameworks = Arrays.asList( - testingFrameworkJunit, testingFrameworkTestNG, testingFrameworkNUnit); - - private String almServerName; - private String almUserName; - private Secret almPassword; - private String almDomain; - private String almProject; - private String almTimeout; - private String almTestFolder; - private String almTestSetFolder; - private String testingFramework; - private String testingTool; - private String testingResultFile; - private String jenkinsServerUrl; - - @DataBoundConstructor - public UploadTestResultToAlmModel(String almServerName, String almUserName, - String almPassword, String almDomain, String almProject, String testingFramework, String testingTool, - String almTestFolder , String almTestSetFolder, String almTimeout, String testingResultFile, String jenkinsServerUrl) { - - this.almServerName = almServerName; - this.almUserName = almUserName; - this.almPassword = Secret.fromString(almPassword); - this.almDomain = almDomain; - this.almProject = almProject; - - this.almTimeout=almTimeout; - this.almTestFolder = almTestFolder; - this.almTestSetFolder = almTestSetFolder; - - this.testingFramework = testingFramework; - this.testingTool = testingTool; - - this.testingResultFile = testingResultFile; - this.jenkinsServerUrl = jenkinsServerUrl; - } - - public String getAlmUserName() { - return almUserName; - } - - public String getAlmDomain() { - return almDomain; - } - - public String getAlmPassword() { - return almPassword.getPlainText(); - } - - public String getAlmProject() { - return almProject; - } - - public String getTestingFramework() { - return testingFramework; - } - public String getTestingTool() { - return testingTool; - } - - public String getAlmTimeout() { - return almTimeout; - } - - public String getAlmTestFolder() { - return almTestFolder; - } - - public String getAlmTestSetFolder() { - return almTestSetFolder; - } - - public String getAlmServerName() { - return almServerName; - } - - public String getTestingResultFile() { - return testingResultFile; - } - - public String getJenkinsServerUrl() { - return jenkinsServerUrl; - } - - public Properties getProperties(EnvVars envVars, - VariableResolver varResolver) { - return CreateProperties(envVars, varResolver); - } - - public Properties getProperties() { - return CreateProperties(null, null); - } - - private Properties CreateProperties(EnvVars envVars, - VariableResolver varResolver) { - Properties props = new Properties(); - - if (envVars == null) { - props.put("almUserName", almUserName); - props.put(ALM_PASSWORD_KEY, almPassword); - props.put("almDomain", almDomain); - props.put("almProject", almProject); - } else { - props.put("almUserName", - Util.replaceMacro(envVars.expand(almUserName), varResolver)); - props.put(ALM_PASSWORD_KEY, almPassword); - props.put("almDomain", - Util.replaceMacro(envVars.expand(almDomain), varResolver)); - props.put("almProject", - Util.replaceMacro(envVars.expand(almProject), varResolver)); - } - - if (!StringUtils.isEmpty(this.testingFramework)) { - props.put("testingFramework" , testingFramework); - - } else { - props.put("testingFramework", ""); - } - - if (!StringUtils.isEmpty(this.testingTool)) { - props.put("testingTool" , testingTool); - - } else { - props.put("testingTool", ""); - } - - if (!StringUtils.isEmpty(this.almTestFolder)) { - props.put("almTestFolder" , almTestFolder); - - } else { - props.put("almTestFolder", ""); - } - - - if (!StringUtils.isEmpty(this.almTestSetFolder)) { - props.put("almTestSetFolder" , almTestSetFolder); - - } else { - props.put("almTestSetFolder", ""); - } - - if (StringUtils.isEmpty(almTimeout)) { - props.put("almTimeout", "-1"); - } else { - props.put("almTimeout", almTimeout); - } - - if (!StringUtils.isEmpty(this.testingResultFile)) { - props.put("testingResultFile" , testingResultFile); - - } else { - props.put("testingResultFile", ""); - } - - if (!StringUtils.isEmpty(this.jenkinsServerUrl)) { - props.put("jenkinsServerUrl" , jenkinsServerUrl); - - } else { - props.put("jenkinsServerUrl", ""); - } - - - return props; - } - - public String toString(){ - return almServerName + "," + - almUserName + "," + - almPassword + "," + - almDomain + "," + - almProject + "," + - almTimeout + "," + - almTestFolder + "," + - almTestSetFolder + "," + - testingFramework + "," + - testingTool+ "," + - testingResultFile + "," + - jenkinsServerUrl; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/AbstractResultQueueImpl.java b/src/main/java/com/hp/application/automation/tools/octane/AbstractResultQueueImpl.java deleted file mode 100644 index 0fa8bf4728..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/AbstractResultQueueImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane; - -import com.squareup.tape.FileObjectQueue; -import net.sf.json.JSONObject; -import net.sf.json.JSONSerializer; -import org.apache.commons.io.IOUtils; - -import java.io.*; - -/** - * Created by benmeior on 11/21/2016. - */ - -public abstract class AbstractResultQueueImpl implements ResultQueue { - - private static final int RETRY_COUNT = 3; - - private FileObjectQueue queue; - - private QueueItem currentItem; - - protected void init(File queueFile) throws IOException { - queue = new FileObjectQueue(queueFile, new JsonConverter()); - } - - @Override - public synchronized QueueItem peekFirst() { - if (currentItem == null) { - currentItem = queue.peek(); - } - return currentItem; - } - - @Override - public synchronized boolean failed() { - if (currentItem != null) { - boolean retry; - if (++currentItem.failCount <= RETRY_COUNT) { - queue.add(currentItem); - retry = true; - } else { - retry = false; - } - - remove(); - - return retry; - } else { - throw new IllegalStateException("no outstanding item"); - } - } - - @Override - public synchronized void remove() { - if (currentItem != null) { - queue.remove(); - currentItem = null; - } else { - throw new IllegalStateException("no outstanding item"); - } - } - - @Override - public synchronized void add(String projectName, int buildNumber) { - queue.add(new QueueItem(projectName, buildNumber)); - } - - @Override - public synchronized void add(String projectName, int buildNumber, String workspace) { - queue.add(new QueueItem(projectName, buildNumber, workspace)); - } - - private static class JsonConverter implements FileObjectQueue.Converter { - - @Override - public QueueItem from(byte[] bytes) throws IOException { - JSONObject json = (JSONObject) JSONSerializer.toJSON(IOUtils.toString(new ByteArrayInputStream(bytes))); - return objectFromJson(json); - } - - @Override - public void toStream(QueueItem item, OutputStream bytes) throws IOException { - JSONObject json = jsonFromObject(item); - OutputStreamWriter writer = new OutputStreamWriter(bytes); - writer.append(json.toString()); - writer.close(); - } - - private static QueueItem objectFromJson(JSONObject json) { - return json.containsKey("workspace") ? - new QueueItem( - json.getString("project"), - json.getInt("build"), - json.getInt("count"), - json.getString("workspace")) : - new QueueItem( - json.getString("project"), - json.getInt("build"), - json.getInt("count")); - } - - private static JSONObject jsonFromObject(QueueItem item) { - JSONObject json = new JSONObject(); - json.put("project", item.projectName); - json.put("build", item.buildNumber); - json.put("count", item.failCount); - json.put("workspace", item.workspace); - return json; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/CIJenkinsServicesImpl.java b/src/main/java/com/hp/application/automation/tools/octane/CIJenkinsServicesImpl.java deleted file mode 100644 index 75cf55d563..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/CIJenkinsServicesImpl.java +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane; - -import com.hp.application.automation.tools.model.OctaneServerSettingsModel; -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessor; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.configuration.CIProxyConfiguration; -import com.hp.octane.integrations.dto.configuration.OctaneConfiguration; -import com.hp.octane.integrations.dto.general.CIJobsList; -import com.hp.octane.integrations.dto.general.CIPluginInfo; -import com.hp.octane.integrations.dto.general.CIServerInfo; -import com.hp.octane.integrations.dto.general.CIServerTypes; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.BuildHistory; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.scm.SCMData; -import com.hp.octane.integrations.dto.snapshots.SnapshotNode; -import com.hp.octane.integrations.dto.tests.TestsResult; -import com.hp.octane.integrations.exceptions.ConfigurationException; -import com.hp.octane.integrations.exceptions.PermissionException; -import com.hp.octane.integrations.spi.CIPluginServices; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import com.hp.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; -import com.hp.application.automation.tools.octane.model.processors.projects.AbstractProjectProcessor; -import com.hp.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessors; -import hudson.ProxyConfiguration; -import hudson.model.*; -import hudson.security.ACL; -import jenkins.model.Jenkins; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.acegisecurity.AccessDeniedException; -import org.acegisecurity.context.SecurityContext; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.xml.bind.DatatypeConverter; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; - -public class CIJenkinsServicesImpl implements CIPluginServices { - private static final Logger logger = LogManager.getLogger(CIJenkinsServicesImpl.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @Override - public CIServerInfo getServerInfo() { - CIServerInfo result = dtoFactory.newDTO(CIServerInfo.class); - String serverUrl = Jenkins.getInstance().getRootUrl(); - if (serverUrl != null && serverUrl.endsWith("/")) { - serverUrl = serverUrl.substring(0, serverUrl.length() - 1); - } - OctaneServerSettingsModel model = ConfigurationService.getModel(); - result.setType(CIServerTypes.JENKINS) - .setVersion(Jenkins.VERSION) - .setUrl(serverUrl) - .setInstanceId(model.getIdentity()) - .setInstanceIdFrom(model.getIdentityFrom()) - .setSendingTime(System.currentTimeMillis()); - return result; - } - - @Override - public CIPluginInfo getPluginInfo() { - CIPluginInfo result = dtoFactory.newDTO(CIPluginInfo.class); - result.setVersion(ConfigurationService.getPluginVersion()); - return result; - } - - @Override - public File getAllowedOctaneStorage() { - return new File(Jenkins.getInstance().getRootDir(), "userContent"); - } - - @Override - public File getPredictiveOctanePath() { - return new File(Jenkins.getInstance().getRootDir(), "predictive"); - } - - @Override - public OctaneConfiguration getOctaneConfiguration() { - OctaneConfiguration result = null; - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - if (serverConfiguration.location != null && !serverConfiguration.location.isEmpty() && - serverConfiguration.sharedSpace != null && !serverConfiguration.sharedSpace.isEmpty()) { - result = dtoFactory.newDTO(OctaneConfiguration.class) - .setUrl(serverConfiguration.location) - .setSharedSpace(serverConfiguration.sharedSpace) - .setApiKey(serverConfiguration.username) - .setSecret(serverConfiguration.password.getPlainText()); - } - return result; - } - - @Override - public CIProxyConfiguration getProxyConfiguration(String targetHost) { - CIProxyConfiguration result = null; - ProxyConfiguration proxy = Jenkins.getInstance().proxy; - if (proxy != null) { - boolean noProxyHost = false; - for (Pattern pattern : proxy.getNoProxyHostPatterns()) { - if (pattern.matcher(targetHost).find()) { - noProxyHost = true; - break; - } - } - if (!noProxyHost) { - result = dtoFactory.newDTO(CIProxyConfiguration.class) - .setHost(proxy.name) - .setPort(proxy.port) - .setUsername(proxy.getUserName()) - .setPassword(proxy.getPassword()); - } - } - return result; - } - - @Override - public CIJobsList getJobsList(boolean includeParameters) { - SecurityContext securityContext = startImpersonation(); - CIJobsList result = dtoFactory.newDTO(CIJobsList.class); - PipelineNode tmpConfig; - TopLevelItem tmpItem; - List list = new ArrayList<>(); - try { - boolean hasReadPermission = Jenkins.getInstance().hasPermission(Item.READ); - if (!hasReadPermission) { - stopImpersonation(securityContext); - throw new PermissionException(403); - } - List itemNames = (List) Jenkins.getInstance().getTopLevelItemNames(); - for (String name : itemNames) { - tmpItem = Jenkins.getInstance().getItem(name); - if (tmpItem instanceof AbstractProject) { - AbstractProject abstractProject = (AbstractProject) tmpItem; - tmpConfig = dtoFactory.newDTO(PipelineNode.class) - .setJobCiId(JobProcessorFactory.getFlowProcessor(abstractProject).getJobCiId()) - .setName(name); - if (includeParameters) { - tmpConfig.setParameters(ParameterProcessors.getConfigs(abstractProject)); - } - list.add(tmpConfig); - } else if (tmpItem.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - Job tmpJob = (Job) tmpItem; - tmpConfig = dtoFactory.newDTO(PipelineNode.class) - .setJobCiId(JobProcessorFactory.getFlowProcessor(tmpJob).getJobCiId()) - .setName(name); - if (includeParameters) { - tmpConfig.setParameters(ParameterProcessors.getConfigs(tmpJob)); - } - list.add(tmpConfig); - } else if (tmpItem.getClass().getName().equals("com.cloudbees.hudson.plugins.folder.Folder")) { - for (Job tmpJob : tmpItem.getAllJobs()) { - tmpConfig = dtoFactory.newDTO(PipelineNode.class) - .setJobCiId(JobProcessorFactory.getFlowProcessor(tmpJob).getJobCiId()) - .setName(tmpJob.getName()); - if (includeParameters) { - tmpConfig.setParameters(ParameterProcessors.getConfigs(tmpJob)); - } - list.add(tmpConfig); - } - } else { - logger.info("item '" + name + "' is not of supported type"); - } - - } - result.setJobs(list.toArray(new PipelineNode[list.size()])); - stopImpersonation(securityContext); - } catch (AccessDeniedException e) { - stopImpersonation(securityContext); - throw new PermissionException(403); - } - return result; - } - - - @Override - public PipelineNode getPipeline(String rootJobCiId) { - PipelineNode result; - SecurityContext securityContext = startImpersonation(); - boolean hasRead = Jenkins.getInstance().hasPermission(Item.READ); - if (!hasRead) { - stopImpersonation(securityContext); - throw new PermissionException(403); - } - Job project = getJobByRefId(rootJobCiId); - if (project != null) { - result = ModelFactory.createStructureItem(project); - stopImpersonation(securityContext); - return result; - } else { - //todo: check error message(s) - logger.warn("Failed to get project from jobRefId: '" + rootJobCiId + "' check plugin user Job Read/Overall Read permissions / project name"); - stopImpersonation(securityContext); - throw new ConfigurationException(404); - } - } - - private SecurityContext startImpersonation() { - String user = ConfigurationService.getModel().getImpersonatedUser(); - SecurityContext originalContext = null; - if (user != null && !user.equalsIgnoreCase("")) { - User jenkinsUser = User.get(user, false); - if (jenkinsUser != null) { - originalContext = ACL.impersonate(jenkinsUser.impersonate()); - } else { - throw new PermissionException(401); - } - } else { - logger.info("No user set to impersonating to. Operations will be done using Anonymous user"); - } - return originalContext; - } - - private void stopImpersonation(SecurityContext originalContext) { - if (originalContext != null) { - ACL.impersonate(originalContext.getAuthentication()); - } else { - logger.warn("Could not roll back impersonation, originalContext is null "); - } - } - - @Override - public void runPipeline(String jobCiId, String originalBody) { - SecurityContext securityContext = startImpersonation(); - Job job = getJobByRefId(jobCiId); - if (job != null) { - boolean hasBuildPermission = job.hasPermission(Item.BUILD); - if (!hasBuildPermission) { - stopImpersonation(securityContext); - throw new PermissionException(403); - } - if (job instanceof AbstractProject || job.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - doRunImpl(job, originalBody); - } - stopImpersonation(securityContext); - } else { - stopImpersonation(securityContext); - throw new ConfigurationException(404); - } - } - - @Override - public SnapshotNode getSnapshotLatest(String jobCiId, boolean subTree) { - SecurityContext securityContext = startImpersonation(); - SnapshotNode result = null; - Job job = getJobByRefId(jobCiId); - if (job != null) { - Run run = job.getLastBuild(); - if (run != null) { - result = ModelFactory.createSnapshotItem(run, subTree); - } - } - stopImpersonation(securityContext); - return result; - } - - @Override - public SnapshotNode getSnapshotByNumber(String jobCiId, String buildCiId, boolean subTree) { - SecurityContext securityContext = startImpersonation(); - - SnapshotNode result = null; - Job job = getJobByRefId(jobCiId); - - Integer buildNumber = null; - try { - buildNumber = Integer.parseInt(buildCiId); - } catch (NumberFormatException nfe) { - logger.error("failed to parse build CI ID to build number, " + nfe.getMessage(), nfe); - } - if (job != null && buildNumber != null) { - Run build = job.getBuildByNumber(buildNumber); - if (build != null) { - result = ModelFactory.createSnapshotItem(build, subTree); - } - } - - stopImpersonation(securityContext); - return result; - } - - @Override - public BuildHistory getHistoryPipeline(String jobCiId, String originalBody) { - SecurityContext securityContext = startImpersonation(); - BuildHistory buildHistory = dtoFactory.newDTO(BuildHistory.class); - Job job = getJobByRefId(jobCiId); - AbstractProject project; - if (job instanceof AbstractProject) { - project = (AbstractProject) job; - SCMData scmData; - Set users; - SCMProcessor scmProcessor = SCMProcessors.getAppropriate(project.getScm().getClass().getName()); - - int numberOfBuilds = 5; - - //TODO : check if it works!! - if (originalBody != null && !originalBody.isEmpty()) { - JSONObject bodyJSON = JSONObject.fromObject(originalBody); - if (bodyJSON.has("numberOfBuilds")) { - numberOfBuilds = bodyJSON.getInt("numberOfBuilds"); - } - } - List result = project.getLastBuildsOverThreshold(numberOfBuilds, Result.ABORTED); // get last five build with result that better or equal failure - for (int i = 0; i < result.size(); i++) { - AbstractBuild build = (AbstractBuild) result.get(i); - scmData = null; - users = null; - if (build != null) { - if (scmProcessor != null) { - scmData = scmProcessor.getSCMData(build); - users = build.getCulprits(); - } - buildHistory.addBuild(build.getResult().toString(), String.valueOf(build.getNumber()), build.getTimestampString(), String.valueOf(build.getStartTimeInMillis()), String.valueOf(build.getDuration()), scmData, ModelFactory.createScmUsersList(users)); - } - } - AbstractBuild lastSuccessfulBuild = null; - AbstractBuild lastProjectBuild = project.getLastBuild(); - if (lastProjectBuild != null) { - lastSuccessfulBuild = (AbstractBuild) lastProjectBuild.getPreviousSuccessfulBuild(); - } - if (lastSuccessfulBuild != null) { - scmData = null; - users = null; - if (scmProcessor != null) { - scmData = scmProcessor.getSCMData(lastSuccessfulBuild); - users = lastSuccessfulBuild.getCulprits(); - } - buildHistory.addLastSuccesfullBuild(lastSuccessfulBuild.getResult().toString(), String.valueOf(lastSuccessfulBuild.getNumber()), lastSuccessfulBuild.getTimestampString(), String.valueOf(lastSuccessfulBuild.getStartTimeInMillis()), String.valueOf(lastSuccessfulBuild.getDuration()), scmData, ModelFactory.createScmUsersList(users)); - } - AbstractBuild lastBuild = project.getLastBuild(); - if (lastBuild != null) { - scmData = null; - users = null; - if (scmProcessor != null) { - scmData = scmProcessor.getSCMData(lastBuild); - users = lastBuild.getCulprits(); - } - - if (lastBuild.getResult() == null) { - buildHistory.addLastBuild("building", String.valueOf(lastBuild.getNumber()), lastBuild.getTimestampString(), String.valueOf(lastBuild.getStartTimeInMillis()), String.valueOf(lastBuild.getDuration()), scmData, ModelFactory.createScmUsersList(users)); - } else { - buildHistory.addLastBuild(lastBuild.getResult().toString(), String.valueOf(lastBuild.getNumber()), lastBuild.getTimestampString(), String.valueOf(lastBuild.getStartTimeInMillis()), String.valueOf(lastBuild.getDuration()), scmData, ModelFactory.createScmUsersList(users)); - } - } - stopImpersonation(securityContext); - } else { - logger.warn("non supported flow"); - } - return buildHistory; - } - - // TODO: implement - @Override - public TestsResult getTestsResult(String jobId, String buildNumber) { - return null; - } - - // TODO: the below flow should go via JobProcessor, once scheduleBuild will be implemented for all of them - private void doRunImpl(Job job, String originalBody) { - if (job instanceof AbstractProject) { - AbstractProject project = (AbstractProject) job; - int delay = project.getQuietPeriod(); - ParametersAction parametersAction = new ParametersAction(); - - if (originalBody != null && !originalBody.isEmpty()) { - JSONObject bodyJSON = JSONObject.fromObject(originalBody); - - // delay - if (bodyJSON.has("delay") && bodyJSON.get("delay") != null) { - delay = bodyJSON.getInt("delay"); - } - - // parameters - if (bodyJSON.has("parameters") && bodyJSON.get("parameters") != null) { - JSONArray paramsJSON = bodyJSON.getJSONArray("parameters"); - parametersAction = new ParametersAction(createParameters(project, paramsJSON)); - } - } - - project.scheduleBuild(delay, new Cause.RemoteCause(getOctaneConfiguration() == null ? "non available URL" : getOctaneConfiguration().getUrl(), "octane driven execution"), parametersAction); - } else if (job.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - AbstractProjectProcessor workFlowJobProcessor = JobProcessorFactory.getFlowProcessor(job); - workFlowJobProcessor.scheduleBuild(originalBody); - } - } - - private List createParameters(AbstractProject project, JSONArray paramsJSON) { - List result = new ArrayList<>(); - boolean parameterHandled; - ParameterValue tmpValue; - ParametersDefinitionProperty paramsDefProperty = (ParametersDefinitionProperty) project.getProperty(ParametersDefinitionProperty.class); - if (paramsDefProperty != null) { - for (ParameterDefinition paramDef : paramsDefProperty.getParameterDefinitions()) { - parameterHandled = false; - for (int i = 0; i < paramsJSON.size(); i++) { - JSONObject paramJSON = paramsJSON.getJSONObject(i); - if (paramJSON.has("name") && paramJSON.get("name") != null && paramJSON.get("name").equals(paramDef.getName())) { - tmpValue = null; - switch (CIParameterType.fromValue(paramJSON.getString("type"))) { - case FILE: - try { - FileItemFactory fif = new DiskFileItemFactory(); - FileItem fi = fif.createItem(paramJSON.getString("name"), "text/plain", false, paramJSON.getString("file")); - fi.getOutputStream().write(DatatypeConverter.parseBase64Binary(paramJSON.getString("value"))); - tmpValue = new FileParameterValue(paramJSON.getString("name"), fi); - } catch (IOException ioe) { - logger.warn("failed to process file parameter", ioe); - } - break; - case NUMBER: - tmpValue = new StringParameterValue(paramJSON.getString("name"), paramJSON.get("value").toString()); - break; - case STRING: - tmpValue = new StringParameterValue(paramJSON.getString("name"), paramJSON.getString("value")); - break; - case BOOLEAN: - tmpValue = new BooleanParameterValue(paramJSON.getString("name"), paramJSON.getBoolean("value")); - break; - case PASSWORD: - tmpValue = new PasswordParameterValue(paramJSON.getString("name"), paramJSON.getString("value")); - break; - default: - break; - } - if (tmpValue != null) { - result.add(tmpValue); - parameterHandled = true; - } - break; - } - } - if (!parameterHandled) { - if (paramDef instanceof FileParameterDefinition) { - FileItemFactory fif = new DiskFileItemFactory(); - FileItem fi = fif.createItem(paramDef.getName(), "text/plain", false, ""); - try { - fi.getOutputStream().write(new byte[0]); - } catch (IOException ioe) { - logger.error("failed to create default value for file parameter '" + paramDef.getName() + "'", ioe); - } - tmpValue = new FileParameterValue(paramDef.getName(), fi); - result.add(tmpValue); - } else { - result.add(paramDef.getDefaultParameterValue()); - } - } - } - } - return result; - } - - private Job getJobByRefId(String jobRefId) { - Job result = null; - if (jobRefId != null) { - try { - jobRefId = URLDecoder.decode(jobRefId, "UTF-8"); - TopLevelItem item = getTopLevelItem(jobRefId); - if (item != null && item instanceof Job) { - result = (Job) item; - } else if (jobRefId.contains("/") && item == null) { - String newJobRefId = jobRefId.substring(0, jobRefId.indexOf("/")); - item = getTopLevelItem(newJobRefId); - if (item != null) { - Collection allJobs = item.getAllJobs(); - for (Job job : allJobs) { - if (jobRefId.endsWith(job.getName())) { - result = job; - break; - } - } - } - } - } catch (UnsupportedEncodingException uee) { - logger.error("failed to decode job ref ID '" + jobRefId + "'", uee); - } - } - return result; - } - - private TopLevelItem getTopLevelItem(String jobRefId) { - TopLevelItem item; - try { - item = Jenkins.getInstance().getItem(jobRefId); - } catch (AccessDeniedException e) { - String user = ConfigurationService.getModel().getImpersonatedUser(); - if (user != null && !user.isEmpty()) { - throw new PermissionException(403); - } else { - throw new PermissionException(405); - } - } - return item; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/ResultQueue.java b/src/main/java/com/hp/application/automation/tools/octane/ResultQueue.java deleted file mode 100644 index 5c00d4d5b0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/ResultQueue.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane; - -import java.io.Serializable; - -@SuppressWarnings("squid:S2039") -public interface ResultQueue { - - ResultQueue.QueueItem peekFirst(); - - boolean failed(); - - void remove(); - - void add(String projectName, int buildNumber); - - void add(String projectName, int buildNumber, String workspace); - - class QueueItem implements Serializable { - private static final long serialVersionUID = 1; - - String projectName; - int buildNumber; - String workspace; - int failCount; - - public QueueItem(String projectName, int buildNumber) { - this(projectName, buildNumber, 0); - } - - public QueueItem(String projectName, int buildNumber, String workspace) { - this(projectName, buildNumber, 0); - this.workspace = workspace; - } - - QueueItem(String projectName, int buildNumber, int failCount) { - this.projectName = projectName; - this.buildNumber = buildNumber; - this.failCount = failCount; - } - - QueueItem(String projectName, int buildNumber, int failCount, String workspace) { - this.projectName = projectName; - this.buildNumber = buildNumber; - this.failCount = failCount; - this.workspace = workspace; - } - - public int incrementFailCount() { - return this.failCount++; - } - - public int getFailCount() { - return failCount; - } - - public String getProjectName() { - return projectName; - } - - public int getBuildNumber(){ - return buildNumber; - } - - public String getWorkspace() { - return workspace; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/BuildActions.java b/src/main/java/com/hp/application/automation/tools/octane/actions/BuildActions.java deleted file mode 100644 index 167c5970de..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/BuildActions.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.tests.TestApi; -import hudson.Extension; -import hudson.model.AbstractBuild; -import hudson.model.Action; -import hudson.model.Run; -import jenkins.model.RunAction2; -import jenkins.model.TransientActionFactory; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 12/08/14 - * Time: 10:45 - * To change this template use File | Settings | File Templates. - */ - -@Extension -public class BuildActions extends TransientActionFactory { - - public BuildActions(){} - - private JenkinsMqmRestClientFactory clientFactory; - - static final public class OctaneBuildActions implements RunAction2 { - private AbstractBuild build; - private JenkinsMqmRestClientFactory clientFactory; - - public OctaneBuildActions(AbstractBuild b, JenkinsMqmRestClientFactory clientFactory) { - build = b; - this.clientFactory = clientFactory; - } - - @Override - public void onAttached(Run run) { - } - @Override - public void onLoad(Run run) { - } - @Override - public String getIconFileName() { - return null; - } - @Override - public String getDisplayName() { - return null; - } - - @Override - public String getUrlName() { - return "nga"; - } - - public TestApi getTests() { - return new TestApi(build, clientFactory); - } - } - - @Override - public Class type() { - return AbstractBuild.class; - } - - @Override - @Nonnull - public Collection createFor(@Nonnull AbstractBuild build) { - ArrayList actions = new ArrayList<>(); - actions.add(new OctaneBuildActions(build, clientFactory)); - return actions; - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } - - /* - * To be used in tests only. - */ - public void _setMqmRestClientFactory(JenkinsMqmRestClientFactory clientFactory) { - this.clientFactory = clientFactory; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/PluginActions.java b/src/main/java/com/hp/application/automation/tools/octane/actions/PluginActions.java deleted file mode 100644 index fec8351d63..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/PluginActions.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import com.hp.octane.integrations.OctaneSDK; -import com.hp.octane.integrations.api.TasksProcessor; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.connectivity.HttpMethod; -import com.hp.octane.integrations.dto.connectivity.OctaneResultAbridged; -import com.hp.octane.integrations.dto.connectivity.OctaneTaskAbridged; -import com.hp.application.automation.tools.octane.configuration.ConfigApi; -import hudson.Extension; -import hudson.model.RootAction; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.Map; -import java.util.UUID; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 8/10/14 - * Time: 12:47 PM - * To change this template use File | Settings | File Templates. - */ - -@Extension -public class PluginActions implements RootAction { - private static final Logger logger = LogManager.getLogger(PluginActions.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - public String getIconFileName() { - return null; - } - - public String getDisplayName() { - return null; - } - - public String getUrlName() { - return "nga"; - } - - public ConfigApi getConfiguration() { - return new ConfigApi(); - } - - public void doDynamic(StaplerRequest req, StaplerResponse res) throws IOException, ServletException { - HttpMethod method = null; - if ("post".equals(req.getMethod().toLowerCase())) { - method = HttpMethod.POST; - } else if ("get".equals(req.getMethod().toLowerCase())) { - method = HttpMethod.GET; - } else if ("put".equals(req.getMethod().toLowerCase())) { - method = HttpMethod.PUT; - } else if ("delete".equals(req.getMethod().toLowerCase())) { - method = HttpMethod.DELETE; - } - if (method != null) { - OctaneTaskAbridged octaneTaskAbridged = dtoFactory.newDTO(OctaneTaskAbridged.class); - octaneTaskAbridged.setId(UUID.randomUUID().toString()); - octaneTaskAbridged.setMethod(method); - octaneTaskAbridged.setUrl(req.getRequestURIWithQueryString()); - octaneTaskAbridged.setBody(""); - TasksProcessor taskProcessor = OctaneSDK.getInstance().getTasksProcessor(); - OctaneResultAbridged result = taskProcessor.execute(octaneTaskAbridged); - - res.setStatus(result.getStatus()); - if (result.getBody() != null) { - res.getWriter().write(result.getBody()); - } - if (result.getHeaders() != null) { - for (Map.Entry header : result.getHeaders().entrySet()) { - res.setHeader(header.getKey(), header.getValue()); - } - } - } else { - res.setStatus(501); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameter.java b/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameter.java deleted file mode 100644 index 9d847ae71d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameter.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -/** - * Created by kashbi on 22/09/2016. - */ -public class UFTParameter { - private String argName; - private int argDirection; - private String argDefaultValue; - private String argType; - private int argIsExternal; - - public UFTParameter(){} - - public String getArgName() { - return argName; - } - - public void setArgName(String argName) { - this.argName = argName; - } - - public int getArgDirection() { - return argDirection; - } - - public void setArgDirection(int argDirection) { - this.argDirection = argDirection; - } - - public String getArgDefaultValue() { - return argDefaultValue; - } - - public void setArgDefaultValue(String argDefaultValue) { - this.argDefaultValue = argDefaultValue; - } - - public String getArgType() { - return argType; - } - - public void setArgType(String argType) { - this.argType = argType; - } - - public int getArgIsExternal() { - return argIsExternal; - } - - public void setArgIsExternal(int argIsExternal) { - this.argIsExternal = argIsExternal; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameterFactory.java b/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameterFactory.java deleted file mode 100644 index 01273e7c69..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTParameterFactory.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.poi.poifs.filesystem.*; -import org.apache.poi.util.StringUtil; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMFactory; -import org.jdom2.input.SAXBuilder; -import org.jdom2.input.sax.SAXHandlerFactory; -import org.jdom2.input.sax.XMLReaders; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -/** - * This class Converts UFT's Paramters info stored in Resource.mtr file into JSON string - */ -public class UFTParameterFactory { - private static POIFSFileSystem poiFS; - private static String xmlData = ""; - private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(UFTParameterFactory.class.getName()); - - - public static String convertResourceMtrAsJSON(InputStream resourceMtrInputStream) throws IOException { - - //TODO: Check is exists - poiFS = new POIFSFileSystem(resourceMtrInputStream); - DirectoryNode root = poiFS.getRoot(); - - for (Entry entry : root) { - String name = entry.getName(); - if (name.equals("ComponentInfo")) { - if (entry instanceof DirectoryEntry) { - System.out.println(entry); - } else if (entry instanceof DocumentEntry) { - byte[] content = new byte[((DocumentEntry) entry).getSize()]; - poiFS.createDocumentInputStream("ComponentInfo").read(content); - String fromUnicodeLE = StringUtil.getFromUnicodeLE(content); - xmlData = fromUnicodeLE.substring(fromUnicodeLE.indexOf('<')).replaceAll("\u0000", ""); -// System.out.println(xmlData); - } - } - } - try { - SAXBuilder saxBuilder = new SAXBuilder(XMLReaders.NONVALIDATING, (SAXHandlerFactory) null, (JDOMFactory) null); - Document document = null; - document = saxBuilder.build(new StringReader(xmlData)); - Element classElement = document.getRootElement(); - List studentList = classElement.getChildren(); - ObjectMapper mapper = new ObjectMapper(); - ArrayList uftParameters = new ArrayList(); - UFTParameter uftParameter = new UFTParameter(); - for (int temp = 0; temp < studentList.size(); temp++) { - Element tag = studentList.get(temp); - if ("ArgumentsCollection".equalsIgnoreCase(tag.getName())) { - List children = tag.getChildren(); - for (int i = 0; i < children.size(); i++) { - Element element = children.get(i); - List elements = element.getChildren(); - - for (int j = 0; j < elements.size(); j++) { - - Element element1 = elements.get(j); - switch (element1.getName()) { - case "ArgName": - uftParameter.setArgName(element1.getValue()); - break; - case "ArgDirection": - uftParameter.setArgDirection(Integer.parseInt(element1.getValue())); - break; - case "ArgDefaultValue": - uftParameter.setArgDefaultValue(element1.getValue()); - break; - case "ArgType": - uftParameter.setArgType(element1.getValue()); - break; - case "ArgIsExternal": - uftParameter.setArgIsExternal(Integer.parseInt(element1.getValue())); - break; - default: - logger.warning(String.format("Element name %s didn't match any case",element1.getName())); - break; - } - } - uftParameters.add(uftParameter); - } - return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(uftParameters); - } - } - } catch (Exception e) { - logger.severe(e.getMessage()); - } - return null; - } - - -} - - - diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java b/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java deleted file mode 100644 index 6c7785de5a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import com.hp.application.automation.tools.octane.actions.dto.AutomatedTests; -import com.hp.mqm.client.MqmRestClient; -import com.hp.application.automation.tools.octane.actions.dto.AutomatedTest; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.ExtensionList; -import hudson.FilePath; -import hudson.model.AbstractBuild; -import hudson.model.Action; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - - -public class UFTTestDetectionBuildAction implements Action { - private String message; - private AbstractBuild build; - private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(UFTTestDetectionBuildAction.class.getName()); - - @Override - public String getIconFileName() { - return "/plugin/testExample/img/build-goals.png"; - } - - @Override - public String getDisplayName() { - return "Test Example Build Page"; - } - - @Override - public String getUrlName() { - return "testExampleBA"; - } - - public String getMessage() { - return this.message; - } - - public int getBuildNumber() { - return this.build.number; - } - - public AbstractBuild getBuild() { - return build; - } - - private void findUFTTestsPath(List root, HashMap testData) throws IOException, InterruptedException { - for (FilePath path : root) { - if (path.isDirectory()) { - findUFTTestsPath(path.list(), testData); - } else { - if (path.getName().contains(".tsp")) { - String convertResourceMtrAsJSON = UFTParameterFactory.convertResourceMtrAsJSON(path.getParent().child("Action0").child("Resource.mtr").read()); - testData.put(path.getParent().getName(), convertResourceMtrAsJSON); - } - } - } - } - - private static T getExtension(Class clazz) { - ExtensionList items = Jenkins.getInstance().getExtensionList(clazz); - return items.get(0); - } - - private MqmRestClient createClient() { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - JenkinsMqmRestClientFactory clientFactory = getExtension(JenkinsMqmRestClientFactory.class); - MqmRestClient client = clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - return client; - } - - UFTTestDetectionBuildAction(final String message, final AbstractBuild build, String workspaceId) { - this.message = message; - this.build = build; - MqmRestClient client = createClient(); - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - try { - HashMap uftTestData = new HashMap<>(); - findUFTTestsPath(build.getWorkspace().list(), uftTestData); - ArrayList data = new ArrayList<>(); - AutomatedTests automatedTests = new AutomatedTests(); - - logger.info(uftTestData.toString()); - - Set keys = uftTestData.keySet(); - String[] uftTestNames = keys.toArray(new String[keys.size()]); - for (int i = 0; i < uftTestNames.length; i++) { - String uftTestName = uftTestNames[i]; - AutomatedTest automatedTest = new AutomatedTest(); - // todo: To enable once decided, need to get the ID dynamicly from server. -// automatedTest.setFramework(new TestFramework()); -// automatedTest.setTesting_tool_type(new com.hp.application.automation.tools.jenkins.actions.dto.TestingToolType()); - automatedTest.setName(uftTestName); - data.add(automatedTest); - } - automatedTests.setData(data); - String uftTestJson = JSONObject.fromObject(automatedTests).toString(); - String serverURL = getServerURL(workspaceId, serverConfiguration.sharedSpace, serverConfiguration.location); - JSONObject jsonObject = client.postTest(uftTestJson, uftTestData, serverURL); - for (int i = 0; i < jsonObject.getInt("total_count"); i++) { - String testID = ((JSONObject) jsonObject.getJSONArray("data").get(i)).getString("id"); - String testName = ((JSONObject) jsonObject.getJSONArray("data").get(i)).getString("name"); - try { - String parametersJSON = uftTestData.get(testName); - if (parametersJSON != null) { - client.attachUFTParametersToTest(testID, parametersJSON, serverURL); - } - - } catch (IOException e) { - logger.severe(e.getMessage()); - } - } - } catch (InterruptedException | IOException e) { - logger.severe(e.getMessage()); - } - } - - private String getServerURL(String workspaceId, String sharedspaceId, String location) { - return location + "/api/shared_spaces/" + sharedspaceId + "/workspaces/" + workspaceId; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java b/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java deleted file mode 100644 index 97d98579fa..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.model.PagedList; -import com.hp.mqm.client.model.Workspace; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import hudson.ExtensionList; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Publisher; -import hudson.tasks.Recorder; -import hudson.util.FormValidation; -import hudson.util.ListBoxModel; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.List; - -public class UFTTestDetectionPublisher extends Recorder { - - private final String workspaceName; - - public String getWorkspaceName() { - return workspaceName; - } - - // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" - @DataBoundConstructor - public UFTTestDetectionPublisher(String workspaceName) { - this.workspaceName = workspaceName; - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { - // This is where you 'build' the project. - // Since this is a dummy, we just say 'hello world' and call that a build. - - // This also shows how you can consult the global configuration of the builder - String message = ""; - - UFTTestDetectionBuildAction buildAction = new UFTTestDetectionBuildAction(message, build, getWorkspaceName()); - build.addAction(buildAction); - - return true; - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - private static T getExtension(Class clazz) { - ExtensionList items = Jenkins.getInstance().getExtensionList(clazz); - return items.get(0); - } - - @Extension // This indicates to Jenkins that this is an implementation of an extension point. - public static final class DescriptorImpl extends BuildStepDescriptor { - private MqmRestClient createClient() { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - JenkinsMqmRestClientFactory clientFactory = getExtension(JenkinsMqmRestClientFactory.class); - return clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - } - - private String workspace; - - public DescriptorImpl() { - load(); - } - - /** - * This method determines the values of the album drop-down list box. - * - * @return ListBoxModel result - */ - public ListBoxModel doFillWorkspaceNameItems() { - ListBoxModel m = new ListBoxModel(); - PagedList workspacePagedList = createClient().queryWorkspaces("", 0, 200); - List items = workspacePagedList.getItems(); - for (Workspace workspace : items) { - m.add(workspace.getName(), String.valueOf(workspace.getId())); - } - return m; - } - - public FormValidation doCheckWorkspaceName(@QueryParameter String value) throws IOException, ServletException { - if (value == null || value.length() == 0) { - return FormValidation.error("Please select workspace"); - } else { - return FormValidation.ok(); - } - } - - public boolean isApplicable(Class aClass) { - // Indicates that this builder can be used with all kinds of project types - return true; - } - - public String getDisplayName() { - return "HP Octane UFT Tests Scanner"; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - // To persist global configuration information, - // set that to properties and call save(). - workspace = formData.getString("useFrench"); - // ^Can also use req.bindJSON(this, formData); - // (easier when there are many fields; need set* methods for this, like setUseFrench) - save(); - return super.configure(req, formData); - } - - public String getWorkspace() { - return workspace; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java b/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java deleted file mode 100644 index fedbc7113c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.cucumber; - -import hudson.FilePath; -import hudson.Util; -import hudson.model.BuildListener; -import hudson.remoting.VirtualChannel; -import jenkins.MasterToSlaveFileCallable; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.types.FileSet; -import com.hp.application.automation.tools.octane.Messages; - -import java.io.*; -import java.nio.file.Files; - -/** - * Created by franksha on 22/03/2016. - */ -public class CucumberResultsService { - - public static final String GHERKIN_NGA_RESULTS_XML = "OctaneGherkinResults.xml"; - public static final String GHERKIN_NGA_RESULTS = "OctaneGherkinResults"; - public static final String DEFAULT_GLOB = "**/" + GHERKIN_NGA_RESULTS_XML; - - private static BuildListener listener; - - public static String getGherkinResultFileName(int index) { - return GHERKIN_NGA_RESULTS + index + ".xml"; - } - - public static String[] getCucumberResultFiles(final FilePath workspace, String glob) throws IOException, InterruptedException { - if (glob.isEmpty() || glob == null) { - glob = DEFAULT_GLOB; - log(Messages.CucumberResultsActionEmptyConfiguration(), glob); - } - - log("Looking for files that match the pattern %s in root directory %s", glob, workspace.getName()); - return workspace.act(new ResultFilesCallable(glob)); - } - - public static void copyResultFile(File resultFile, File destinationFolder, final FilePath workspace) throws IOException, InterruptedException { - File existingReportFile; - int existingResultIndex = -1; - - log("Copying %s to %s", resultFile.getPath(), destinationFolder.getPath()); - - do { - existingReportFile = new File(destinationFolder, getGherkinResultFileName(++existingResultIndex)); - } while (existingReportFile.exists()); - log("New file name on destination will be %s", existingReportFile.getPath()); - - byte[] content = workspace.act(new FileContentCallable(resultFile)); - log("Got result file content"); - - validateContent(content); - - File target = existingReportFile; - try (FileOutputStream os = new FileOutputStream(target)) { - os.write(content); - } - log("Result file copied to %s", target.getPath()); - } - - private static void validateContent(byte[] content) { - String contentStr = new String(content, 0, content.length > 2000 ? 2000 : content.length); - //Heuristic validation. we don't check the whole file structure here - we should be quick. - if(!contentStr.contains(" { - private final String glob; - - private ResultFilesCallable(String glob) { - this.glob = glob; - } - - @Override - public String[] invoke(File rootDir, VirtualChannel channel) throws IOException { - FileSet fs = Util.createFileSet(rootDir, glob); - DirectoryScanner ds = fs.getDirectoryScanner(); - String[] files = ds.getIncludedFiles(); - return files; - } - } - - private static final class FileContentCallable extends MasterToSlaveFileCallable { - private final File file; - - private FileContentCallable(File file) { - this.file = file; - } - - @Override - public byte[] invoke(File rootDir, VirtualChannel channel) throws IOException { - return Files.readAllBytes(file.toPath()); - } - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java b/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java deleted file mode 100644 index 52c441d0e0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.cucumber; - -import com.hp.application.automation.tools.octane.Messages; -import hudson.model.AbstractBuild; -import hudson.model.Action; -import hudson.model.BuildListener; -import hudson.model.Result; - -import java.io.File; - -/** - * Created by franksha on 07/12/2016. - */ -public class CucumberTestResultsAction implements Action { - private final String glob; - private final AbstractBuild build; - - CucumberTestResultsAction(AbstractBuild build, String glob, BuildListener listener) { - this.build = build; - this.glob = glob; - CucumberResultsService.setListener(listener); - } - - public boolean copyResultsToBuildFolder() { - try { - CucumberResultsService.log(Messages.CucumberResultsActionCollecting()); - String[] files = CucumberResultsService.getCucumberResultFiles(build.getWorkspace(), glob); - boolean found = files.length > 0; - - for (String fileName : files) { - File resultFile = new File(build.getWorkspace().child(fileName).toURI()); - CucumberResultsService.copyResultFile(resultFile, build.getRootDir(), build.getWorkspace()); - } - - if (!found && build.getResult() != Result.FAILURE) { - // most likely a configuration error in the job - e.g. false pattern to match the cucumber result files - CucumberResultsService.log(Messages.CucumberResultsActionNotFound()); - } // else , if results weren't found but build result is failure - most likely a build failed before us. don't report confusing error message. - - return found; - - } catch (Exception e) { - CucumberResultsService.log(Messages.CucumberResultsActionError(), e.toString()); - return false; - } - } - - @Override - public String getIconFileName() { - return null; - } - - @Override - public String getDisplayName() { - return null; - } - - @Override - public String getUrlName() { - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java b/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java deleted file mode 100644 index 8802639f7b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.cucumber; - -import com.hp.application.automation.tools.octane.Messages; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Publisher; -import hudson.tasks.Recorder; -import hudson.util.FormValidation; -import org.kohsuke.stapler.AncestorInPath; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import javax.servlet.ServletException; -import java.io.IOException; - -/** - * Created by franksha on 07/12/2016. - */ -public class CucumberTestResultsActionPublisher extends Recorder { - - private final String glob; - - @Override - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - @DataBoundConstructor - public CucumberTestResultsActionPublisher(String cucumberResultsGlob) { - this.glob = cucumberResultsGlob; - } - - public String getCucumberResultsGlob() { - return glob; - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { - CucumberTestResultsAction action = new CucumberTestResultsAction(build, glob, listener); - build.addAction(action); - boolean resultsFound = action.copyResultsToBuildFolder(); - return resultsFound; - } - - @Override - public CucumberTestResultsActionPublisher.Descriptor getDescriptor() { - return (CucumberTestResultsActionPublisher.Descriptor) super.getDescriptor(); - } - - @Extension - public static final class Descriptor extends BuildStepDescriptor { - - public boolean isApplicable(Class aClass) { - return true; - } - - public String getDisplayName() { - return Messages.CucumberReporterName(); - } - - public FormValidation doCheckCucumberResultsGlob(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException, ServletException { - if (value == null || value.isEmpty()) { - return FormValidation.warning(Messages.CucumberResultsActionEmptyConfigurationWarning(), CucumberResultsService.DEFAULT_GLOB); - } else if (project == null) { - return FormValidation.ok(); - } - return FilePath.validateFileMask(project.getSomeWorkspace(), value); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTest.java b/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTest.java deleted file mode 100644 index d6e5985272..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.dto; - -/** - * Created by kashbi on 25/09/2016. - */ -public class AutomatedTest { - private String type = "test"; - private String subtype = "test_automated"; - private com.hp.application.automation.tools.octane.actions.dto.TestingToolType testing_tool_type; - private TestFramework framework; - private String name; - - public AutomatedTest(){} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getSubtype() { - return subtype; - } - - public void setSubtype(String subtype) { - this.subtype = subtype; - } - - public TestingToolType getTestingToolType() { - return testing_tool_type; - } - - public void setTesting_tool_type(TestingToolType testing_tool_type) { - this.testing_tool_type = testing_tool_type; - } - - public TestFramework getFramework() { - return framework; - } - - public void setFramework(TestFramework framework) { - this.framework = framework; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTests.java b/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTests.java deleted file mode 100644 index 8a2b4c87df..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/AutomatedTests.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hp.application.automation.tools.octane.actions.dto; - -import java.util.ArrayList; - -/** - * Created by kashbi on 25/09/2016. - */ -public class AutomatedTests { - private ArrayList data=new ArrayList<>(); - - public ArrayList getData() { - return data; - } - - public void setData(ArrayList data) { - this.data = data; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestFramework.java b/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestFramework.java deleted file mode 100644 index 1e6e70bc04..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestFramework.java +++ /dev/null @@ -1,71 +0,0 @@ -/* -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.dto; - -/** - * Created by kashbi on 25/09/2016. - */ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109"}) -public class TestFramework { - private String type = "list_node"; - private String logical_name = "list_node.testing_tool_type.uft"; - private String name = "UFT"; - private Integer index = 3; - private Integer id = 1055; - - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getLogical_name() { - return logical_name; - } - - public void setLogical_name(String logical_name) { - this.logical_name = logical_name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getIndex() { - return index; - } - - public void setIndex(Integer index) { - this.index = index; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestingToolType.java b/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestingToolType.java deleted file mode 100644 index 33d3e862fa..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/actions/dto/TestingToolType.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.dto; - -/** - * Created by kashbi on 25/09/2016. - */ -@SuppressWarnings("squid:S109") -public class TestingToolType { - private String type = "list_node"; - private String logical_name = "list_node.testing_tool_type.uft"; - private String name = "UFT"; - private Integer index = 4; - private Integer id = 1075; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getIndex() { - return index; - } - - public void setIndex(Integer index) { - this.index = index; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgeClient.java b/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgeClient.java deleted file mode 100644 index 1b54da166b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgeClient.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.bridge; - -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.AuthenticationException; -import com.hp.mqm.client.exception.ServerException; -import com.hp.mqm.client.exception.TemporarilyUnavailableException; -import com.hp.octane.integrations.OctaneSDK; -import com.hp.octane.integrations.spi.CIPluginServices; -import com.hp.octane.integrations.api.TasksProcessor; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.connectivity.OctaneResultAbridged; -import com.hp.octane.integrations.dto.connectivity.OctaneTaskAbridged; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.stapler.export.Exported; - -import javax.annotation.Nonnull; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -public class BridgeClient { - private static final Logger logger = LogManager.getLogger(BridgeClient.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - private static String serverInstanceId; - private ExecutorService connectivityExecutors = Executors.newFixedThreadPool(5, new AbridgedConnectivityExecutorsFactory()); - private ExecutorService taskProcessingExecutors = Executors.newFixedThreadPool(30, new AbridgedTasksExecutorsFactory()); - volatile private boolean isConnected = false; - volatile private boolean shuttingDown = false; - - private ServerConfiguration mqmConfig; - private JenkinsMqmRestClientFactory restClientFactory; - - public BridgeClient(ServerConfiguration mqmConfig, JenkinsMqmRestClientFactory clientFactory, String serverIdentity) { - this.serverInstanceId = serverIdentity; - this.mqmConfig = new ServerConfiguration(mqmConfig.location, mqmConfig.sharedSpace, mqmConfig.username, mqmConfig.password, mqmConfig.impersonatedUser); - restClientFactory = clientFactory; - connect(); - logger.info("client initialized for '" + this.mqmConfig.location + "'; SP: " + this.mqmConfig.sharedSpace + "; access key: " + this.mqmConfig.username); - } - - public void update(ServerConfiguration newConfig, String serverIdentity) { - this.serverInstanceId = serverIdentity; - mqmConfig = new ServerConfiguration(newConfig.location, newConfig.sharedSpace, newConfig.username, newConfig.password, newConfig.impersonatedUser); - logger.info("client updated to '" + mqmConfig.location + "'; SP: " + mqmConfig.sharedSpace + "; access key: " + newConfig.username); - restClientFactory.updateMqmRestClient(mqmConfig.location, mqmConfig.sharedSpace, mqmConfig.username, mqmConfig.password); - connect(); - } - - private void connect() { - if (!shuttingDown && !isConnected) { - isConnected = true; - connectivityExecutors.execute(new Runnable() { - @Override - public void run() { - String tasksJSON; - CIPluginServices pluginServices = OctaneSDK.getInstance().getPluginServices(); - try { - MqmRestClient restClient = restClientFactory.obtain(mqmConfig.location, mqmConfig.sharedSpace, mqmConfig.username, mqmConfig.password); - tasksJSON = restClient.getAbridgedTasks( - serverInstanceId, - pluginServices.getServerInfo().getType().value(), - pluginServices.getServerInfo().getUrl(), - OctaneSDK.API_VERSION, - OctaneSDK.SDK_VERSION); - isConnected = false; - connect(); - if (tasksJSON != null && !tasksJSON.isEmpty()) { - dispatchTasks(tasksJSON); - } - } catch (AuthenticationException ae) { - isConnected = false; - logger.error("connection to MQM Server temporary failed: authentication error", ae); - try { - Thread.sleep(20000); - } catch (InterruptedException ie) { - logger.info("interrupted while breathing on temporary exception, continue to re-connect..."); - } - connect(); - } catch (TemporarilyUnavailableException tue) { - isConnected = false; - logger.error("connection to MQM Server temporary failed: resource not available", tue); - try { - Thread.sleep(20000); - } catch (InterruptedException ie) { - logger.info("interrupted while breathing on temporary exception, continue to re-connect..."); - } - connect(); - } catch (ServerException se) { - isConnected = false; - logger.error("connection to MQM Server temporary failed: " + se.getMessage(), se); - try { - Thread.sleep(10000); - } catch (InterruptedException ie) { - logger.info("interrupted while breathing on temporary exception, continue to re-connect..."); - } - connect(); - } catch (Exception e) { - isConnected = false; - logger.error("connection to MQM Server temporary failed: " + e.getMessage(), e); - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - logger.info("interrupted while breathing on temporary exception, continue to re-connect..."); - } - connect(); - } - } - }); - } else if (shuttingDown) { - logger.info("bridge client stopped"); - } - } - - void dispose() { - // TODO: disconnect current connection once async connectivity is possible - shuttingDown = true; - } - - private void dispatchTasks(String tasksJSON) { - try { - OctaneTaskAbridged[] tasks = dtoFactory.dtoCollectionFromJson(tasksJSON, OctaneTaskAbridged[].class); - - logger.info("received " + tasks.length + " task(s)"); - for (final OctaneTaskAbridged task : tasks) { - taskProcessingExecutors.execute(new Runnable() { - @Override - public void run() { - TasksProcessor TasksProcessor = OctaneSDK.getInstance().getTasksProcessor(); - OctaneResultAbridged result = TasksProcessor.execute(task); - MqmRestClient restClient = restClientFactory.obtain( - mqmConfig.location, - mqmConfig.sharedSpace, - mqmConfig.username, - mqmConfig.password); - int submitStatus = restClient.putAbridgedResult( - serverInstanceId, - result.getId(), - dtoFactory.dtoToJson(result)); - logger.info("result for task '" + result.getId() + "' submitted with status " + submitStatus); - } - }); - } - } catch (Exception e) { - logger.error("failed to process tasks: " + e.getMessage(), e); - } - } - - @Exported(inline = true) - public String getLocation() { - return mqmConfig.location; - } - - @Exported(inline = true) - public String getSharedSpace() { - return mqmConfig.sharedSpace; - } - - @Exported(inline = true) - public String getUsername() { - return mqmConfig.username; - } - - private static final class AbridgedConnectivityExecutorsFactory implements ThreadFactory { - - @Override - public Thread newThread(@Nonnull Runnable runnable) { - Thread result = new Thread(runnable); - result.setName("AbridgedConnectivityThread-" + result.getId()); - result.setDaemon(true); - return result; - } - } - - private static final class AbridgedTasksExecutorsFactory implements ThreadFactory { - - @Override - public Thread newThread(@Nonnull Runnable runnable) { - Thread result = new Thread(runnable); - result.setName("AbridgedTasksExecutorsFactory-" + result.getId()); - result.setDaemon(true); - return result; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgesService.java b/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgesService.java deleted file mode 100644 index 78c57e0721..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/bridge/BridgesService.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.bridge; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.configuration.ConfigurationListener; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.List; - -/** - * Created by gullery on 05/08/2015. - *

- * Bridge Service meant to provide an abridged connectivity functionality - * The only APIs to be exposed is the basic management of abridged clients - */ - -@Extension -public class BridgesService implements ConfigurationListener { - private static final Logger logger = LogManager.getLogger(BridgesService.class); - - private static BridgesService extensionInstance; - private JenkinsMqmRestClientFactory clientFactory; - private BridgeClient bridgeClient; - - public static BridgesService getExtensionInstance() { - if (extensionInstance == null) { - List extensions = Jenkins.getInstance().getExtensionList(BridgesService.class); - if (extensions.isEmpty()) { - throw new RuntimeException("bridge service was not initialized properly"); - } else if (extensions.size() > 1) { - throw new RuntimeException("bridge service expected to be singleton, found " + extensions.size() + " instances"); - } else { - extensionInstance = extensions.get(0); - } - } - return extensionInstance; - } - - public void updateBridge(ServerConfiguration conf, String serverIdentity) { - if (conf.isValid()) { - if (bridgeClient != null) { - bridgeClient.update(conf, serverIdentity); - } else { - bridgeClient = new BridgeClient(conf, clientFactory, serverIdentity); - } - } else { - if (bridgeClient != null) { - logger.info("empty / non-valid configuration submitted, disposing bridge client"); - bridgeClient.dispose(); - bridgeClient = null; - } - } - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public void onChanged(ServerConfiguration conf, ServerConfiguration oldConf) { - updateBridge(conf, ConfigurationService.getModel().getIdentity()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/BdiConfigurationFetcher.java b/src/main/java/com/hp/application/automation/tools/octane/buildLogs/BdiConfigurationFetcher.java deleted file mode 100644 index bd7e40ecc2..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/BdiConfigurationFetcher.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.buildLogs; - -import com.google.inject.Inject; -import com.hp.mqm.client.MqmRestClient; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.configuration.BdiConfiguration; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import com.hp.application.automation.tools.octane.tests.AbstractSafeLoggingAsyncPeriodWork; -import hudson.Extension; -import hudson.model.TaskListener; -import hudson.util.TimeUnit2; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; - -/** - * Created by benmeior on 12/21/2016. - */ -@Extension -public class BdiConfigurationFetcher extends AbstractSafeLoggingAsyncPeriodWork { - - private static Logger logger = LogManager.getLogger(BdiConfigurationFetcher.class); - - private JenkinsMqmRestClientFactory clientFactory; - - private static BdiConfiguration bdiConfiguration; - - private boolean shouldFetchBdiConfiguration; - - public BdiConfigurationFetcher() { - super("BDI configuration fetcher"); - shouldFetchBdiConfiguration = true; - } - - public synchronized BdiConfiguration obtain() { - if (shouldFetchBdiConfiguration && bdiConfiguration == null) { - fetchBdiConfiguration(); - } - return bdiConfiguration; - } - - public void refresh() { - fetchBdiConfiguration(); - } - - private void fetchBdiConfiguration() { - try { - shouldFetchBdiConfiguration = false; - MqmRestClient mqmRestClient = createMqmRestClient(); - if (mqmRestClient == null) { - logger.info("Octane configuration is not valid"); - bdiConfiguration = null; - return; - } - bdiConfiguration = BdiConfiguration.fromJSON(mqmRestClient.getBdiConfiguration()); - - String loggingMessage = bdiConfiguration == null ? "BDI is not configured in Octane." : "Fetched BDI configuration from Octane. Address: " + bdiConfiguration.getHost() + ", Port: " + bdiConfiguration.getPort(); - logger.info(loggingMessage); - } catch (Exception e) { - logger.error("Failed to fetch BDI configuration from Octane", e); - } - } - - private MqmRestClient createMqmRestClient() { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - if (configuration.isValid()) { - return clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - } - return null; - } - - @Override - protected void doExecute(TaskListener listener) throws IOException, InterruptedException { - fetchBdiConfiguration(); - } - - @Override - public long getRecurrencePeriod() { - return TimeUnit2.DAYS.toMillis(1); - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogAbstractResultQueue.java b/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogAbstractResultQueue.java deleted file mode 100644 index ad224ca7f8..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogAbstractResultQueue.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.buildLogs; - -import com.hp.application.automation.tools.octane.AbstractResultQueueImpl; -import jenkins.model.Jenkins; - -import java.io.File; -import java.io.IOException; - -/** - * Created by benmeior on 11/21/2016. - */ -public class LogAbstractResultQueue extends AbstractResultQueueImpl { - - public LogAbstractResultQueue() throws IOException { - File queueFile = new File(Jenkins.getInstance().getRootDir(), "octane-log-result-queue.dat"); - init(queueFile); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogDispatcher.java b/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogDispatcher.java deleted file mode 100644 index d1f843f74d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/LogDispatcher.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.buildLogs; - -import com.google.inject.Inject; -import com.hp.indi.bdi.client.BdiClient; -import com.hp.indi.bdi.client.BdiClientFactory; -import com.hp.application.automation.tools.octane.ResultQueue; -import com.hp.application.automation.tools.octane.client.RetryModel; -import com.hp.application.automation.tools.octane.configuration.BdiConfiguration; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.tests.AbstractSafeLoggingAsyncPeriodWork; -import hudson.Extension; -import hudson.ProxyConfiguration; -import hudson.model.Job; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.util.TimeUnit2; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; - -/** - * Created by benmeior on 11/20/2016. - */ -@Extension -public class LogDispatcher extends AbstractSafeLoggingAsyncPeriodWork { - private static final String BDI_PRODUCT = "octane"; - private static Logger logger = LogManager.getLogger(LogDispatcher.class); - - @Inject - private RetryModel retryModel; - - @Inject - private BdiConfigurationFetcher bdiConfigurationFetcher; - - private ResultQueue logsQueue; - - public LogDispatcher() { - super("BDI log dispatcher"); - } - - @Override - protected void doExecute(TaskListener listener) throws IOException, InterruptedException { - if (logsQueue.peekFirst() == null) { - return; - } - if (retryModel.isQuietPeriod()) { - logger.info("There are pending logs, but we are in quiet period"); - return; - } - manageLogsQueue(); - } - - private void manageLogsQueue() { - BdiConfiguration configuration = bdiConfigurationFetcher.obtain(); - if (configuration == null || !configuration.isFullyConfigured()) { - logger.error("Could not send logs. BDI is not configured"); - return; - } - - BdiClient client = BdiClientFactory.getBdiClient(configuration.getHost(), Integer.parseInt(configuration.getPort())); - - // Configure proxy if needed - ProxyConfiguration proxy = Jenkins.getInstance().proxy; - if (proxy != null) { - client.setProxy(proxy.name, proxy.port); - } - - String response; - ResultQueue.QueueItem item; - while ((item = logsQueue.peekFirst()) != null) { - Run build = getBuildFromQueueItem(item); - if (build == null) { - logsQueue.remove(); - continue; - } - try { - client.post("consolelog",BDI_PRODUCT,Long.valueOf(configuration.getTenantId()), - item.getWorkspace(),buildDataId(build),build.getLogFile()); - - logger.info(String.format("Successfully sent log of build [%s#%s]"),item.getProjectName() ,item.getBuildNumber()); - - logsQueue.remove(); - } catch (Exception e) { - logger.error(String.format("Could not send log of build [%s#%s] to bdi.", item.getProjectName(), item.getBuildNumber()), e); - if (!logsQueue.failed()) { - logger.warn("Maximum number of attempts reached, operation will not be re-attempted for this build"); - } - } - } - } - - private Run getBuildFromQueueItem(ResultQueue.QueueItem item) { - Job project = (Job) Jenkins.getInstance().getItemByFullName(item.getProjectName()); - if (project == null) { - logger.warn("Project [" + item.getProjectName() + "] no longer exists, pending logs can't be submitted"); - return null; - } - - Run build = project.getBuildByNumber(item.getBuildNumber()); - if (build == null) { - logger.warn("Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] no longer exists, pending logs can't be submitted"); - return null; - } - return build; - } - - private String buildDataId(Run build) { - String ciServerId = ConfigurationService.getModel().getIdentity(); - String ciBuildId = String.valueOf(build.getNumber()); - String jobName = build.getParent().getName(); - - return String.format("%s-%s-%s", ciServerId, ciBuildId, jobName.replaceAll(" ", "")); - } - - @Override - public long getRecurrencePeriod() { - String value = System.getProperty("BDI.LogDispatcher.Period"); // let's us config the recurrence period. default is 10 seconds. - if (!StringUtils.isEmpty(value)) { - return Long.valueOf(value); - } - return TimeUnit2.SECONDS.toMillis(10); - } - - void enqueueLog(String projectName, int buildNumber, String workspace) { - logsQueue.add(projectName, buildNumber, workspace); - } - - @Inject - public void setLogResultQueue(LogAbstractResultQueue queue) { - this.logsQueue = queue; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/RunListenerForLogs.java b/src/main/java/com/hp/application/automation/tools/octane/buildLogs/RunListenerForLogs.java deleted file mode 100644 index 6ad3ebae06..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/buildLogs/RunListenerForLogs.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.buildLogs; - -import com.google.inject.Inject; -import com.hp.mqm.client.MqmRestClient; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.configuration.BdiConfiguration; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import hudson.model.AbstractBuild; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.model.listeners.RunListener; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nonnull; -import java.util.List; - -/** - * Created by benmeior on 11/16/2016. - */ -@Extension -public class RunListenerForLogs extends RunListener { - public RunListenerForLogs(){} - - private static Logger logger = LogManager.getLogger(RunListenerForLogs.class); - - private JenkinsMqmRestClientFactory clientFactory; - - @Inject - private LogDispatcher logDispatcher; - - @Inject - private BdiConfigurationFetcher bdiConfigurationFetcher; - - @Override - public void onCompleted(Run r, @Nonnull TaskListener listener) { - BdiConfiguration bdiConfiguration = bdiConfigurationFetcher.obtain(); - if (bdiConfiguration == null || !bdiConfiguration.isFullyConfigured()) { - logger.debug("BDI is not configured in Octane"); - return; - } - - if (!(r instanceof AbstractBuild)) { - return; - } - - AbstractBuild build = (AbstractBuild) r; - - try { - MqmRestClient mqmRestClient = createMqmRestClient(); - if (mqmRestClient == null) { - logger.warn("Octane configuration is not valid"); - return; - } - - List workspaces = mqmRestClient.getJobWorkspaceId(ConfigurationService.getModel().getIdentity(), build.getParent().getName()); - if (workspaces.isEmpty()) { - logger.info(String.format("Job '%s' is not part of an Octane pipeline in any workspace, so its log will not be sent.", build.getParent().getName())); - } else { - for (String workspace : workspaces) { - logger.info(String.format("Enqueued job %s of workspace %s", build.getParent().getName(), workspace)); - logDispatcher.enqueueLog(build.getProject().getName(), build.getNumber(), workspace); - } - } - } catch (Exception e) { - logger.error(String.format("Could not enqueue log for job %s", build.getParent().getName())); - } - } - - private MqmRestClient createMqmRestClient() { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - if (configuration.isValid()) { - return clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - } - return null; - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/client/EventPublisher.java b/src/main/java/com/hp/application/automation/tools/octane/client/EventPublisher.java deleted file mode 100644 index 220935140e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/client/EventPublisher.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -public interface EventPublisher { - - boolean isSuspended(); - - void resume(); - -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsInsightEventPublisher.java b/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsInsightEventPublisher.java deleted file mode 100644 index 4a8e582607..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsInsightEventPublisher.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -import com.hp.application.automation.tools.octane.events.EventsClient; -import com.hp.application.automation.tools.octane.events.EventsService; -import hudson.Extension; - -@Extension -public class JenkinsInsightEventPublisher implements EventPublisher { - - @Override - public boolean isSuspended() { - EventsClient client = EventsService.getExtensionInstance().getClient(); - return client == null || client.isSuspended(); - } - - @Override - public void resume() { - EventsService.getExtensionInstance().wakeUpClient(); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactory.java b/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactory.java deleted file mode 100644 index ec61860859..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -import com.hp.mqm.client.MqmRestClient; -import hudson.util.Secret; - -public interface JenkinsMqmRestClientFactory { - - MqmRestClient obtain(String location, String sharedSpace, String username, Secret password); - - MqmRestClient obtainTemp(String location, String sharedSpace, String username, Secret password); - - void updateMqmRestClient(String location, String sharedSpace, String username, Secret password); - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactoryImpl.java b/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactoryImpl.java deleted file mode 100644 index b65c2d6f18..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/client/JenkinsMqmRestClientFactoryImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -import com.hp.mqm.client.MqmConnectionConfig; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.MqmRestClientImpl; -import com.hp.mqm.client.UsernamePasswordProxyCredentials; -import hudson.Extension; -import hudson.ProxyConfiguration; -import hudson.util.Secret; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -@Extension -public class JenkinsMqmRestClientFactoryImpl implements JenkinsMqmRestClientFactory { - private static final Logger logger = LogManager.getLogger(JenkinsMqmRestClientFactoryImpl.class); - private static final String CLIENT_TYPE = "HPE_CI_CLIENT"; - private static MqmRestClient mqmRestClient; - - @Override - public synchronized MqmRestClient obtain(String location, String sharedSpace, String username, Secret password) { - if (mqmRestClient == null) { - mqmRestClient = create(location, sharedSpace, username, password); - logger.info("NGA REST Clint: initialized for " + location + " - " + sharedSpace + " - " + username); - } - return mqmRestClient; - } - - @Override - public MqmRestClient obtainTemp(String location, String sharedSpace, String username, Secret password) { - MqmRestClient mqmRestClientTemp = create(location, sharedSpace, username, password); - logger.info("NGA REST Clint: initialized for " + location + " - " + sharedSpace + " - " + username); - return mqmRestClientTemp; - } - - @Override - public synchronized void updateMqmRestClient(String location, String sharedSpace, String username, Secret password) { - mqmRestClient = create(location, sharedSpace, username, password); - logger.info("NGA REST Clint: updated to " + location + " - " + sharedSpace + " - " + username); - } - - private MqmRestClient create(String location, String sharedSpace, String username, Secret password) { - MqmConnectionConfig clientConfig = new MqmConnectionConfig(location, sharedSpace, username, password.getPlainText(), CLIENT_TYPE); - URL locationUrl; - try { - locationUrl = new URL(clientConfig.getLocation()); - } catch (MalformedURLException e) { - throw new IllegalArgumentException(e); - } - if (isProxyNeeded(locationUrl.getHost())) { - clientConfig.setProxyHost(getProxyHost()); - clientConfig.setProxyPort(getProxyPort()); - final String proxyUsername = getUsername(); - if (!StringUtils.isEmpty(proxyUsername)) { - clientConfig.setProxyCredentials(new UsernamePasswordProxyCredentials(username, getPassword())); - } - } - return new MqmRestClientImpl(clientConfig); - } - - private String getProxyHost() { - final ProxyConfiguration proxyConfiguration = Jenkins.getInstance().proxy; - if (proxyConfiguration != null) { - return proxyConfiguration.name; - } - return null; - } - - private Integer getProxyPort() { - final ProxyConfiguration proxyConfiguration = Jenkins.getInstance().proxy; - if (proxyConfiguration != null) { - return proxyConfiguration.port; - } - return null; - } - - private String getUsername() { - final ProxyConfiguration proxyConfiguration = Jenkins.getInstance().proxy; - if (proxyConfiguration != null) { - return proxyConfiguration.getUserName(); - } - return null; - } - - private String getPassword() { - final ProxyConfiguration proxyConfiguration = Jenkins.getInstance().proxy; - if (proxyConfiguration != null) { - return proxyConfiguration.getPassword(); - } - return null; - } - - private boolean isProxyNeeded(final String host) { - final ProxyConfiguration proxyConfiguration = Jenkins.getInstance().proxy; - if (proxyConfiguration != null && !StringUtils.isEmpty(proxyConfiguration.name)) { - // if any patterns match the host, we will not use proxy - final List patterns = proxyConfiguration.getNoProxyHostPatterns(); - if (patterns != null) { - for (final Pattern pattern : patterns) { - final Matcher matcher = pattern.matcher(host); - if (matcher.matches()) { - return false; - } - } - } - return true; - } - return false; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/client/RetryModel.java b/src/main/java/com/hp/application/automation/tools/octane/client/RetryModel.java deleted file mode 100644 index 2457a05f8a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/client/RetryModel.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.configuration.ConfigurationListener; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import hudson.util.TimeUnit2; - -@Extension -public class RetryModel implements ConfigurationListener { - - private static final long[] QUIET_PERIOD = { // TODO: janotav: verify against our Saas policy - TimeUnit2.MINUTES.toMillis(1), - TimeUnit2.MINUTES.toMillis(10), - TimeUnit2.MINUTES.toMillis(60) - }; - - private long boundary; - private int periodIndex; - - private TimeProvider timeProvider = new SystemTimeProvider(); - private EventPublisher eventPublisher; - - @Inject - public RetryModel() { - doSuccess(); - } - - - public RetryModel(EventPublisher eventPublisher) { - this(); - this.eventPublisher = eventPublisher; - } - - public synchronized boolean isQuietPeriod() { - return timeProvider.getTime() < boundary; - } - - public synchronized void failure() { - if (periodIndex < QUIET_PERIOD.length - 1) { - periodIndex++; - } - boundary = timeProvider.getTime() + QUIET_PERIOD[periodIndex]; - } - - public void success() { - doSuccess(); - eventPublisher.resume(); - } - - private synchronized void doSuccess() { - periodIndex = -1; - boundary = 0; - } - - @Override - public void onChanged(ServerConfiguration conf, ServerConfiguration oldConf) { - doSuccess(); - } - - @Inject - public void setEventPublisher(JenkinsInsightEventPublisher eventPublisher) { - this.eventPublisher = eventPublisher; - } - - - void setTimeProvider(TimeProvider timeProvider) { - this.timeProvider = timeProvider; - } - - private static class SystemTimeProvider implements TimeProvider { - - @Override - public long getTime() { - return System.currentTimeMillis(); - } - } - - interface TimeProvider { - - long getTime(); - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/BdiConfiguration.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/BdiConfiguration.java deleted file mode 100644 index 65801aa1b5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/BdiConfiguration.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import net.sf.json.JSONObject; - -/** - * Created by benmeior on 12/12/2016. - */ -public class BdiConfiguration { - - private String host; - private String port; - private String tenantId; - - private BdiConfiguration(String host, String port, String tenantId) { - this.host = host; - this.port = port; - this.tenantId = tenantId; - } - - public String getHost() { - return host; - } - - public String getPort() { - return port; - } - - public String getTenantId() { - return tenantId; - } - - public boolean isFullyConfigured() { - return host != null && port != null && tenantId != null; - } - - public static BdiConfiguration fromJSON(JSONObject jsonObject) { - if (jsonObject == null || !jsonObject.containsKey("host") - || !jsonObject.containsKey("port") || !jsonObject.containsKey("tenant")) { - return null; - } - - String host = jsonObject.getString("host"); - String port = jsonObject.getString("port"); - String tenant = jsonObject.getString("tenant"); - - return new BdiConfiguration(host, port, tenant); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BdiConfiguration that = (BdiConfiguration) o; - - if (host != null ? !host.equals(that.host) : that.host != null) return false; - if (port != null ? !port.equals(that.port) : that.port != null) return false; - if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false; - return true; - } - - @Override - public int hashCode() { - int result = host != null ? host.hashCode() : 0; - result = 31 * result + (port != null ? port.hashCode() : 0); - result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0); - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigApi.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigApi.java deleted file mode 100644 index a48469a69f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigApi.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.hp.application.automation.tools.model.OctaneServerSettingsModel; -import hudson.util.FormValidation; -import hudson.util.Secret; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.export.Flavor; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import javax.servlet.ServletException; -import java.io.IOException; - -public class ConfigApi { - private static final Logger logger = LogManager.getLogger(ConfigApi.class); - - public void doRead(StaplerRequest req, StaplerResponse res) throws ServletException, IOException { - checkPermission(); - res.serveExposedBean(req, getConfiguration(), Flavor.JSON); - } - - @RequirePOST - public void doSave(StaplerRequest req, StaplerResponse res) throws IOException, ServletException { - checkPermission(); - - JSONObject configuration = JSONObject.fromObject(IOUtils.toString(req.getInputStream())); - String uiLocation; - if (!configuration.containsKey("uiLocation")) { - // allow per-partes project specification - String location = (String) configuration.get("location"); - String sharedSpace = (String) configuration.get("sharedSpace"); - if (StringUtils.isEmpty(location) || StringUtils.isEmpty(sharedSpace)) { - res.sendError(400, "Either (uiLocation) or (location and shared space) must be specified"); - return; - } - uiLocation = location.replaceAll("/$", "") + "/ui?p=" + sharedSpace; - } else { - uiLocation = configuration.getString("uiLocation"); - } - try { - // validate location format - ConfigurationParser.parseUiLocation(uiLocation); - } catch (FormValidation ex) { - res.sendError(400, ex.getMessage()); - return; - } - - String impersonatedUser = configuration.containsKey("impersonatedUser") ? configuration.getString("impersonatedUser") : ""; - - String username; - Secret password; - if (!configuration.containsKey("username")) { - // when username is not provided, use existing credentials (password can be overridden later) - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - username = serverConfiguration.username; - password = serverConfiguration.password; - } else { - // when username is provided, clear password unless provided later - username = configuration.getString("username"); - password = Secret.fromString(""); - } - if (configuration.containsKey("password")) { - password = Secret.fromString(configuration.getString("password")); - } - OctaneServerSettingsModel model = new OctaneServerSettingsModel(uiLocation, username, password, impersonatedUser); - ConfigurationService.configurePlugin(model); - - String serverIdentity = (String) configuration.get("serverIdentity"); - if (!StringUtils.isEmpty(serverIdentity)) { - ConfigurationService.getModel().setIdentity(serverIdentity); - } - - res.serveExposedBean(req, getConfiguration(), Flavor.JSON); - } - - private void checkPermission() { - Jenkins.getInstance().getACL().checkPermission(Jenkins.ADMINISTER); - } - - private Configuration getConfiguration() { - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - return new Configuration( - serverConfiguration.location, - serverConfiguration.sharedSpace, - serverConfiguration.username, - serverConfiguration.impersonatedUser, - ConfigurationService.getModel().getIdentity()); - } - - @ExportedBean - public static final class Configuration { - - private String location; - private String sharedSpace; - private String username; - private String serverIdentity; - private String impersonatedUser; - - - public Configuration(String location, String sharedSpace, String username, String impersonatedUser, String serverIdentity) { - this.location = location; - this.sharedSpace = sharedSpace; - this.username = username; - this.impersonatedUser = impersonatedUser; - this.serverIdentity = serverIdentity; - } - - @Exported(inline = true) - public String getLocation() { - return location; - } - - @Exported(inline = true) - public String getImpersonatedUser() { - return impersonatedUser; - } - - @Exported(inline = true) - public String getSharedSpace() { - return sharedSpace; - } - - @Exported(inline = true) - public String getUsername() { - return username; - } - - @Exported(inline = true) - public String getServerIdentity() { - return serverIdentity; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationAction.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationAction.java deleted file mode 100644 index fbc301aded..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationAction.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.hp.application.automation.tools.octane.Messages; -import hudson.model.Action; -import hudson.model.Item; -import hudson.model.Job; -import org.kohsuke.stapler.StaplerProxy; - -public class ConfigurationAction implements Action, StaplerProxy { - - final public Job owner; - final public JobConfigurationProxy proxy; - - public ConfigurationAction(Job job) { - this.owner = job; - this.proxy = new JobConfigurationProxy(job); - } - - @Override - public String getIconFileName() { - return owner.getACL().hasPermission(Item.CONFIGURE)? "setting.png": null; - } - - @Override - public String getDisplayName() { - return Messages.ConfigurationLabel(); - } - - @Override - public String getUrlName() { - return "mqmConfiguration"; - } - - @Override - public Object getTarget() { - owner.getACL().checkPermission(Item.CONFIGURE); - return this; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactory.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactory.java deleted file mode 100644 index 9e4e9112ad..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import hudson.Extension; -import hudson.model.Action; -import hudson.model.Job; -import jenkins.model.TransientActionFactory; - -import javax.annotation.Nonnull; -import java.util.Collection; -import java.util.Collections; - -@Extension -public class ConfigurationActionFactory extends TransientActionFactory { - - @Override - public Class type() { - return Job.class; - } - - @Nonnull - @Override - public Collection createFor(@Nonnull Job job) { - // not sure if we need proper extensibility mechanism here: let's start small and extend if needed - if ("hudson.matrix.MatrixConfiguration".equals(job.getClass().getName())) { - return Collections.emptyList(); - } - return Collections.singleton(new ConfigurationAction(job)); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListener.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListener.java deleted file mode 100644 index 7838e9a34c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListener.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import hudson.ExtensionPoint; - -public interface ConfigurationListener extends ExtensionPoint { - - void onChanged(ServerConfiguration conf, ServerConfiguration oldConf); - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationParser.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationParser.java deleted file mode 100644 index d22185af8a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationParser.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.google.inject.Inject; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.*; -import com.hp.application.automation.tools.octane.Messages; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import hudson.Extension; -import hudson.util.FormValidation; -import hudson.util.Secret; -import org.apache.commons.lang.StringUtils; -import org.apache.http.NameValuePair; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.List; - -@Extension -public class ConfigurationParser { - - public ConfigurationParser(){} - - private final static Logger logger = LogManager.getLogger(ConfigurationParser.class); - - private static final String PARAM_SHARED_SPACE = "p"; // NON-NLS - - private JenkinsMqmRestClientFactory clientFactory; - - public static MqmProject parseUiLocation(String uiLocation) throws FormValidation { - try { - URL url = new URL(uiLocation); - String location; - int contextPos = uiLocation.indexOf("/ui"); - if (contextPos < 0) { - throw FormValidation.errorWithMarkup(markup("red", Messages.ApplicationContextNotFound())); - } else { - location = uiLocation.substring(0, contextPos); - } - List params = URLEncodedUtils.parse(url.toURI(), "UTF-8"); - for (NameValuePair param : params) { - if (param.getName().equals(PARAM_SHARED_SPACE)) { - String[] sharedSpaceAndWorkspace = param.getValue().split("/"); - // we are relaxed and allow parameter without workspace in order not to force user to makeup - // workspace value when configuring manually or via config API and not via copy & paste - if (sharedSpaceAndWorkspace.length < 1 || StringUtils.isEmpty(sharedSpaceAndWorkspace[0])) { - throw FormValidation.errorWithMarkup(markup("red", Messages.UnexpectedSharedSpace())); - } - return new MqmProject(location, sharedSpaceAndWorkspace[0]); - } - } - throw FormValidation.errorWithMarkup(markup("red", Messages.MissingSharedSpace())); - } catch (MalformedURLException e) { - throw FormValidation.errorWithMarkup(markup("red", Messages.ConfigurationUrInvalid())); - } catch (URISyntaxException e) { - throw FormValidation.errorWithMarkup(markup("red", Messages.ConfigurationUrInvalid())); - } - } - - public FormValidation checkConfiguration(String location, String sharedSpace, String username, Secret password) { - MqmRestClient client = clientFactory.obtainTemp(location, sharedSpace, username, password); - try { - client.validateConfiguration(); - } catch (AuthenticationException ae) { - logger.warn("Authentication failure", ae); - return FormValidation.errorWithMarkup(markup("red", Messages.AuthenticationFailure())); - } catch (AuthorizationException ae) { - logger.warn("Authorization failure", ae); - return FormValidation.errorWithMarkup(markup("red", Messages.AuthorizationFailure())); - } catch (SharedSpaceNotExistException ssnee) { - logger.warn("Shared space validation failure", ssnee); - return FormValidation.errorWithMarkup(markup("red", Messages.ConnectionSharedSpaceInvalid())); - } catch (LoginErrorException lee) { - logger.warn("General logic failure", lee); - return FormValidation.errorWithMarkup(markup("red", Messages.ConnectionFailure())); - } catch (RequestErrorException ree) { - logger.warn("Connection check failed due to communication problem", ree); - return FormValidation.errorWithMarkup(markup("red", Messages.ConnectionFailure())); - } - return FormValidation.okWithMarkup(markup("green", Messages.ConnectionSuccess())); - } - - public static String markup(String color, String message) { - return "" + message + ""; - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } - - /* - * To be used in tests only. - */ - public void _setMqmRestClientFactory(JenkinsMqmRestClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationService.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationService.java deleted file mode 100644 index 7172a6b3ea..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ConfigurationService.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.hp.application.automation.tools.model.OctaneServerSettingsModel; -import com.hp.application.automation.tools.settings.OctaneServerSettingsBuilder; -import hudson.Extension; -import hudson.Plugin; -import hudson.model.Hudson; -import jenkins.model.Jenkins; - -@Extension -public class ConfigurationService { - - public static OctaneServerSettingsModel getModel() { - return getOctaneDescriptor().getModel(); - } - - public static ServerConfiguration getServerConfiguration() { - return getOctaneDescriptor().getServerConfiguration(); - } - - public static void configurePlugin(OctaneServerSettingsModel newModel){ - getOctaneDescriptor().setModel(newModel); - } - - private static OctaneServerSettingsBuilder.OctaneDescriptorImpl getOctaneDescriptor(){ - return Hudson.getInstance().getDescriptorByType(OctaneServerSettingsBuilder.OctaneDescriptorImpl.class); - } - - public static String getPluginVersion(){ - Plugin plugin = Jenkins.getInstance().getPlugin("hp-application-automation-tools-plugin"); - return plugin.getWrapper().getVersion(); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/JobConfigurationProxy.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/JobConfigurationProxy.java deleted file mode 100644 index 9bfba208d9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/JobConfigurationProxy.java +++ /dev/null @@ -1,902 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.RequestException; -import com.hp.mqm.client.model.*; -import com.hp.octane.integrations.OctaneSDK; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.general.CIServerInfo; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.application.automation.tools.octane.Messages; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.RetryModel; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.ExtensionList; -import hudson.model.Job; -import jenkins.model.Jenkins; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.stapler.bind.JavaScriptMethod; - -import java.io.IOException; -import java.util.*; -import java.util.Map.Entry; -import java.util.regex.Pattern; - -public class JobConfigurationProxy { - private final static Logger logger = LogManager.getLogger(JobConfigurationProxy.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - final private Job job; - private RetryModel retryModel; - - private static final String PRODUCT_NAME = Messages.ServerName(); - private static final String NOT_SPECIFIED = "-- Not specified --"; - - JobConfigurationProxy(Job job) { - this.job = job; - } - - @JavaScriptMethod - public JSONObject createPipelineOnServer(JSONObject pipelineObject) throws IOException { - JSONObject result = new JSONObject(); - - PipelineNode pipelineNode = ModelFactory.createStructureItem(job); - CIServerInfo ciServerInfo = OctaneSDK.getInstance().getPluginServices().getServerInfo(); - Long releaseId = pipelineObject.getLong("releaseId") != -1 ? pipelineObject.getLong("releaseId") : null; - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - - try { - Pipeline createdPipeline = client.createPipeline( - ConfigurationService.getModel().getIdentity(), - job.getName(), - pipelineObject.getString("name"), - pipelineObject.getLong("workspaceId"), - releaseId, - dtoFactory.dtoToJson(pipelineNode), - dtoFactory.dtoToJson(ciServerInfo)); - - //WORKAROUND BEGIN - //getting workspaceName - because the workspaceName is not returned from configuration API - List workspaces = client.getWorkspaces(Collections.singletonList(createdPipeline.getWorkspaceId())); - if (workspaces.size() != 1) { - throw new ClientException("WorkspaceName could not be retrieved for workspaceId: " + createdPipeline.getWorkspaceId()); - } - //WORKAROUND END - - JSONObject pipelineJSON = fromPipeline(createdPipeline, workspaces.get(0)); - //WORKAROUND BEGIN - //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API - enrichPipeline(pipelineJSON, client); - //WORKAROUND END - result.put("pipeline", pipelineJSON); - - JSONArray fieldsMetadata = getFieldMetadata(createdPipeline.getWorkspaceId(), client); - result.put("fieldsMetadata", fieldsMetadata); - - } catch (RequestException e) { - logger.warn("Failed to create pipeline", e); - return error("Unable to create pipeline"); - } catch (ClientException e) { - logger.warn("Failed to create pipeline", e); - return error(e.getMessage(), e.getLink()); - } - return result; - } - - @JavaScriptMethod - public JSONObject updatePipelineOnSever(JSONObject pipelineObject) throws IOException { - JSONObject result = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - long pipelineId = pipelineObject.getLong("id"); - - LinkedList taxonomies = new LinkedList<>(); - JSONArray taxonomyTags = pipelineObject.getJSONArray("taxonomyTags"); - for (JSONObject jsonObject : toCollection(taxonomyTags)) { - taxonomies.add(new Taxonomy(jsonObject.optLong("tagId"), jsonObject.getString("tagName"), - new Taxonomy(jsonObject.optLong("tagTypeId"), jsonObject.getString("tagTypeName"), null))); - } - - LinkedList fields = new LinkedList<>(); - JSONArray fieldTags = pipelineObject.getJSONArray("fieldTags"); - for (JSONObject jsonObject : toCollection(fieldTags)) { - List assignedValues = new LinkedList<>(); - for (JSONObject value : toCollection(jsonObject.getJSONArray("values"))) { - Long id; - if (value.containsKey("id")) { - id = value.getLong("id"); - } else { - id = null; - } - assignedValues.add(new ListItem(id, null, value.getString("name"), null)); - } - fields.add(new ListField(jsonObject.getString("name"), assignedValues)); - } - - Pipeline pipeline = client.updatePipeline(ConfigurationService.getModel().getIdentity(), job.getName(), - new Pipeline(pipelineId, pipelineObject.getString("name"), null, pipelineObject.getLong("workspaceId"), pipelineObject.getLong("releaseId"), taxonomies, fields, pipelineObject.getBoolean("ignoreTests"))); - - //WORKAROUND BEGIN - //getting workspaceName - because the workspaceName is not returned from configuration API - List workspaces = client.getWorkspaces(Collections.singletonList(pipeline.getWorkspaceId())); - if (workspaces.size() != 1) { - throw new ClientException("WorkspaceName could not be retrieved for workspaceId: " + pipeline.getWorkspaceId()); - } - //WORKAROUND END - - JSONObject pipelineJSON = fromPipeline(pipeline, workspaces.get(0)); - //WORKAROUND BEGIN - //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API - enrichPipeline(pipelineJSON, client); - //WORKAROUND END - result.put("pipeline", pipelineJSON); - - - //Server might do partial sucess - //So need to validate each item if it succedded or not - //For now we add handling of duplicate pipeline name - String originalName = pipelineObject.get("name").toString(); - String updatedName = pipelineJSON.get("name").toString(); - if (!originalName.equalsIgnoreCase(updatedName)) { - JSONObject errorObj = new JSONObject(); - errorObj.put("message", "Failed to update pipeline name. Make sure not to enter the name of an existing pipeline."); - result.put("error", errorObj); - } - - } catch (RequestException e) { - logger.warn("Failed to update pipeline", e); - return error("Unable to update pipeline"); - } catch (ClientException e) { - logger.warn("Failed to update pipeline", e); - return error(e.getMessage(), e.getLink()); - } - - return result; - } - - - @JavaScriptMethod - public JSONObject deleteTests(JSONObject pipelineObject) throws IOException, InterruptedException { - JSONObject result = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - long pipelineId = pipelineObject.getLong("id"); - long workspaceId = pipelineObject.getLong("workspaceId"); - client.deleteTestsFromPipelineNodes(job.getName(), pipelineId, workspaceId); - result.put("Test deletion was succeful", ""); - } catch (RequestException e) { - logger.warn("Failed to delete tests", e); - return error("Unable to delete tests"); - } - - return result; - } - - @JavaScriptMethod - public JSONObject loadJobConfigurationFromServer() throws IOException { - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - - JSONObject ret = new JSONObject(); - JSONObject workspaces = new JSONObject(); - JSONArray fieldsMetadata = new JSONArray(); - try { - JobConfiguration jobConfiguration = client.getJobConfiguration(ConfigurationService.getModel().getIdentity(), job.getName()); - - if (!jobConfiguration.getWorkspacePipelinesMap().isEmpty()) { - Map> workspacesMap = jobConfiguration.getWorkspacePipelinesMap(); - //WORKAROUND BEGIN - //getting workspaceName - because the workspaceName is not returned from configuration API - Map relatedWorkspaces = new HashMap<>(); - List workspaceList = client.getWorkspaces(new LinkedList<>(workspacesMap.keySet())); - for (Workspace workspace : workspaceList) { - relatedWorkspaces.put(workspace.getId(), workspace.getName()); - } - //WORKAROUND END - - Map> sortedWorkspacesMap = new TreeMap<>(new Comparator() { - @Override - public int compare(final Workspace w1, final Workspace w2) { - return w1.getName().compareTo(w2.getName()); - } - }); - Comparator pipelineComparator = new Comparator() { - @Override - public int compare(final Pipeline p1, final Pipeline p2) { - return p1.getName().compareTo(p2.getName()); - } - }; - - //create workspaces JSON Object - for (Entry> workspacePipelines : workspacesMap.entrySet()) { - Workspace relatedWorkspace = new Workspace(workspacePipelines.getKey(), relatedWorkspaces.get(workspacePipelines.getKey())); - JSONObject relatedPipelinesJSON = new JSONObject(); - - for (Pipeline relatedPipeline : workspacePipelines.getValue()) { - JSONObject pipelineJSON = fromPipeline(relatedPipeline, relatedWorkspace); - relatedPipelinesJSON.put(String.valueOf(relatedPipeline.getId()), pipelineJSON); - } - JSONObject workspaceJSON = new JSONObject(); - workspaceJSON.put("id", relatedWorkspace.getId()); - workspaceJSON.put("name", relatedWorkspace.getName()); - workspaceJSON.put("pipelines", relatedPipelinesJSON); - workspaces.put(String.valueOf(relatedWorkspace.getId()), workspaceJSON); - - //inserting this workspace into sortedMap (sorted by workspaceName and by pipelineName, so that we can pick first workspace and its first pipeline as preselected values - LinkedList workspacePipelinesList = new LinkedList(workspacePipelines.getValue()); - Collections.sort(workspacePipelinesList, pipelineComparator); - sortedWorkspacesMap.put(relatedWorkspace, workspacePipelinesList); - } - - //create currentPipeline JSON Object - //currently the first pipeline in the first workspace is picked - Workspace preSelectedWorkspace = sortedWorkspacesMap.keySet().iterator().next(); - Pipeline preSelectedPipeline = sortedWorkspacesMap.get(preSelectedWorkspace).get(0); - JSONObject preSelectedPipelineJSON = fromPipeline(preSelectedPipeline, preSelectedWorkspace); - - //WORKAROUND BEGIN - //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API - enrichPipeline(preSelectedPipelineJSON, client); - //WORKAROUND END - ret.put("currentPipeline", preSelectedPipelineJSON); - - //retrieving metadata fields for preselected workspace - fieldsMetadata = getFieldMetadata(preSelectedWorkspace.getId(), client); - } - - ret.put("workspaces", workspaces); - ret.put("fieldsMetadata", fieldsMetadata); - - } catch (RequestException e) { - logger.warn("Failed to retrieve job configuration", e); - return error("Unable to retrieve job configuration"); - } - - return ret; - } - - @JavaScriptMethod - public JSONObject loadWorkspaceConfiguration(JSONObject pipelineJSON) { - MqmRestClient client; - JSONObject ret = new JSONObject(); - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - - try { - JSONArray fieldsMetadata = getFieldMetadata(pipelineJSON.getLong("workspaceId"), client); - ret.put("fieldsMetadata", fieldsMetadata); - enrichPipeline(pipelineJSON, client); - ret.put("pipeline", pipelineJSON); - } catch (RequestException e) { - logger.warn("Failed to retrieve metadata for workspace", e); - return error("Unable to retrieve metadata for workspace"); - } - - return ret; - } - - private JSONObject fromPipeline(final Pipeline pipeline, Workspace relatedWorkspace) { - JSONObject pipelineJSON = new JSONObject(); - pipelineJSON.put("id", pipeline.getId()); - pipelineJSON.put("name", pipeline.getName()); - pipelineJSON.put("releaseId", pipeline.getReleaseId() != null ? pipeline.getReleaseId() : -1); - pipelineJSON.put("isRoot", pipeline.isRoot()); - pipelineJSON.put("workspaceId", relatedWorkspace.getId()); - pipelineJSON.put("workspaceName", relatedWorkspace.getName()); - pipelineJSON.put("ignoreTests", pipeline.getIgnoreTests()); - addTaxonomyTags(pipelineJSON, pipeline); - addFields(pipelineJSON, pipeline); - - return pipelineJSON; - } - - @JavaScriptMethod - public JSONObject enrichPipeline(JSONObject pipelineJSON) { - MqmRestClient client; - JSONObject ret = new JSONObject(); - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - - try { - enrichPipeline(pipelineJSON, client); - ret.put("pipeline", pipelineJSON); - } catch (RequestException e) { - logger.warn("Failed to retrieve metadata for pipeline", e); - return error("Unable to retrieve metadata for pipeline"); - } - - return ret; - } - - private void enrichPipeline(JSONObject pipelineJSON, MqmRestClient client) { - enrichRelease(pipelineJSON, client); - enrichTaxonomies(pipelineJSON, client); - enrichFields(pipelineJSON, client); - } - - private void enrichRelease(JSONObject pipeline, MqmRestClient client) { - long workspaceId = pipeline.getLong("workspaceId"); - if (pipeline.containsKey("releaseId") && pipeline.getLong("releaseId") != -1) { - long releaseId = pipeline.getLong("releaseId"); - String releaseName = client.getRelease(releaseId, workspaceId).getName(); - pipeline.put("releaseName", releaseName); - } - } - - private void enrichTaxonomies(JSONObject pipeline, MqmRestClient client) { - JSONArray ret = new JSONArray(); - if (pipeline.has("taxonomyTags")) { - - JSONArray taxonomyTags = pipeline.getJSONArray("taxonomyTags"); - List taxonomyIdsList = new LinkedList<>(); - for (int i = 0; i < taxonomyTags.size(); i++) { - JSONObject taxonomy = taxonomyTags.getJSONObject(i); - if (taxonomy.has("tagId")) { - taxonomyIdsList.add(taxonomy.getLong("tagId")); - } - } - List taxonomies = client.getTaxonomies(taxonomyIdsList, pipeline.getLong("workspaceId")); - for (Taxonomy tax : taxonomies) { - ret.add(tag(tax)); - } - } - pipeline.put("taxonomyTags", ret); - } - - private void enrichFields(JSONObject pipeline, MqmRestClient client) { - JSONObject ret = new JSONObject(); - - if (pipeline.has("fields")) { - long workspaceId = pipeline.getLong("workspaceId"); - JSONObject pipelineFields = pipeline.getJSONObject("fields"); - Iterator keys = pipelineFields.keys(); - //iteration over listFields - while (keys.hasNext()) { - String key = (String) keys.next(); - if (pipelineFields.get(key) instanceof JSONArray) { - List fieldTagsIdsList = new LinkedList<>(); - //getting all ids assigned to listField - for (JSONObject singleField : toCollection(pipelineFields.getJSONArray(key))) { - fieldTagsIdsList.add(singleField.getLong("id")); - } - //retrieving names of assigned items - if (fieldTagsIdsList.size() > 0) { - List enrichedFields = client.getListItems(fieldTagsIdsList, workspaceId); - JSONArray values = new JSONArray(); - for (ListItem item : enrichedFields) { - JSONObject value = new JSONObject(); - value.put("id", item.getId()); - value.put("name", item.getName()); - values.add(value); - } - ret.put(key, values); - } - } - } - } - pipeline.put("fields", ret); - } - - private JSONArray getFieldMetadata(final long workspaceId, MqmRestClient client) { - JSONArray fieldMetadataArray = new JSONArray(); - List metadataList = client.getFieldsMetadata(workspaceId); - - for (FieldMetadata fieldMetadata : metadataList) { - fieldMetadataArray.add(fromFieldMetadata(fieldMetadata)); - } - return fieldMetadataArray; - } - - private JSONObject fromFieldMetadata(FieldMetadata fieldMetadata) { - JSONObject fieldMetadataJSON = new JSONObject(); - fieldMetadataJSON.put("name", fieldMetadata.getName()); - fieldMetadataJSON.put("listName", fieldMetadata.getListName()); - fieldMetadataJSON.put("logicalListName", fieldMetadata.getLogicalListName()); - fieldMetadataJSON.put("extensible", fieldMetadata.isExtensible()); - fieldMetadataJSON.put("multiValue", fieldMetadata.isMultiValue()); - fieldMetadataJSON.put("order", fieldMetadata.getOrder()); - return fieldMetadataJSON; - } - - @JavaScriptMethod - public JSONObject searchListItems(String logicalListName, String term, long workspaceId, boolean multiValue, boolean extensible) { - int defaultSize = 10; - JSONObject ret = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - - PagedList listItemPagedList = client.queryListItems(logicalListName, term, workspaceId, 0, defaultSize); - List listItems = listItemPagedList.getItems(); - boolean moreResults = listItemPagedList.getTotalCount() > listItems.size(); - - JSONArray retArray = new JSONArray(); - if (moreResults) { - retArray.add(createMoreResultsJson()); - } - - if (!multiValue) { - String quotedTerm = Pattern.quote(term.toLowerCase()); - if (Pattern.matches(".*" + quotedTerm + ".*", NOT_SPECIFIED.toLowerCase())) { - JSONObject notSpecifiedItemJson = new JSONObject(); - notSpecifiedItemJson.put("id", -1); - notSpecifiedItemJson.put("text", NOT_SPECIFIED); - retArray.add(notSpecifiedItemJson); - } - } - - for (ListItem item : listItems) { - if (!toBeFiltered(item)) { - JSONObject itemJson = new JSONObject(); - itemJson.put("id", item.getId()); - itemJson.put("text", item.getName()); - retArray.add(itemJson); - } - - } - // we shall use "if (extensible){}" on following line, but we do not have UI ready for the case: multiValue = true & extensible = true - if (extensible && !multiValue) { - //if exactly one item matches, we do not want to bother user with "new value" item - if ((listItems.size() != 1) || (!listItems.get(0).getName().toLowerCase().equals(term.toLowerCase()))) { - retArray.add(createNewValueJson("0")); - } - } - - - ret.put("results", retArray); - } catch (RequestException e) { - logger.warn("Failed to retrieve list items", e); - return error("Unable to retrieve job configuration"); - } - - return ret; - } - - private boolean toBeFiltered(ListItem item) { - return (item.getLogicalName().equalsIgnoreCase("list_node.testing_tool_type.manual")); - } - - @JavaScriptMethod - public JSONObject searchReleases(String term, long workspaceId) { - int defaultSize = 5; - JSONObject ret = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - PagedList releasePagedList = client.queryReleases(term, workspaceId, 0, defaultSize); - List releases = releasePagedList.getItems(); - boolean moreResults = releasePagedList.getTotalCount() > releases.size(); - - JSONArray retArray = new JSONArray(); - if (moreResults) { - retArray.add(createMoreResultsJson()); - } - - String quotedTerm = Pattern.quote(term.toLowerCase()); - if (Pattern.matches(".*" + quotedTerm + ".*", NOT_SPECIFIED.toLowerCase())) { - JSONObject notSpecifiedItemJson = new JSONObject(); - notSpecifiedItemJson.put("id", -1); - notSpecifiedItemJson.put("text", NOT_SPECIFIED); - retArray.add(notSpecifiedItemJson); - } - - for (Release release : releases) { - JSONObject relJson = new JSONObject(); - relJson.put("id", release.getId()); - relJson.put("text", release.getName()); - retArray.add(relJson); - } - ret.put("results", retArray); - - } catch (RequestException e) { - logger.warn("Failed to retrieve releases", e); - return error("Unable to retrieve releases"); - } - - return ret; - } - - @JavaScriptMethod - public JSONObject searchWorkspaces(String term) { - int defaultSize = 5; - JSONObject ret = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - PagedList workspacePagedList = client.queryWorkspaces(term, 0, defaultSize); - List workspaces = workspacePagedList.getItems(); - boolean moreResults = workspacePagedList.getTotalCount() > workspaces.size(); - - JSONArray retArray = new JSONArray(); - if (moreResults) { - retArray.add(createMoreResultsJson()); - } - - for (Workspace workspace : workspaces) { - JSONObject relJson = new JSONObject(); - relJson.put("id", workspace.getId()); - relJson.put("text", workspace.getName()); - retArray.add(relJson); - } - ret.put("results", retArray); - - } catch (RequestException e) { - logger.warn("Failed to retrieve workspaces", e); - return error("Unable to retrieve workspaces"); - } - - return ret; - } - - @JavaScriptMethod - public JSONObject searchTaxonomies(String term, long workspaceId, JSONArray pipelineTaxonomies) { - int defaultSize = 20; - JSONObject ret = new JSONObject(); - - MqmRestClient client; - try { - client = createClient(); - } catch (ClientException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - return error(e.getMessage(), e.getLink()); - } - try { - - //currently existing taxonomies on pipeline -> we need to show these options as disabled - List pipelineTaxonomiesList = new LinkedList<>(); - for (int i = 0; i < pipelineTaxonomies.size(); i++) { - JSONObject pipelineTaxonomy = pipelineTaxonomies.getJSONObject(i); - if (pipelineTaxonomy.containsKey("tagId") && pipelineTaxonomy.containsKey("tagTypeId")) { // we need to compare only taxonomies which already exist on server - pipelineTaxonomiesList.add(pipelineTaxonomy.getLong("tagId")); - } - } - //retrieving taxonomies from server - PagedList foundTaxonomies = client.queryTaxonomies(term, workspaceId, 0, defaultSize); - final List foundTaxonomiesList = foundTaxonomies.getItems(); - boolean moreResults = foundTaxonomies.getTotalCount() > foundTaxonomiesList.size(); - - //creating map > - // for easier creating result JSON - Map> taxonomyMap = new HashMap<>(); - Map taxonomyCategories = new HashMap<>(); - for (Taxonomy taxonomy : foundTaxonomiesList) { - if (taxonomy.getRoot() != null) { - if (taxonomyMap.containsKey(taxonomy.getRoot().getId())) { - taxonomyMap.get(taxonomy.getRoot().getId()).add(taxonomy); - } else { - taxonomyMap.put(taxonomy.getRoot().getId(), new LinkedHashSet<>(Arrays.asList(taxonomy))); - taxonomyCategories.put(taxonomy.getRoot().getId(), taxonomy.getRoot().getName()); - } - } - } - - //writing result json - JSONArray select2InputArray = new JSONArray(); - JSONObject allTags = new JSONObject(); - JSONObject tagTypesByName = new JSONObject(); - JSONObject tagTypes = new JSONObject(); - - //show warning, that there are more results and user should filter more specific - if (moreResults) { - select2InputArray.add(createMoreResultsJson()); - } - - for (Entry> taxonomyType : taxonomyMap.entrySet()) { - Long tagTypeId = taxonomyType.getKey(); - String tagTypeName = taxonomyCategories.get(tagTypeId); - JSONArray childrenArray = new JSONArray(); - - JSONObject optgroup = new JSONObject(); - optgroup.put("text", tagTypeName); - - //for tagTypesByName - JSONObject tagTypeJson = new JSONObject(); - tagTypeJson.put("tagTypeId", tagTypeId); - tagTypeJson.put("tagTypeName", tagTypeName); - JSONArray tagTypeByNameValues = new JSONArray(); - - for (Taxonomy tax : taxonomyType.getValue()) { - //creating input format for select2, so that this structure does not have to be refactored in javascript - JSONObject taxonomyJson = new JSONObject(); - taxonomyJson.put("id", tax.getId()); - taxonomyJson.put("text", tax.getName()); - taxonomyJson.put("value", tax.getId()); - if (pipelineTaxonomiesList.contains(tax.getId())) { - taxonomyJson.put("disabled", "disabled"); - } - childrenArray.add(taxonomyJson); - - //for allTags - adding tag into table of selected ones - JSONObject tagObject = new JSONObject(); - tagObject.put("tagId", tax.getId()); - tagObject.put("tagName", tax.getName()); - tagObject.put("tagTypeId", tax.getRoot().getId()); - tagObject.put("tagTypeName", tax.getRoot().getName()); - allTags.put(String.valueOf(tax.getId()), tagObject); - - //for tagTypesByName - JSONObject tagTypeByNameValue = new JSONObject(); - tagTypeByNameValue.put("tagId", tax.getId()); - tagTypeByNameValue.put("tagName", tax.getName()); - tagTypeByNameValues.add(tagTypeByNameValue); - } - //New value.. for current type - JSONObject newValueJson = createNewValueJson(Long.toString(tagTypeValue(tagTypeId))); - childrenArray.add(newValueJson); - - optgroup.put("children", childrenArray); - select2InputArray.add(optgroup); - tagTypeJson.put("values", tagTypeByNameValues); - tagTypesByName.put(tagTypeName, tagTypeJson); - tagTypes.put(Long.toString(tagTypeId), tagTypeJson); - } - - // New type... New value... - JSONObject optgroup = new JSONObject(); - optgroup.put("text", "New type..."); - JSONObject newValueJson = createNewValueJson("newTagType"); - JSONArray childrenArray = new JSONArray(); - childrenArray.add(newValueJson); - optgroup.put("children", childrenArray); - select2InputArray.add(optgroup); - - ret.put("select2Input", select2InputArray); - ret.put("allTags", allTags); - ret.put("tagTypesByName", tagTypesByName); - ret.put("tagTypes", tagTypes); - ret.put("more", moreResults); - - } catch (RequestException e) { - logger.warn("Failed to retrieve environments", e); - return error("Unable to retrieve environments"); - } - - return ret; - } - - private JSONObject createMoreResultsJson() { - JSONObject moreResultsJson = new JSONObject(); - moreResultsJson.put("id", "moreResultsFound"); - moreResultsJson.put("text", Messages.TooManyResults()); - moreResultsJson.put("warning", "true"); - moreResultsJson.put("disabled", "disabled"); - return moreResultsJson; - } - - private JSONObject createNewValueJson(String id) { - JSONObject newValueJson = new JSONObject(); - newValueJson.put("id", id); - newValueJson.put("text", "New value..."); - newValueJson.put("newValue", "true"); - return newValueJson; - } - - private long tagTypeValue(long n) { - // mapping to ensure negative value (solve the "0" tag type ID) - return -(n + 1); - } - - private void addTaxonomyTags(JSONObject result, Pipeline pipeline) { - JSONArray pipelineTaxonomies = new JSONArray(); - for (Taxonomy taxonomy : pipeline.getTaxonomies()) { - pipelineTaxonomies.add(tag(taxonomy)); - } - result.put("taxonomyTags", pipelineTaxonomies); - } - - private void addFields(JSONObject result, Pipeline pipeline) { - JSONObject listFields = new JSONObject(); - - for (ListField field : pipeline.getFields()) { - JSONArray assignedValuesArray = listFieldValues(field); - listFields.put(field.getName(), assignedValuesArray); - } - result.put("fields", listFields); - } - - private JSONArray listFieldValues(ListField field) { - JSONArray ret = new JSONArray(); - - for (ListItem item : field.getValues()) { - JSONObject value = new JSONObject(); - value.put("id", item.getId()); - if (item.getName() != null) { - value.put("name", item.getName()); - } - ret.add(value); - } - return ret; - } - - private static Collection toCollection(JSONArray array) { - return (Collection) array.subList(0, array.size()); - } - - private JSONObject tag(Long tagId, String value) { - JSONObject tag = new JSONObject(); - tag.put("tagId", String.valueOf(tagId)); - tag.put("tagName", value); - return tag; - } - - private JSONObject tag(Taxonomy taxonomy) { - JSONObject tag = tag(taxonomy.getId(), taxonomy.getName()); - if (taxonomy.getRoot() != null) { - tag.put("tagTypeId", String.valueOf(taxonomy.getRoot().getId())); - tag.put("tagTypeName", taxonomy.getRoot().getName()); - } - return tag; - } - - private JSONObject error(String message) { - return error(message, null); - } - - private JSONObject error(String message, ExceptionLink exceptionLink) { - JSONObject result = new JSONObject(); - JSONArray errors = new JSONArray(); - JSONObject error = new JSONObject(); - error.put("message", message); - if (exceptionLink != null) { - error.put("url", exceptionLink.getUrl()); - error.put("label", exceptionLink.getLabel()); - } - errors.add(error); - result.put("errors", errors); - return result; - } - - private MqmRestClient createClient() throws ClientException { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - if (StringUtils.isEmpty(configuration.location)) { - String label = "Please configure server here"; - throw new ClientException(PRODUCT_NAME + " not configured", new ExceptionLink("/configure", label)); - } - - RetryModel retryModel = getRetryModel(); - - if (retryModel.isQuietPeriod()) { - String label = "Please validate your configuration settings here"; - throw new ClientException(PRODUCT_NAME + " not connected", new ExceptionLink("/configure", label)); - } - - JenkinsMqmRestClientFactory clientFactory = getExtension(JenkinsMqmRestClientFactory.class); - MqmRestClient client = clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - try { - client.validateConfigurationWithoutLogin(); - } catch (RequestException e) { - logger.warn(PRODUCT_NAME + " connection failed", e); - retryModel.failure(); - throw new ClientException("Connection to " + PRODUCT_NAME + " failed"); - } - - retryModel.success(); - return client; - } - - private RetryModel getRetryModel() { - if (retryModel == null) { - retryModel = getExtension(RetryModel.class); - } - return retryModel; - } - - private static T getExtension(Class clazz) { - ExtensionList items = Jenkins.getInstance().getExtensionList(clazz); - assert 1 == items.size() : "Expected to have one and only one extension of type " + clazz; - return items.get(0); - } - - private static class ClientException extends Exception { - - private ExceptionLink link; - - ClientException(String message) { - this(message, null); - } - - ClientException(String message, ExceptionLink link) { - super(message); - this.link = link; - } - - public ExceptionLink getLink() { - return link; - } - } - - private static class ExceptionLink { - - private String url; - private String label; - - ExceptionLink(String url, String label) { - this.url = url; - this.label = label; - } - - public String getUrl() { - return url; - } - - public String getLabel() { - return label; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/MqmProject.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/MqmProject.java deleted file mode 100644 index 520b9d9337..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/MqmProject.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -final public class MqmProject { - private final String location; - private final String sharedSpace; - - public MqmProject(String location, String sharedSpace) { - this.location = location; - this.sharedSpace = sharedSpace; - } - - public String getLocation() { - return location; - } - - public String getSharedSpace() { - return sharedSpace; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfiguration.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfiguration.java deleted file mode 100644 index dd89be5c78..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class PredefinedConfiguration { - - private String uiLocation; - - public String getUiLocation() { - return uiLocation; - } - - public void setUiLocation(String location) { - this.uiLocation = location; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfigurationUnmarshaller.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfigurationUnmarshaller.java deleted file mode 100644 index e099065de9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/PredefinedConfigurationUnmarshaller.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import hudson.Extension; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import java.io.File; -import java.util.List; - -@Extension -public final class PredefinedConfigurationUnmarshaller { - private final static Logger logger = LogManager.getLogger(PredefinedConfigurationUnmarshaller.class); - - private static PredefinedConfigurationUnmarshaller extensionInstance; - private static Unmarshaller jaxbUnmarshaller; - - public static synchronized PredefinedConfigurationUnmarshaller getExtensionInstance() { - List extensions; - if (extensionInstance == null) { - extensions = Jenkins.getInstance().getExtensionList(PredefinedConfigurationUnmarshaller.class); - if (extensions.isEmpty()) { - logger.warn("PredefinedConfigurationUnmarshaller was not initialized properly"); - return null; - } else { - extensionInstance = extensions.get(0); - } - } - - if (jaxbUnmarshaller == null) { - try { - jaxbUnmarshaller = JAXBContext.newInstance(PredefinedConfiguration.class).createUnmarshaller(); - } catch (JAXBException e) { - logger.warn("Unable to create JAXB unmarshaller for predefined server configuration", e); - return null; - } - } - return extensionInstance; - } - - public PredefinedConfiguration unmarshall(File configurationFile) { - if (!configurationFile.canRead()) { - logger.warn("Unable to read predefined server configuration file"); - return null; - } - try { - return (PredefinedConfiguration) jaxbUnmarshaller.unmarshal(configurationFile); - } catch (JAXBException e) { - logger.warn("Unable to unmarshall predefined server configuration", e); - return null; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/configuration/ServerConfiguration.java b/src/main/java/com/hp/application/automation/tools/octane/configuration/ServerConfiguration.java deleted file mode 100644 index 305823c235..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/configuration/ServerConfiguration.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import hudson.util.Secret; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.net.MalformedURLException; -import java.net.URL; - -@SuppressWarnings({"squid:S1312","squid:S00122"}) -final public class ServerConfiguration { - private static final Logger logger = LogManager.getLogger(ServerConfiguration.class); - - public String location; - public String sharedSpace; - public String username; - public Secret password; - public String impersonatedUser; - - public ServerConfiguration(String location, String sharedSpace, String username, Secret password, String impersonatedUser) { - this.location = location; - this.sharedSpace = sharedSpace; - this.username = username; - this.password = password; - this.impersonatedUser = impersonatedUser; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ServerConfiguration that = (ServerConfiguration) o; - - if (location != null ? !location.equals(that.location) : that.location != null) return false; - if (sharedSpace != null ? !sharedSpace.equals(that.sharedSpace) : that.sharedSpace != null) return false; - if (username != null ? !username.equals(that.username) : that.username != null) return false; - if (password != null ? !password.equals(that.password) : that.password != null) return false; - if (impersonatedUser != null ? !impersonatedUser.equals(that.impersonatedUser) : that.impersonatedUser != null) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - int result = location != null ? location.hashCode() : 0; - result = 31 * result + (sharedSpace != null ? sharedSpace.hashCode() : 0); - result = 31 * result + (username != null ? username.hashCode() : 0); - result = 31 * result + (password != null ? password.hashCode() : 0); - result = 31 * result + (impersonatedUser != null ? impersonatedUser.hashCode() : 0); - return result; - } - - public boolean isValid() { - boolean result = false; - if (location != null && !location.isEmpty() && - sharedSpace != null && !sharedSpace.isEmpty()) { - try { - URL tmp = new URL(location); - logger.debug(String.format("location: %s",tmp.toString())); - result = true; - } catch (MalformedURLException mue) { - logger.error("configuration with malformed URL supplied", mue); - } - } - return result; - } - - @Override - public String toString() { - return "{ url: " + location + - ", sharedSpace: " + sharedSpace + - ", username: " + username + " }"; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/EventsClient.java b/src/main/java/com/hp/application/automation/tools/octane/events/EventsClient.java deleted file mode 100644 index 9b50cb19bd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/EventsClient.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.hp.mqm.client.MqmRestClient; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.events.CIEvent; -import com.hp.octane.integrations.dto.events.CIEventsList; -import com.hp.application.automation.tools.octane.CIJenkinsServicesImpl; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -public class EventsClient { - private static final Logger logger = LogManager.getLogger(EventsClient.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - private static final class WaitMonitor { - volatile boolean released; - } - - private final List events = Collections.synchronizedList(new ArrayList()); - private final Object INIT_LOCKER = new Object(); - private final WaitMonitor WAIT_MONITOR = new WaitMonitor(); - private Thread worker; - volatile boolean paused; - - private JenkinsMqmRestClientFactory restClientFactory; - - private int MAX_SEND_RETRIES = 7; - private int INITIAL_RETRY_PAUSE = 1739; - private int DATA_SEND_INTERVAL = 1373; - private int DATA_SEND_INTERVAL_IN_SUSPEND = 10 * 60 * 2; - private int failedRetries; - private int pauseInterval; - volatile private boolean shuttingDown; - - private ServerConfiguration mqmConfig; - private String lastErrorNote; - private Date lastErrorTime; - - public EventsClient(ServerConfiguration mqmConfig, JenkinsMqmRestClientFactory clientFactory) { - this.mqmConfig = new ServerConfiguration(mqmConfig.location, mqmConfig.sharedSpace, mqmConfig.username, mqmConfig.password, mqmConfig.impersonatedUser); - this.restClientFactory = clientFactory; - activate(); - logger.info("client initialized for '" + this.mqmConfig.location + "'; SP: " + this.mqmConfig.sharedSpace + "; access key: " + mqmConfig.username); - } - - public void update(ServerConfiguration newConfig) { - mqmConfig = new ServerConfiguration(newConfig.location, newConfig.sharedSpace, newConfig.username, newConfig.password, newConfig.impersonatedUser); - activate(); - logger.info("client updated to '" + mqmConfig.location + "'; SP: " + mqmConfig.sharedSpace + "; access key: " + newConfig.username); - } - - public void pushEvent(CIEvent event) { - events.add(event); - } - - void activate() { - resetCounters(); - if (worker == null || !worker.isAlive()) { - synchronized (INIT_LOCKER) { - if (worker == null || !worker.isAlive()) { - worker = new Thread(new Runnable() { - @Override - public void run() { - while (!shuttingDown) { - try { - if (events.size() > 0) { - if (!sendData()) suspend(); - } - Thread.sleep(DATA_SEND_INTERVAL); - } catch (Exception e) { - logger.error("failed to send events", e); - } - } - logger.info("worker thread of events client stopped"); - } - }); - worker.setDaemon(true); - worker.setName("EventsClientWorker"); - worker.start(); - } - } - } - } - - void suspend() { - events.clear(); - failedRetries = MAX_SEND_RETRIES - 1; - doBreakableWait(DATA_SEND_INTERVAL_IN_SUSPEND); - //shuttingDown = true; - } - - void dispose() { - events.clear(); - if (worker != null) { - shuttingDown = true; - try { - worker.join(); - } catch (InterruptedException ie) { - logger.info("interruption happened while shutting down worker thread", ie); - } finally { - if (worker.isAlive()) { - worker.interrupt(); - } - } - } - } - - private void resetCounters() { - shuttingDown = false; - failedRetries = 0; - pauseInterval = INITIAL_RETRY_PAUSE; - synchronized (WAIT_MONITOR) { - if (worker != null && worker.getState() == Thread.State.TIMED_WAITING) { - WAIT_MONITOR.released = true; - WAIT_MONITOR.notify(); - } - } - } - - private boolean sendData() { - CIEventsList eventsSnapshot = dtoFactory.newDTO(CIEventsList.class) - .setServer(new CIJenkinsServicesImpl().getServerInfo()) - .setEvents(new ArrayList(events)); - String requestBody; - boolean result = true; - MqmRestClient restClient = restClientFactory.obtain(mqmConfig.location, mqmConfig.sharedSpace, mqmConfig.username, mqmConfig.password); - String eventsSummary = ""; - for (CIEvent event : eventsSnapshot.getEvents()) { - eventsSummary += event.getProject() + ":" + event.getBuildCiId() + ":" + event.getEventType() + ", "; - } - eventsSummary = eventsSummary.substring(0, eventsSummary.length() - 2); - - try { - requestBody = dtoFactory.dtoToJson(eventsSnapshot); - logger.info("sending events [" + eventsSummary + "] to '" + mqmConfig.location + "'..."); - while (failedRetries < MAX_SEND_RETRIES) { - if (restClient.putEvents(requestBody)) { - events.removeAll(eventsSnapshot.getEvents()); - logger.info("... done, left to send " + events.size() + " events"); - resetCounters(); - break; - } else { - lastErrorNote = "send to MQM server failed"; - lastErrorTime = new Date(); - failedRetries++; - - if (failedRetries < MAX_SEND_RETRIES) { - doBreakableWait(pauseInterval *= 2); - } - } - } - if (failedRetries == MAX_SEND_RETRIES) { - logger.error("max number of retries reached"); - result = false; - } - } catch (Exception e) { - logger.error("failed to send snapshot of " + eventsSnapshot.getEvents().size() + " events: " + e.getMessage() + "; dropping them all", e); - events.removeAll(eventsSnapshot.getEvents()); - } - return result; - } - - private void doBreakableWait(long timeout) { - logger.info("entering waiting period of " + timeout + "ms"); - long waitStart = new Date().getTime(); - synchronized (WAIT_MONITOR) { - WAIT_MONITOR.released = false; - paused = true; - while (!WAIT_MONITOR.released && new Date().getTime() - waitStart < timeout) { - try { - WAIT_MONITOR.wait(timeout); - } catch (InterruptedException ie) { - logger.info("waiting period was interrupted", ie); - } - } - paused = false; - if (WAIT_MONITOR.released) { - logger.info("pause finished on demand"); - } else { - logger.info("pause finished timely"); - } - } - } - - public String getLocation() { - return mqmConfig.location; - } - - public String getSharedSpace() { - return mqmConfig.sharedSpace; - } - - public String getUsername() { - return mqmConfig.username; - } - - public boolean isActive() { - return worker != null && worker.isAlive(); - } - - public boolean isPaused() { - return paused; - } - - public boolean isSuspended() { - return !isActive() || isPaused(); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/EventsService.java b/src/main/java/com/hp/application/automation/tools/octane/events/EventsService.java deleted file mode 100644 index 36bf0e8d67..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/EventsService.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.google.inject.Inject; -import com.hp.octane.integrations.dto.events.CIEvent; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.configuration.ConfigurationListener; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Collections; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 31/08/14 - * Time: 14:07 - * To change this template use File | Settings | File Templates. - */ - -@Extension -public final class EventsService implements ConfigurationListener { - private static final Logger logger = LogManager.getLogger(EventsService.class); - - private static EventsService extensionInstance; - private JenkinsMqmRestClientFactory clientFactory; - private EventsClient eventsClient; - - public static EventsService getExtensionInstance() { - if (extensionInstance == null) { - List extensions = Jenkins.getInstance().getExtensionList(EventsService.class); - if (extensions.isEmpty()) { - throw new RuntimeException("events service was not initialized properly"); - } else if (extensions.size() > 1) { - throw new RuntimeException("events service expected to be singleton, found " + extensions.size() + " instances"); - } else { - extensionInstance = extensions.get(0); - } - } - return extensionInstance; - } - - public void updateClient(ServerConfiguration conf) { - if (conf.isValid()) { - if (eventsClient != null) { - eventsClient.update(conf); - } else { - eventsClient = new EventsClient(conf, clientFactory); - } - } else { - if (eventsClient != null) { - logger.info("empty / non-valid configuration submitted, disposing events client"); - eventsClient.dispose(); - eventsClient = null; - } - } - } - - public void wakeUpClient() { - if (eventsClient != null) { - eventsClient.activate(); - } - } - - public void dispatchEvent(CIEvent event) { - if (eventsClient != null) { - eventsClient.pushEvent(event); - } - } - - public List getStatus() { - if (eventsClient != null) { - return Collections.singletonList(eventsClient); - } else { - return Collections.emptyList(); - } - } - - public EventsClient getClient() { - return eventsClient; - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public void onChanged(ServerConfiguration conf, ServerConfiguration oldConf) { - updateClient(conf); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/ItemListenerImpl.java b/src/main/java/com/hp/application/automation/tools/octane/events/ItemListenerImpl.java deleted file mode 100644 index cc7a95b9a0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/ItemListenerImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import hudson.Extension; -import hudson.model.Item; -import hudson.model.listeners.ItemListener; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/08/14 - * Time: 17:21 - * To change this template use File | Settings | File Templates. - */ - -@Extension -public final class ItemListenerImpl extends ItemListener { - private static final Logger logger = LogManager.getLogger(ItemListenerImpl.class); - - public void onRenamed(Item item, String oldName, String newName) { - logger.info("Renamed for: " + oldName + " => " + newName); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/QueueListenerImpl.java b/src/main/java/com/hp/application/automation/tools/octane/events/QueueListenerImpl.java deleted file mode 100644 index 06275c0185..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/QueueListenerImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.events.CIEvent; -import com.hp.octane.integrations.dto.events.CIEventType; -import com.hp.application.automation.tools.octane.model.CIEventCausesFactory; -import hudson.Extension; -import hudson.model.AbstractProject; -import hudson.model.Queue; -import hudson.model.queue.QueueListener; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 31/08/14 - * Time: 13:25 - * To change this template use File | Settings | File Templates. - */ - -@Extension -public final class QueueListenerImpl extends QueueListener { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @Override - public void onEnterWaiting(Queue.WaitingItem wi) { - AbstractProject project; - if (wi.task instanceof AbstractProject) { - project = (AbstractProject) wi.task; - CIEvent event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.QUEUED) - .setProject(project.getName()) - .setProjectDisplayName(project.getName()) - .setCauses(CIEventCausesFactory.processCauses(wi.getCauses())); - // REMARK: temporary decided to not send QUEUED event - //EventsDispatcher.getExtensionInstance().dispatchEvent(event); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/RunListenerImpl.java b/src/main/java/com/hp/application/automation/tools/octane/events/RunListenerImpl.java deleted file mode 100644 index f9b64be5e9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/RunListenerImpl.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.google.inject.Inject; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.events.CIEvent; -import com.hp.octane.integrations.dto.events.CIEventType; -import com.hp.octane.integrations.dto.events.PhaseType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import com.hp.octane.integrations.dto.snapshots.CIBuildResult; -import com.hp.application.automation.tools.octane.model.CIEventCausesFactory; -import com.hp.application.automation.tools.octane.model.processors.builders.WorkFlowRunProcessor; -import com.hp.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; -import com.hp.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; -import com.hp.application.automation.tools.octane.tests.TestListener; -import hudson.Extension; -import hudson.matrix.MatrixConfiguration; -import hudson.matrix.MatrixRun; -import hudson.model.*; -import hudson.model.listeners.RunListener; -import jenkins.model.Jenkins; -import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import javax.annotation.Nonnull; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/08/14 - * Time: 17:21 - */ - -@Extension -@SuppressWarnings({"squid:S2259","squid:S1872","squid:S1698","squid:S1132"}) -public final class RunListenerImpl extends RunListener { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - private ExecutorService executor = new ThreadPoolExecutor(0, 5, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue()); - - @Inject - private TestListener testListener; - - @Override - public void onStarted(final Run r, TaskListener listener) { - CIEvent event; - if (r.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowRun")) { - event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.STARTED) - .setProject(JobProcessorFactory.getFlowProcessor(r.getParent()).getJobCiId()) - .setBuildCiId(String.valueOf(r.getNumber())) - .setNumber(String.valueOf(r.getNumber())) - .setStartTime(r.getStartTimeInMillis()) - .setPhaseType(PhaseType.POST) - .setEstimatedDuration(r.getEstimatedDuration()) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(r))); - EventsService.getExtensionInstance().dispatchEvent(event); - WorkFlowRunProcessor workFlowRunProcessor = new WorkFlowRunProcessor(r); - workFlowRunProcessor.registerEvents(executor, this); - } else { - if (r.getParent() instanceof MatrixConfiguration) { - AbstractBuild build = (AbstractBuild) r; - event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.STARTED) - .setProject(getJobCiId(r)) - .setProjectDisplayName(getJobCiId(r)) - .setBuildCiId(String.valueOf(build.getNumber())) - .setNumber(String.valueOf(build.getNumber())) - .setStartTime(build.getStartTimeInMillis()) - .setEstimatedDuration(build.getEstimatedDuration()) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(build))) - .setParameters(ParameterProcessors.getInstances(build)); - if (isInternal(r)) { - event.setPhaseType(PhaseType.INTERNAL); - } else { - event.setPhaseType(PhaseType.POST); - } - EventsService.getExtensionInstance().dispatchEvent(event); - } else if (r instanceof AbstractBuild) { - AbstractBuild build = (AbstractBuild) r; - event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.STARTED) - .setProject(getJobCiId(r)) - .setProjectDisplayName(getJobCiId(r)) - .setBuildCiId(String.valueOf(build.getNumber())) - .setNumber(String.valueOf(build.getNumber())) - .setStartTime(build.getStartTimeInMillis()) - .setEstimatedDuration(build.getEstimatedDuration()) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(build))) - .setParameters(ParameterProcessors.getInstances(build)); - if (isInternal(r)) { - event.setPhaseType(PhaseType.INTERNAL); - } else { - event.setPhaseType(PhaseType.POST); - } - EventsService.getExtensionInstance().dispatchEvent(event); - } - } - } - - @Override - public void onCompleted(Run r, @Nonnull TaskListener listener) { - CIBuildResult result; - if (r.getResult() == Result.SUCCESS) { - result = CIBuildResult.SUCCESS; - } else if (r.getResult() == Result.ABORTED) { - result = CIBuildResult.ABORTED; - } else if (r.getResult() == Result.FAILURE) { - result = CIBuildResult.FAILURE; - } else if (r.getResult() == Result.UNSTABLE) { - result = CIBuildResult.UNSTABLE; - } else { - result = CIBuildResult.UNAVAILABLE; - } - CIEvent event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.FINISHED) - .setProject(getJobCiId(r)) - .setProjectDisplayName(getJobCiId(r)) - .setBuildCiId(String.valueOf(r.getNumber())) - .setNumber(String.valueOf(r.getNumber())) - .setStartTime(r.getStartTimeInMillis()) - .setEstimatedDuration(r.getEstimatedDuration()) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(r))) - .setResult(result) - .setDuration(r.getDuration()); - - if (r instanceof AbstractBuild) { - event.setParameters(ParameterProcessors.getInstances(r)); - } - if(event!=null){ - EventsService.getExtensionInstance().dispatchEvent(event); - testListener.processBuild(r, listener); - } - } - - // TODO: [YG] this method should be part of causes factory or something like this, it is not suitable for merged build as well - private boolean isInternal(Run r) { - boolean result = false; - - // get upstream cause, if any - Cause.UpstreamCause upstreamCause = null; - for (Cause cause : (List) r.getCauses()) { - if (cause instanceof Cause.UpstreamCause) { - upstreamCause = (Cause.UpstreamCause) cause; - break; // TODO: here we are breaking the merged build support - } - } - - if (upstreamCause != null) { - String causeJobName = upstreamCause.getUpstreamProject(); - TopLevelItem parent = Jenkins.getInstance().getItem(causeJobName); - if (parent == null) { - if (causeJobName.contains("/") && !causeJobName.contains(",")) { - parent = getJobFromFolder(causeJobName); - if (parent == null) { - result = false; - } - } - } else { - if (parent.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - result = true; - } else { - List phases = JobProcessorFactory.getFlowProcessor((Job) parent).getInternals(); - for (PipelinePhase p : phases) { - for (PipelineNode n : p.getJobs()) { - if (n != null && n.getName().equals(r.getParent().getName())) { - return true; - } - } - } - return false; - } - } - } - - return result; - } - - private static TopLevelItem getJobFromFolder(String causeJobName) { - String newJobRefId = causeJobName.substring(0, causeJobName.indexOf('/')); - TopLevelItem item = Jenkins.getInstance().getItem(newJobRefId); - if (item != null) { - Collection allJobs = item.getAllJobs(); - for (Job job : allJobs) { - if (causeJobName.endsWith(job.getName())) { - return (TopLevelItem) job; - } - } - return null; - } - return null; - } - - private static String getJobCiId(Run r) { - if (r.getParent() instanceof MatrixConfiguration) { - return JobProcessorFactory.getFlowProcessor(((MatrixRun) r).getParentBuild().getParent()).getJobCiId(); - } - if (r.getParent().getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - return r.getParent().getName(); - } - return JobProcessorFactory.getFlowProcessor(((AbstractBuild) r).getProject()).getJobCiId(); - } - - private static List extractCauses(Run r) { - if (r.getParent() instanceof MatrixConfiguration) { - return ((MatrixRun) r).getParentBuild().getCauses(); - } - - return r.getCauses(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/events/SCMListenerImpl.java b/src/main/java/com/hp/application/automation/tools/octane/events/SCMListenerImpl.java deleted file mode 100644 index c7015927b6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/events/SCMListenerImpl.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessor; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.events.CIEvent; -import com.hp.octane.integrations.dto.events.CIEventType; -import com.hp.octane.integrations.dto.scm.SCMData; -import com.hp.application.automation.tools.octane.model.CIEventCausesFactory; -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessors; -import hudson.Extension; -import hudson.FilePath; -import hudson.matrix.MatrixConfiguration; -import hudson.matrix.MatrixRun; -import hudson.model.AbstractBuild; -import hudson.model.Cause; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.model.listeners.SCMListener; -import hudson.scm.ChangeLogSet; -import hudson.scm.SCM; -import hudson.scm.SCMRevisionState; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.io.File; -import java.util.List; - -/** - * Created by gullery on 10/07/2016. - */ - -@Extension -@SuppressWarnings("squid:S1872") -public class SCMListenerImpl extends SCMListener { - private static final Logger logger = LogManager.getLogger(SCMListenerImpl.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - - @Override - public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener listener, File changelogFile, SCMRevisionState pollingBaseline) throws Exception { - super.onCheckout(build, scm, workspace, listener, changelogFile, pollingBaseline); - } - - @Override - public void onChangeLogParsed(Run r, SCM scm, TaskListener listener, ChangeLogSet changelog) throws Exception { - super.onChangeLogParsed(r, scm, listener, changelog); - CIEvent event; - if (r.getParent() instanceof MatrixConfiguration || r instanceof AbstractBuild) { - AbstractBuild build = (AbstractBuild) r; - if (changelog != null && !changelog.isEmptySet()) { // if there are any commiters - SCMProcessor scmProcessor = SCMProcessors.getAppropriate(scm.getClass().getName()); - if (scmProcessor != null) { - createSCMData(r, build, scmProcessor); - } else { - logger.info("SCM changes detected, but no processors found for SCM provider of type " + scm.getClass().getName()); - } - } - } - - else if (r.getParent() instanceof WorkflowJob) { - WorkflowRun wRun = (WorkflowRun)r; - if (changelog != null && !changelog.isEmptySet() || !wRun.getChangeSets().isEmpty()) { - SCMProcessor scmProcessor = SCMProcessors.getAppropriate(scm.getClass().getName()); - if (scmProcessor != null) { - List scmDataList = scmProcessor.getSCMData(wRun); - for (SCMData scmData : scmDataList) { - event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.SCM) - .setProject(getProjectName(r)) - .setBuildCiId(String.valueOf(r.getNumber())) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(r))) - .setNumber(String.valueOf(r.getNumber())) - .setScmData(scmData); - EventsService.getExtensionInstance().dispatchEvent(event); - } - } else { - logger.info("SCM changes detected, but no processors found for SCM provider of type " + scm.getClass().getName()); - } - } - } - } - - private void createSCMData(Run r, AbstractBuild build, SCMProcessor scmProcessor) { - CIEvent event; - SCMData scmData = scmProcessor.getSCMData(build); - event = dtoFactory.newDTO(CIEvent.class) - .setEventType(CIEventType.SCM) - .setProject(getProjectName(r)) - .setBuildCiId(String.valueOf(r.getNumber())) - .setCauses(CIEventCausesFactory.processCauses(extractCauses(r))) - .setNumber(String.valueOf(r.getNumber())) - .setScmData(scmData); - EventsService.getExtensionInstance().dispatchEvent(event); - } - - private String getProjectName(Run r) { - if (r.getParent() instanceof MatrixConfiguration) { - return ((MatrixRun) r).getParentBuild().getParent().getName(); - } - if ("org.jenkinsci.plugins.workflow.job.WorkflowJob".equals(r.getParent().getClass().getName())) { - return r.getParent().getName(); - } - return ((AbstractBuild) r).getProject().getName(); - } - - - private List extractCauses(Run r) { - if (r.getParent() instanceof MatrixConfiguration) { - return ((MatrixRun) r).getParentBuild().getCauses(); - } else { - return r.getCauses(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/CIEventCausesFactory.java b/src/main/java/com/hp/application/automation/tools/octane/model/CIEventCausesFactory.java deleted file mode 100644 index a8f2e35614..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/CIEventCausesFactory.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.causes.CIEventCause; -import com.hp.octane.integrations.dto.causes.CIEventCauseType; -import hudson.model.Cause; -import hudson.triggers.SCMTrigger; -import hudson.triggers.TimerTrigger; - -import java.util.LinkedList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 20/10/14 - * Time: 18:19 - * To change this template use File | Settings | File Templates. - */ - -public final class CIEventCausesFactory { - protected CIEventCausesFactory(){} - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - public static List processCauses(List causes) { - List result = new LinkedList<>(); - CIEventCause tmpResultCause; - Cause.UserIdCause tmpUserCause; - Cause.UpstreamCause tmpUpstreamCause; - - if (causes != null) { - for (Cause cause : causes) { - tmpResultCause = dtoFactory.newDTO(CIEventCause.class); - if (cause instanceof SCMTrigger.SCMTriggerCause) { - tmpResultCause.setType(CIEventCauseType.SCM); - } else if (cause instanceof TimerTrigger.TimerTriggerCause) { - tmpResultCause.setType(CIEventCauseType.TIMER); - } else if (cause instanceof Cause.UserIdCause) { - tmpUserCause = (Cause.UserIdCause) cause; - tmpResultCause.setType(CIEventCauseType.USER); - tmpResultCause.setUser(tmpUserCause.getUserId()); - } else if (cause instanceof Cause.UpstreamCause) { - tmpUpstreamCause = (Cause.UpstreamCause) cause; - tmpResultCause.setType(CIEventCauseType.UPSTREAM); - tmpResultCause.setProject(resolveJobCiId(tmpUpstreamCause.getUpstreamProject())); - tmpResultCause.setBuildCiId(String.valueOf(tmpUpstreamCause.getUpstreamBuild())); - tmpResultCause.setCauses(processCauses(tmpUpstreamCause.getUpstreamCauses())); - } else { - tmpResultCause.setType(CIEventCauseType.UNDEFINED); - } - result.add(tmpResultCause); - } - } - return result; - } - - private static String resolveJobCiId(String jobPlainName) { - if(jobPlainName.contains("/") && !jobPlainName.contains(",")) { - return jobPlainName.replaceAll("/", "/job/"); - } - return jobPlainName; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/ModelFactory.java b/src/main/java/com/hp/application/automation/tools/octane/model/ModelFactory.java deleted file mode 100644 index 71b346f7f0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/ModelFactory.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model; - -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessor; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.BuildHistory; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import com.hp.octane.integrations.dto.snapshots.CIBuildResult; -import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; -import com.hp.octane.integrations.dto.snapshots.SnapshotNode; -import com.hp.octane.integrations.dto.snapshots.SnapshotPhase; -import com.hp.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; -import com.hp.application.automation.tools.octane.model.processors.projects.AbstractProjectProcessor; -import com.hp.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; -import com.hp.application.automation.tools.octane.model.processors.scm.SCMProcessors; -import hudson.model.*; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.*; - -/** - * Created by lazara on 26/01/2016. - */ -public class ModelFactory { - private static final Logger logger = LogManager.getLogger(ModelFactory.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - public static PipelineNode createStructureItem(Job job) { - AbstractProjectProcessor projectProcessor = JobProcessorFactory.getFlowProcessor(job); - PipelineNode pipelineNode = dtoFactory.newDTO(PipelineNode.class); - pipelineNode.setJobCiId(projectProcessor.getJobCiId()); - pipelineNode.setName(job.getName()); - pipelineNode.setParameters(ParameterProcessors.getConfigs(job)); - pipelineNode.setPhasesInternal(projectProcessor.getInternals()); - pipelineNode.setPhasesPostBuild(projectProcessor.getPostBuilds()); - - return pipelineNode; - } - - public static PipelinePhase createStructurePhase(String name, boolean blocking, List items) { - PipelinePhase pipelinePhase = dtoFactory.newDTO(PipelinePhase.class); - pipelinePhase.setName(name); - pipelinePhase.setBlocking(blocking); - - PipelineNode[] tmp = new PipelineNode[items.size()]; - for (int i = 0; i < tmp.length; i++) { - if (items.get(i) != null) { - tmp[i] = ModelFactory.createStructureItem(items.get(i)); - - } else { - logger.warn("One of referenced jobs is null, your Jenkins config probably broken, skipping this job..."); - } - } - - pipelinePhase.setJobs(Arrays.asList(tmp)); - - return pipelinePhase; - } - - - public static SnapshotNode createSnapshotItem(Run build, boolean metaOnly) { - SnapshotNode snapshotNode = dtoFactory.newDTO(SnapshotNode.class); - SCMProcessor scmProcessor = null; - if (build.getParent() instanceof AbstractProject) { - scmProcessor = SCMProcessors.getAppropriate(((AbstractProject) build.getParent()).getScm().getClass().getName()); - } - - CIBuildStatus status = CIBuildStatus.FINISHED; - if (build.hasntStartedYet()) { - status = CIBuildStatus.QUEUED; - } else if (build.isBuilding()) { - status = CIBuildStatus.RUNNING; - } - - CIBuildResult result = CIBuildResult.UNAVAILABLE; - if (build.getResult() == Result.SUCCESS) { - result = CIBuildResult.SUCCESS; - } else if (build.getResult() == Result.ABORTED) { - result = CIBuildResult.ABORTED; - } else if (build.getResult() == Result.FAILURE) { - result = CIBuildResult.FAILURE; - } else if (build.getResult() == Result.UNSTABLE) { - result = CIBuildResult.UNSTABLE; - } - - if (!metaOnly) { - AbstractProjectProcessor flowProcessor = JobProcessorFactory.getFlowProcessor(build.getParent()); - List tmpPipelinePhasesInternals = flowProcessor.getInternals(); - List tmpPipelinePhasesPostBuilds = flowProcessor.getPostBuilds(); - ArrayList invokeesNames = new ArrayList(); - appendInvokeesNames(invokeesNames, tmpPipelinePhasesInternals); - appendInvokeesNames(invokeesNames, tmpPipelinePhasesPostBuilds); - HashMap> invokedBuilds = getInvokedBuilds(build, invokeesNames); - snapshotNode.setPhasesInternal((inflatePhases(tmpPipelinePhasesInternals, invokedBuilds))); - snapshotNode.setPhasesPostBuild(inflatePhases(tmpPipelinePhasesPostBuilds, invokedBuilds)); - } - - snapshotNode.setJobCiId(build.getParent().getName()); - snapshotNode.setName(build.getParent().getName()); - snapshotNode.setBuildCiId(String.valueOf(build.getNumber())); - snapshotNode.setNumber(String.valueOf(build.getNumber())); - snapshotNode.setCauses(CIEventCausesFactory.processCauses(build.getCauses())); - snapshotNode.setDuration(build.getDuration()); - snapshotNode.setEstimatedDuration(build.getEstimatedDuration()); - if (build instanceof AbstractBuild) { - snapshotNode.setScmData(scmProcessor == null ? null : scmProcessor.getSCMData((AbstractBuild) build)); - } - snapshotNode.setStartTime(build.getStartTimeInMillis()); - snapshotNode.setParameters(ParameterProcessors.getInstances(build)); - snapshotNode.setResult(result); - snapshotNode.setStatus(status); - - return snapshotNode; - } - - - public static SnapshotNode createSnapshotItem(Job project, boolean metaOnly) { - SnapshotNode snapshotNode = dtoFactory.newDTO(SnapshotNode.class); - AbstractProjectProcessor flowProcessor = JobProcessorFactory.getFlowProcessor(project); - snapshotNode.setJobCiId(flowProcessor.getJobCiId()); - snapshotNode.setName(project.getName()); - - if (!metaOnly) { - snapshotNode.setPhasesPostBuild(inflatePhases(flowProcessor.getPostBuilds(), null)); - snapshotNode.setPhasesInternal(inflatePhases(flowProcessor.getInternals(), null)); - } - return snapshotNode; - } - - private static void appendInvokeesNames(ArrayList list, List phases) { - for (PipelinePhase phase : phases) { - for (PipelineNode item : phase.getJobs()) { - if (item != null) { - if (!list.contains(item.getJobCiId())) list.add(item.getJobCiId()); - } else { - logger.error("null referenced project encountered; considering it as corrupted configuration and skipping"); - } - } - } - } - - private static HashMap> getInvokedBuilds(Run self, ArrayList invokeesNames) { - HashMap> result = new HashMap>(); - Job run; - for (String invokeeName : invokeesNames) { - run = (Job) Jenkins.getInstance().getItem(invokeeName); - result.put(invokeeName, getInvokees(self, run)); - } - return result; - } - - @SuppressWarnings("unchecked") - private static ArrayList getInvokees(Run invoker, Job job) { - ArrayList result = new ArrayList(); - Cause.UpstreamCause tmpCause; - for (Object o : job.getBuilds()) { - Run tmpRun = (Run) o; - for (Cause cause : (List) tmpRun.getCauses()) { - if (!(cause instanceof Cause.UpstreamCause)) continue; - - tmpCause = (Cause.UpstreamCause) cause; - if (tmpCause.pointsTo(invoker)) { - result.add(0, tmpRun); - } else if (tmpCause.pointsTo(invoker.getParent()) && tmpCause.getUpstreamBuild() < invoker.getNumber()) { - return result; - } - } - } - return result; - } - - private static List inflatePhases(List structures, HashMap> invokedBuilds) { - List phases = new ArrayList(); - for (int i = 0; i < structures.size(); i++) { - phases.add(i, createSnapshotPhase(structures.get(i), invokedBuilds)); - } - return phases; - } - - public static SnapshotPhase createSnapshotPhase(PipelinePhase pipelinePhase, HashMap> invokedBuilds) { - SnapshotPhase snapshotPhase = dtoFactory.newDTO(SnapshotPhase.class); - snapshotPhase.setName(pipelinePhase.getName()); - snapshotPhase.setBlocking(pipelinePhase.isBlocking()); - - ArrayList tmpBuilds; - List structures = pipelinePhase.getJobs(); - List tmp = new ArrayList(); - - for (int i = 0; i < structures.size(); i++) { - if (structures.get(i) != null) { - tmpBuilds = invokedBuilds == null ? null : invokedBuilds.get(structures.get(i).getJobCiId()); - if (tmpBuilds == null || tmpBuilds.size() == 0) { - tmp.add(i, createSnapshotItem((Job) Jenkins.getInstance().getItem(structures.get(i).getJobCiId()), false)); - } else { - tmp.add(i, createSnapshotItem(tmpBuilds.get(0), false)); - tmpBuilds.remove(0); - } - } else { - logger.warn("One of referenced jobs is null, your Jenkins config probably broken, skipping the build info for this job..."); - } - } - snapshotPhase.setBuilds(tmp); - - return snapshotPhase; - } - - - public static BuildHistory.SCMUser createScmUser(User user) { - BuildHistory.SCMUser scmUser = new BuildHistory.SCMUser(); - scmUser.setDisplayName(user.getDisplayName()); - scmUser.setFullName(user.getFullName()); - scmUser.setId(user.getId()); - - return scmUser; - } - - public static Set createScmUsersList(Set users) { - Set userList = new HashSet(); - if (users != null) { - for (User user : users) { - userList.add(ModelFactory.createScmUser(user)); - } - } - return userList; - } - - - public static CIParameter createParameterConfig(ParameterDefinition pd) { - return createParameterConfig(pd, CIParameterType.UNKNOWN, null, null); - } - - public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type) { - return createParameterConfig( - pd, - type, - pd.getDefaultParameterValue() == null ? null : pd.getDefaultParameterValue().getValue(), - null); - } - - public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type, Object defaultValue) { - return createParameterConfig(pd, type, defaultValue, null); - } - - public static CIParameter createParameterConfig(String name, CIParameterType type, List choices) { - CIParameter ciParameter = dtoFactory.newDTO(CIParameter.class); - ciParameter.setName(name); - ciParameter.setType(type); - ciParameter.setDescription(""); - ciParameter.setChoices(choices.toArray()); - return ciParameter; - } - - public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type, Object defaultValue, List choices) { - CIParameter ciParameter = dtoFactory.newDTO(CIParameter.class); - ciParameter.setName(pd.getName()); - ciParameter.setType(type); - ciParameter.setDescription(pd.getDescription()); - ParameterValue tmp; - if (type != CIParameterType.UNKNOWN && type != CIParameterType.PASSWORD) { - if (defaultValue != null) { - ciParameter.setDefaultValue(defaultValue); - } else { - tmp = pd.getDefaultParameterValue(); - ciParameter.setDefaultValue(tmp == null ? "" : tmp.getValue()); - } - if (choices != null) { - ciParameter.setChoices(choices.toArray()); - } - } - - return ciParameter; - } - - - public static CIParameter createParameterInstance(CIParameter pc, Object rawValue) { - String value = rawValue == null ? null : rawValue.toString(); - return dtoFactory.newDTO(CIParameter.class) - .setName(pc.getName()) - .setType(pc.getType()) - .setDescription(pc.getDescription()) - .setChoices(pc.getChoices()) - .setDescription(pc.getDescription()) - .setDefaultValue(pc.getDefaultValue()) - .setValue(value); - } - - public static String generateSubBuildName(List parameters) { - List sortedList = new ArrayList<>(); - for (CIParameter p : parameters) { - if (p.getType() == CIParameterType.AXIS) { - sortedList.add(p); - } - } - - Collections.sort(sortedList, new Comparator() { - @Override - public int compare(CIParameter p1, CIParameter p2) { - return p1.getName().compareTo(p2.getName()); - } - }); - - String subBuildName = ""; - if (sortedList.size() > 0) { - int i = 0; - for (; i < sortedList.size() - 1; i++) { - subBuildName += sortedList.get(i).getName() + "=" + sortedList.get(i).getValue().toString() + ","; - } - subBuildName += sortedList.get(i).getName() + "=" + sortedList.get(i).getValue().toString(); - } - return subBuildName; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java deleted file mode 100644 index 5e43314224..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.builders; - - -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 09/01/15 - * Time: 00:59 - * To change this template use File | Settings | File Templates. - */ - -public abstract class AbstractBuilderProcessor { - protected ArrayList phases = new ArrayList(); - - public List getPhases() { - return phases; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java deleted file mode 100644 index a9c2c4ba4b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.builders; - -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.AbstractProject; -import hudson.tasks.BuildTrigger; -import hudson.tasks.Publisher; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 08/01/15 - * Time: 23:01 - * To change this template use File | Settings | File Templates. - */ - -public class BuildTriggerProcessor extends AbstractBuilderProcessor { - private static final Logger logger = LogManager.getLogger(BuildTriggerProcessor.class); - - public BuildTriggerProcessor(Publisher publisher, AbstractProject project) { - BuildTrigger t = (BuildTrigger) publisher; - super.phases = new ArrayList<>(); - List items = t.getChildProjects(project.getParent()); - for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { - AbstractProject next = iterator.next(); - if (next == null) { - iterator.remove(); - logger.warn("encountered null project reference; considering it as corrupted configuration and skipping"); - } - } - super.phases.add(ModelFactory.createStructurePhase("downstream", false, items)); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java deleted file mode 100644 index 08769dcda2..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.builders; - -import com.hp.application.automation.tools.octane.model.ModelFactory; -import com.tikal.jenkins.plugins.multijob.MultiJobBuilder; -import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig; -import hudson.model.AbstractProject; -import hudson.tasks.Builder; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 08/01/15 - * Time: 23:02 - * To change this template use File | Settings | File Templates. - */ - -public class MultiJobBuilderProcessor extends AbstractBuilderProcessor { - private static final Logger logger = LogManager.getLogger(MultiJobBuilderProcessor.class); - - public MultiJobBuilderProcessor(Builder builder) { - MultiJobBuilder b = (MultiJobBuilder) builder; - super.phases = new ArrayList<>(); - List items = new ArrayList<>(); - AbstractProject tmpProject; - for (PhaseJobsConfig config : b.getPhaseJobs()) { - tmpProject = (AbstractProject) Jenkins.getInstance().getItem(config.getJobName()); - if (tmpProject != null) { - items.add(tmpProject); - } else { - logger.warn("project named '" + config.getJobName() + "' not found; considering this as corrupted configuration and skipping the project"); - } - } - super.phases.add(ModelFactory.createStructurePhase(b.getPhaseName(), true, items)); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java deleted file mode 100644 index 7ef4f743d4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.builders; - -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.AbstractProject; -import hudson.model.Job; -import hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig; -import hudson.plugins.parameterizedtrigger.BuildTrigger; -import hudson.plugins.parameterizedtrigger.BuildTriggerConfig; -import hudson.plugins.parameterizedtrigger.TriggerBuilder; -import hudson.tasks.Builder; -import hudson.tasks.Publisher; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 08/01/15 - * Time: 23:01 - * To change this template use File | Settings | File Templates. - */ - -public class ParameterizedTriggerProcessor extends AbstractBuilderProcessor { - private static final Logger logger = LogManager.getLogger(ParameterizedTriggerProcessor.class); - - public ParameterizedTriggerProcessor(Builder builder, Job job, String phasesName) { - TriggerBuilder b = (TriggerBuilder) builder; - super.phases = new ArrayList<>(); - List items; - for (BlockableBuildTriggerConfig config : b.getConfigs()) { - items = config.getProjectList(job.getParent(), null); - for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { - AbstractProject next = iterator.next(); - if (next == null) { - iterator.remove(); - logger.warn("encountered null project reference; considering it as corrupted configuration and skipping"); - } - } - super.phases.add(ModelFactory.createStructurePhase(phasesName, config.getBlock() != null, items)); - } - } - - public ParameterizedTriggerProcessor(Publisher publisher, AbstractProject project, String phasesName) { - BuildTrigger t = (BuildTrigger) publisher; - super.phases = new ArrayList<>(); - List items; - for (BuildTriggerConfig config : t.getConfigs()) { - items = config.getProjectList(project.getParent(), null); - for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { - AbstractProject next = iterator.next(); - if (next == null) { - iterator.remove(); - logger.warn("encountered null project reference; considering it as corrupted configuration and skipping"); - } - } - super.phases.add(ModelFactory.createStructurePhase(phasesName, false, items)); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/WorkFlowRunProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/WorkFlowRunProcessor.java deleted file mode 100644 index 981d5d5b25..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/builders/WorkFlowRunProcessor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.builders; - -import com.google.common.util.concurrent.ListenableFuture; -import com.hp.application.automation.tools.octane.events.RunListenerImpl; -import com.hp.application.automation.tools.octane.workflow.WorkflowGraphListener; -import hudson.model.Run; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.workflow.flow.FlowExecution; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; - -/** - * Created by gadiel on 21/07/2016. - */ - -public class WorkFlowRunProcessor { - private static final Logger logger = LogManager.getLogger(WorkFlowRunProcessor.class); - WorkflowRun workFlowRun; - - public WorkFlowRunProcessor(Run r) { - this.workFlowRun = (WorkflowRun) r; - } - - public void registerEvents(ExecutorService executor, final RunListenerImpl runListener) { - ListenableFuture promise = workFlowRun.getExecutionPromise(); - promise.addListener(new Runnable() { - @Override - public void run() { - try { - FlowExecution ex = workFlowRun.getExecutionPromise().get(); - ex.addListener(new WorkflowGraphListener()); - } catch (InterruptedException ie) { - logger.error("failed to obtain execution promise of " + workFlowRun, ie); - } catch (ExecutionException ee) { - logger.error("failed to obtain execution promise of " + workFlowRun, ee); - } - } - }, executor); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java deleted file mode 100644 index 5427a67f55..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.parameters.CIParameter; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; - -/** - * Created by gullery on 19/02/2015. - */ -public abstract class AbstractParametersProcessor { - public abstract CIParameter createParameterConfig(ParameterDefinition pd); - - public abstract CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv); -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/DynamicParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/DynamicParameterProcessor.java deleted file mode 100644 index 4bd3a8004a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/DynamicParameterProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import com.seitenbau.jenkins.plugins.dynamicparameter.ChoiceParameterDefinition; -import com.seitenbau.jenkins.plugins.dynamicparameter.StringParameterDefinition; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; - -/** - * Created by gullery on 19/02/2015. - */ - -public class DynamicParameterProcessor extends AbstractParametersProcessor { - DynamicParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - if (pd instanceof StringParameterDefinition) { - StringParameterDefinition stringPd = (StringParameterDefinition) pd; - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING); - } else if (pd instanceof ChoiceParameterDefinition) { - ChoiceParameterDefinition choicePd = (ChoiceParameterDefinition) pd; - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, null, choicePd.getChoices()); - } else { - return ModelFactory.createParameterConfig(pd); - } - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - Object value = pv == null ? null : pv.getValue(); - return ModelFactory.createParameterInstance(createParameterConfig(pd), value); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java deleted file mode 100644 index 7f989f3554..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterDefinition; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by gullery on 19/02/2015. - */ - -public class ExtendedChoiceParameterProcessor extends AbstractParametersProcessor { - ExtendedChoiceParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - ExtendedChoiceParameterDefinition extChoice = (ExtendedChoiceParameterDefinition) pd; - Map choicesMap; - List choices = new ArrayList(); - try { - choicesMap = extChoice.getChoicesByDropdownId(); - } catch (Exception e) { - choicesMap = null; - } - if (choicesMap != null) { - choices = new ArrayList(choicesMap.values()); - } - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, null, choices); - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - Object value = pv == null ? null : pv.getValue(); - return ModelFactory.createParameterInstance(createParameterConfig(pd), value); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java deleted file mode 100644 index c2df42f338..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.*; - -import java.util.ArrayList; - -/** - * Created by gullery on 19/02/2015. - */ - -public class InherentParameterProcessor extends AbstractParametersProcessor { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - InherentParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - CIParameter result; - if (pd instanceof BooleanParameterDefinition) { - result = ModelFactory.createParameterConfig(pd, CIParameterType.BOOLEAN); - } else if (pd instanceof TextParameterDefinition) { - result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING); - } else if (pd instanceof StringParameterDefinition) { - result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING); - } else if (pd instanceof ChoiceParameterDefinition) { - ChoiceParameterDefinition choicePd = (ChoiceParameterDefinition) pd; - result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING, null, new ArrayList(choicePd.getChoices())); - } else if (pd instanceof PasswordParameterDefinition) { - PasswordParameterDefinition passPd = (PasswordParameterDefinition) pd; - result = ModelFactory.createParameterConfig(pd, CIParameterType.PASSWORD, passPd.getDefaultValue()); - } else if (pd instanceof FileParameterDefinition) { - result = ModelFactory.createParameterConfig(pd, CIParameterType.FILE); - } else { - result = new UnsupportedParameterProcessor().createParameterConfig(pd); - } - return result; - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - CIParameter result; - CIParameter pc = createParameterConfig(pd); - Object value = pv == null ? null : pv.getValue(); - if (pd instanceof BooleanParameterDefinition) { - result = ModelFactory.createParameterInstance(pc, value); - } else if (pd instanceof TextParameterDefinition) { - result = ModelFactory.createParameterInstance(pc, value); - } else if (pd instanceof StringParameterDefinition) { - result = ModelFactory.createParameterInstance(pc, value); - } else if (pd instanceof ChoiceParameterDefinition) { - result = ModelFactory.createParameterInstance(pc, value); - } else if (pd instanceof PasswordParameterDefinition) { - result = dtoFactory.newDTO(CIParameter.class) - .setType(pc.getType()) - .setName(pc.getName()) - .setDescription(pc.getDescription()) - .setChoices(pc.getChoices()) - .setDefaultValue(pc.getDefaultValue()) - .setValue(null); - } else if (pd instanceof FileParameterDefinition) { - FileParameterValue filePv = (FileParameterValue) pv; - result = dtoFactory.newDTO(CIParameter.class) - .setType(pc.getType()) - .setName(pc.getName()) - .setDescription(pc.getDescription()) - .setChoices(pc.getChoices()) - .setDefaultValue(pc.getDefaultValue()) - .setValue(filePv != null ? filePv.getOriginalFileName() : null); - } else { - result = new UnsupportedParameterProcessor().createParameterInstance(pd, pv); - } - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java deleted file mode 100644 index 782708eb0c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; -import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition; -import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue; -import org.jvnet.jenkins.plugins.nodelabelparameter.NodeParameterDefinition; -import org.jvnet.jenkins.plugins.nodelabelparameter.NodeParameterValue; - -import java.util.ArrayList; - -/** - * Created by gullery on 19/02/2015. - */ - -public class NodeLabelParameterProcessor extends AbstractParametersProcessor { - NodeLabelParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - if (pd instanceof NodeParameterDefinition) { - NodeParameterDefinition nodePd = (NodeParameterDefinition) pd; - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, new ArrayList(nodePd.allowedSlaves)); - } else if (pd instanceof LabelParameterDefinition) { - LabelParameterDefinition labelPd = (LabelParameterDefinition) pd; - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING); - } else { - return ModelFactory.createParameterConfig(pd); - } - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - Object value = null; - if (pv instanceof NodeParameterValue) { - value = ((NodeParameterValue) pv).getLabel(); - } else if (pv instanceof LabelParameterValue) { - value = ((LabelParameterValue) pv).getLabel(); - } - return ModelFactory.createParameterInstance(createParameterConfig(pd), value); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java deleted file mode 100644 index a1a6f022cc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.matrix.*; -import hudson.model.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by gullery on 26/03/2015. - */ - -public enum ParameterProcessors { - // DYNAMIC("com.seitenbau.jenkins.plugins.dynamicparameter", DynamicParameterProcessor.class), - EXTENDED("com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterDefinition", ExtendedChoiceParameterProcessor.class), - INHERENT("hudson.model", InherentParameterProcessor.class), - NODE_LABEL("org.jvnet.jenkins.plugins.nodelabelparameter", NodeLabelParameterProcessor.class), - RANDOM_STRING("hudson.plugins.random_string_parameter.RandomStringParameterDefinition", RandomStringParameterProcessor.class); - - private static final Logger logger = LogManager.getLogger(ParameterProcessors.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - private String targetPluginClassName; - private Class processorClass; - - ParameterProcessors(String targetPluginClassName, Class processorClass) { - this.targetPluginClassName = targetPluginClassName; - this.processorClass = processorClass; - } - - public static List getConfigs(Job job) { - ArrayList result = new ArrayList<>(); - List paramDefinitions; - ParameterDefinition pd; - String className; - AbstractParametersProcessor processor; - if (job.getProperty(ParametersDefinitionProperty.class) != null) { - paramDefinitions = ((ParametersDefinitionProperty) job.getProperty(ParametersDefinitionProperty.class)).getParameterDefinitions(); - for (int i = 0; i < paramDefinitions.size(); i++) { - pd = paramDefinitions.get(i); - className = pd.getClass().getName(); - processor = getAppropriate(className); - result.add(processor.createParameterConfig(pd)); - } - } - - if (job instanceof MatrixProject) { - AxisList axisList = ((MatrixProject) job).getAxes(); - for (Axis axis : axisList) { - result.add(ModelFactory.createParameterConfig(axis.getName(), CIParameterType.AXIS, new ArrayList(axis.getValues()))); - } - } - - return result; - } - - // TODO: the below mapping between param configs and values based on param name uniqueness, beware! - public static List getInstances(Run run) { - List result = new ArrayList<>(); - CIParameter tmp; - Job job = run.getParent(); - List paramDefinitions; - String className; - - AbstractParametersProcessor processor; - List parametersValues; - ParametersAction parametersAction = run.getAction(ParametersAction.class); - if (parametersAction != null) { - parametersValues = new ArrayList<>(parametersAction.getParameters()); - } else { - parametersValues = new ArrayList<>(); - } - ParameterValue pv; - - // TODO: should be moved to the Matrix Project processor - if (job instanceof MatrixConfiguration) { - Combination combination = ((MatrixConfiguration) job).getCombination(); - for (Map.Entry entry : combination.entrySet()) { - tmp = dtoFactory.newDTO(CIParameter.class) - .setType(CIParameterType.AXIS) - .setName(entry.getKey()) - .setValue(entry.getValue()); - result.add(tmp); - } - } - - if (job.getProperty(ParametersDefinitionProperty.class) != null) { - paramDefinitions = ((ParametersDefinitionProperty) job.getProperty(ParametersDefinitionProperty.class)).getParameterDefinitions(); - for (ParameterDefinition pd : paramDefinitions) { - className = pd.getClass().getName(); - pv = null; - - try { - for (int j = 0; j < parametersValues.size(); j++) { - if (parametersValues.get(j) != null && parametersValues.get(j).getName().equals(pd.getName())) { - pv = parametersValues.get(j); - parametersValues.remove(j); - break; - } - } - processor = getAppropriate(className); - result.add(processor.createParameterInstance(pd, pv)); - } catch (Exception e) { - logger.error("failed to process instance of parameter or type '" + className + "', adding as unsupported", e); - result.add(new UnsupportedParameterProcessor().createParameterInstance(pd, pv)); - } - } - } - - return result; - - } - - private static AbstractParametersProcessor getAppropriate(String className) { - for (ParameterProcessors p : values()) { - if (className.startsWith(p.targetPluginClassName)) { - try { - return p.processorClass.newInstance(); - } catch (InstantiationException ie) { - logger.error("failed to instantiate instance of parameters processor of type " + className, ie); - } catch (IllegalAccessException iae) { - logger.error("failed to instantiate instance of parameters processor of type " + className, iae); - } - } - } - return new UnsupportedParameterProcessor(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java deleted file mode 100644 index 2ea1b0a1a0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; - -/** - * Created by gullery on 19/02/2015. - */ - -public class RandomStringParameterProcessor extends AbstractParametersProcessor { - RandomStringParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - return ModelFactory.createParameterConfig(pd, CIParameterType.STRING); - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - Object value = pv == null ? null : pv.getValue(); - return ModelFactory.createParameterInstance(createParameterConfig(pd), value); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java deleted file mode 100644 index a007d5d8e6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.parameters; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import hudson.model.ParameterDefinition; -import hudson.model.ParameterValue; - -/** - * Created by gullery on 19/02/2015. - */ - -public class UnsupportedParameterProcessor extends AbstractParametersProcessor { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - UnsupportedParameterProcessor() { - } - - @Override - public CIParameter createParameterConfig(ParameterDefinition pd) { - return ModelFactory.createParameterConfig(pd); - } - - @Override - public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { - return dtoFactory.newDTO(CIParameter.class) - .setType(CIParameterType.UNKNOWN) - .setName(pd.getName()) - .setDescription(pd.getDescription()) - .setDefaultValue(pd.getDefaultParameterValue() != null ? pd.getDefaultParameterValue().getValue() : null); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java deleted file mode 100644 index 243735759f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import com.hp.application.automation.tools.octane.model.processors.builders.AbstractBuilderProcessor; -import com.hp.application.automation.tools.octane.model.processors.builders.BuildTriggerProcessor; -import com.hp.application.automation.tools.octane.model.processors.builders.MultiJobBuilderProcessor; -import com.hp.application.automation.tools.octane.model.processors.builders.ParameterizedTriggerProcessor; -import hudson.model.AbstractProject; -import hudson.model.Job; -import hudson.tasks.BuildStep; -import hudson.tasks.Builder; -import hudson.tasks.Publisher; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuilder; -import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 09/01/15 - * Time: 00:59 - * To change this template use File | Settings | File Templates. - */ - -@SuppressWarnings({"squid:S1132","squid:S1872"}) -public abstract class AbstractProjectProcessor { - private static final Logger logger = LogManager.getLogger(AbstractProjectProcessor.class); - private final List internals = new ArrayList<>(); - private final List postBuilds = new ArrayList<>(); - - T job; - - AbstractProjectProcessor(T job) { - this.job = job; - } - - // PUBLIC APIs - // - public abstract List tryGetBuilders(); - - public abstract void scheduleBuild(String parametersBody); - - public String getJobCiId() { - if (job.getParent().getClass().getName().equals("com.cloudbees.hudson.plugins.folder.Folder")) { - String jobPlainName = job.getFullName(); // e.g: myFolder/myJob - return jobPlainName.replaceAll("/", "/job/"); - } else { - return job.getName(); - } - } - - public List getInternals() { - return internals; - } - - public List getPostBuilds() { - return postBuilds; - } - - // INTERNALS - // - void processBuilders(List builders, Job job) { - this.processBuilders(builders, job, ""); - } - - void processBuilders(List builders, Job job, String phasesName) { - for (Builder builder : builders) { - builderClassValidator(builder, job, phasesName); - } - } - - @SuppressWarnings("unchecked") - void processPublishers(Job job) { - if (job instanceof AbstractProject) { - AbstractProject project = (AbstractProject) job; - AbstractBuilderProcessor builderProcessor; - List publishers = project.getPublishersList(); - for (Publisher publisher : publishers) { - builderProcessor = null; - if (publisher.getClass().getName().equals("hudson.tasks.BuildTrigger")) { - builderProcessor = new BuildTriggerProcessor(publisher, project); - } else if (publisher.getClass().getName().equals("hudson.plugins.parameterizedtrigger.BuildTrigger")) { - builderProcessor = new ParameterizedTriggerProcessor(publisher, project, ""); - } - if (builderProcessor != null) { - postBuilds.addAll(builderProcessor.getPhases()); - } else { - logger.debug("not yet supported publisher (post build) action: " + publisher.getClass().getName()); - } - } - } - } - - private void builderClassValidator(Builder builder, Job job, String phasesName) { - AbstractBuilderProcessor builderProcessor = null; - if (builder.getClass().getName().equals("org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuilder")) { - ConditionalBuilder conditionalBuilder = (ConditionalBuilder) builder; - for (BuildStep currentBuildStep : conditionalBuilder.getConditionalbuilders()) { - builderClassValidator((Builder) currentBuildStep, job, phasesName); - } - } else if (builder.getClass().getName().equals("org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder")) { - SingleConditionalBuilder singleConditionalBuilder = (SingleConditionalBuilder) builder; - builderClassValidator((Builder) singleConditionalBuilder.getBuildStep(), job, phasesName); - } else if (builder.getClass().getName().equals("hudson.plugins.parameterizedtrigger.TriggerBuilder")) { - builderProcessor = new ParameterizedTriggerProcessor(builder, job, phasesName); - } else if (builder.getClass().getName().equals("com.tikal.jenkins.plugins.multijob.MultiJobBuilder")) { - builderProcessor = new MultiJobBuilderProcessor(builder); - } - - if (builderProcessor != null) { - internals.addAll(builderProcessor.getPhases()); - } else { - logger.debug("not yet supported build (internal) action: " + builder.getClass().getName()); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java deleted file mode 100644 index d1b572ac83..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import hudson.model.FreeStyleProject; -import hudson.model.Job; -import hudson.tasks.Builder; - -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:47 - * To change this template use File | Settings | File Templates. - */ - -class FreeStyleProjectProcessor extends AbstractProjectProcessor { - - FreeStyleProjectProcessor(Job job) { - super((FreeStyleProject) job); - - // Internal phases - // - super.processBuilders(this.job.getBuilders(), this.job); - - // Post build phases - // - super.processPublishers(this.job); - } - - @Override - public List tryGetBuilders() { - return job.getBuilders(); - } - - @Override - public void scheduleBuild(String parametersBody) { - throw new RuntimeException("non yet implemented"); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java deleted file mode 100644 index ce4329f400..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import hudson.model.Job; - -/** - * Created by gadiel on 30/11/2016. - * - * Job processors factory - should be used as a 'static' class, no instantiation, only static method/s - */ - -public class JobProcessorFactory { - - private JobProcessorFactory() { - } - - public static AbstractProjectProcessor getFlowProcessor(T job) { - AbstractProjectProcessor flowProcessor; - - if (job.getClass().getName().equals("hudson.model.FreeStyleProject")) { - flowProcessor = new FreeStyleProjectProcessor(job); - } else if (job.getClass().getName().equals("hudson.matrix.MatrixProject")) { - flowProcessor = new MatrixProjectProcessor(job); - } else if (job.getClass().getName().equals("hudson.maven.MavenModuleSet")) { - flowProcessor = new MavenProjectProcessor(job); - } else if (job.getClass().getName().equals("com.tikal.jenkins.plugins.multijob.MultiJobProject")) { - flowProcessor = new MultiJobProjectProcessor(job); - } else if (job.getClass().getName().equals("org.jenkinsci.plugins.workflow.job.WorkflowJob")) { - flowProcessor = new WorkFlowJobProcessor(job); - } else { - flowProcessor = new UnsupportedProjectProcessor(job); - } - return flowProcessor; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java deleted file mode 100644 index 30c8241190..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import hudson.matrix.MatrixProject; -import hudson.model.Job; -import hudson.tasks.Builder; - -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:30 - * To change this template use File | Settings | File Templates. - */ - -class MatrixProjectProcessor extends AbstractProjectProcessor { - - MatrixProjectProcessor(Job project) { - super((MatrixProject) project); - - // Internal phases - // - super.processBuilders(this.job.getBuilders(), this.job); - - // Post build phases - // - super.processPublishers(this.job); - } - - @Override - public List tryGetBuilders() { - return job.getBuilders(); - } - - @Override - public void scheduleBuild(String parametersBody) { - throw new RuntimeException("non yet implemented"); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java deleted file mode 100644 index 2fd11bea78..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import hudson.maven.MavenModuleSet; -import hudson.model.Job; -import hudson.tasks.Builder; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:35 - * To change this template use File | Settings | File Templates. - */ - -class MavenProjectProcessor extends AbstractProjectProcessor { - - MavenProjectProcessor(Job mavenJob) { - super((MavenModuleSet) mavenJob); - // Internal phases - pre maven phases - // - super.processBuilders(this.job.getPrebuilders(), this.job, "pre-maven"); - - // Internal phases - post maven phases - // - super.processBuilders(this.job.getPostbuilders(), this.job, "post-maven"); - - // Post build phases - // - super.processPublishers(this.job); - } - - @Override - public List tryGetBuilders() { - return new ArrayList<>(); - } - - @Override - public void scheduleBuild(String parametersBody) { - throw new RuntimeException("non yet implemented"); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java deleted file mode 100644 index dac4959b62..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import com.tikal.jenkins.plugins.multijob.MultiJobProject; -import hudson.model.Job; -import hudson.tasks.Builder; - -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:40 - * To change this template use File | Settings | File Templates. - */ - -class MultiJobProjectProcessor extends AbstractProjectProcessor { - - MultiJobProjectProcessor(Job job) { - super((MultiJobProject) job); - // Internal phases - // - super.processBuilders(this.job.getBuilders(), this.job); - - // Post build phases - // - super.processPublishers(this.job); - } - - @Override - public List tryGetBuilders() { - return job.getBuilders(); - } - - @Override - public void scheduleBuild(String parametersBody) { - throw new RuntimeException("non yet implemented"); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java deleted file mode 100644 index deaaeaf999..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import hudson.model.Job; -import hudson.tasks.Builder; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:47 - * To change this template use File | Settings | File Templates. - */ - -class UnsupportedProjectProcessor extends AbstractProjectProcessor { - UnsupportedProjectProcessor(Job job) { - super(job); - } - - @Override - public List tryGetBuilders() { - return new ArrayList<>(); - } - - @Override - public void scheduleBuild(String parametersBody) { - throw new IllegalStateException("unsupported job MAY NOT be run"); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java deleted file mode 100644 index 27ad47d0aa..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.projects; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.configuration.OctaneConfiguration; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.model.Cause; -import hudson.model.Job; -import hudson.tasks.Builder; -import net.sf.json.JSONObject; -import org.jenkinsci.plugins.workflow.job.WorkflowJob; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 24/12/14 - * Time: 13:40 - * To change this template use File | Settings | File Templates. - */ - -public class WorkFlowJobProcessor extends AbstractProjectProcessor { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - WorkFlowJobProcessor(Job job) { - super((WorkflowJob) job); - } - - public List tryGetBuilders() { - return new ArrayList<>(); - } - - public void scheduleBuild(String parametersBody) { - int delay = this.job.getQuietPeriod(); - - if (parametersBody != null && !parametersBody.isEmpty()) { - JSONObject bodyJSON = JSONObject.fromObject(parametersBody); - - // delay - if (bodyJSON.has("delay") && bodyJSON.get("delay") != null) { - delay = bodyJSON.getInt("delay"); - } - - // TODO: support parameters - } - this.job.scheduleBuild(delay, new Cause.RemoteCause(getOctaneConfiguration() == null ? "non available URL" : getOctaneConfiguration().getUrl(), "octane driven execution")); - } - - private OctaneConfiguration getOctaneConfiguration() { - OctaneConfiguration result = null; - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - if (serverConfiguration.location != null && !serverConfiguration.location.isEmpty() && - serverConfiguration.sharedSpace != null && !serverConfiguration.sharedSpace.isEmpty()) { - result = dtoFactory.newDTO(OctaneConfiguration.class) - .setUrl(serverConfiguration.location) - .setSharedSpace(serverConfiguration.sharedSpace) - .setApiKey(serverConfiguration.username) - .setSecret(serverConfiguration.password.getPlainText()); - } - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java deleted file mode 100644 index 5c909679cd..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.scm; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.scm.SCMChange; -import com.hp.octane.integrations.dto.scm.SCMCommit; -import com.hp.octane.integrations.dto.scm.SCMData; -import com.hp.octane.integrations.dto.scm.SCMRepository; -import com.hp.octane.integrations.dto.scm.SCMType; -import hudson.model.AbstractBuild; -import hudson.model.User; -import hudson.model.UserProperty; -import hudson.scm.ChangeLogSet; -import hudson.tasks.Mailer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by benmeior on 9/8/2016. - */ - -public class GenericSCMProcessor implements SCMProcessor { - private static final Logger logger = LogManager.getLogger(GenericSCMProcessor.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - GenericSCMProcessor(){ - } - - @Override - public SCMData getSCMData(AbstractBuild build) { - SCMData result; - SCMRepository repository = buildScmRepository(); - - ChangeLogSet changes = build.getChangeSet(); - ArrayList tmpCommits = buildScmCommits(changes); - - result = dtoFactory.newDTO(SCMData.class) - .setCommits(tmpCommits) - .setRepository(repository); - - return result; - } - - @Override - public List getSCMData(WorkflowRun run) { - // todo: implement default - yanivl - return null; - } - - private ArrayList buildScmCommits(ChangeLogSet changes) { - ArrayList tmpCommits = new ArrayList<>(); - ArrayList tmpChanges; - SCMChange tmpChange; - - for (ChangeLogSet.Entry c : changes) { - User user = c.getAuthor(); - String userEmail = null; - - tmpChanges = new ArrayList<>(); - - for (ChangeLogSet.AffectedFile item : c.getAffectedFiles()) { - tmpChange = dtoFactory.newDTO(SCMChange.class) - .setType(item.getEditType().getName()) - .setFile(item.getPath()); - tmpChanges.add(tmpChange); - } - - for (UserProperty property : user.getAllProperties()) { - if (property instanceof Mailer.UserProperty) { - userEmail = ((Mailer.UserProperty) property).getAddress(); - } - } - SCMCommit tmpCommit = buildScmCommit(tmpChanges, c, userEmail); - tmpCommits.add(tmpCommit); - } - return tmpCommits; - } - - private SCMCommit buildScmCommit(ArrayList tmpChanges, ChangeLogSet.Entry commit, String userEmail) { - return dtoFactory.newDTO(SCMCommit.class) - .setTime(commit.getTimestamp()) - .setUser(commit.getAuthor().getId()) - .setUserEmail(userEmail) - .setRevId(commit.getCommitId()) - .setComment(commit.getMsg().trim()) - .setChanges(tmpChanges); - } - - private SCMRepository buildScmRepository() { - return dtoFactory.newDTO(SCMRepository.class) - .setType(SCMType.UNKNOWN); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java deleted file mode 100644 index cb5b8c2e88..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.scm; - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.scm.SCMChange; -import com.hp.octane.integrations.dto.scm.SCMCommit; -import com.hp.octane.integrations.dto.scm.SCMData; -import com.hp.octane.integrations.dto.scm.SCMRepository; -import com.hp.octane.integrations.dto.scm.SCMType; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.User; -import hudson.model.UserProperty; -import hudson.plugins.git.Branch; -import hudson.plugins.git.GitChangeSet; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.util.BuildData; -import hudson.scm.ChangeLogSet; -import hudson.tasks.Mailer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by gullery on 31/03/2015. - */ - -public class GitSCMProcessor implements SCMProcessor { - private static final Logger logger = LogManager.getLogger(GitSCMProcessor.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - GitSCMProcessor() { - } - - @Override - public SCMData getSCMData(AbstractBuild build) { - AbstractProject project = build.getProject(); - SCMData result = null; - GitSCM scmGit; - SCMRepository scmRepository; - String builtCommitRevId = null; - ChangeLogSet changes = build.getChangeSet(); - BuildData buildData; - - if (project.getScm() instanceof GitSCM) { - scmGit = (GitSCM) project.getScm(); - buildData = scmGit.getBuildData(build); - if (buildData != null) { - scmRepository = getSCMRepository(scmGit, build); - if (buildData.getLastBuiltRevision() != null) { - builtCommitRevId = buildData.getLastBuiltRevision().getSha1String(); - } - - List commits = getCommits(changes); - - result = dtoFactory.newDTO(SCMData.class) - .setRepository(scmRepository) - .setBuiltRevId(builtCommitRevId) - .setCommits(commits); - } - } - return result; - } - - @Override - public List getSCMData(WorkflowRun run) { - List result = new ArrayList<>(); - SCMRepository scmRepository; - String builtCommitRevId = null; - List> changes = run.getChangeSets(); - List buildData; - - buildData = run.getActions(BuildData.class); - - if (buildData != null && !buildData.isEmpty()) { - scmRepository = getSCMRepository(buildData); - if (buildData.get(0).getLastBuiltRevision() != null) { - builtCommitRevId = buildData.get(0).getLastBuiltRevision().getSha1String(); - } - - for (ChangeLogSet changeLogSet : changes) { - List commits = getCommits(changeLogSet); - result.add(dtoFactory.newDTO(SCMData.class) - .setRepository(scmRepository) - .setBuiltRevId(builtCommitRevId) - .setCommits(commits)); - } - } - return result; - } - - private List getCommits(ChangeLogSet changes) { - List commits = new ArrayList<>(); - for (ChangeLogSet.Entry c : changes) { - if (c instanceof GitChangeSet) { - GitChangeSet commit = (GitChangeSet) c; - User user = commit.getAuthor(); - String userEmail = null; - - List tmpChanges = new ArrayList(); - for (GitChangeSet.Path item : commit.getAffectedFiles()) { - SCMChange tmpChange = dtoFactory.newDTO(SCMChange.class) - .setType(item.getEditType().getName()) - .setFile(item.getPath()); - tmpChanges.add(tmpChange); - } - - for (UserProperty property : user.getAllProperties()) { - if (property instanceof Mailer.UserProperty) { - userEmail = ((Mailer.UserProperty) property).getAddress(); - } - } - - SCMCommit tmpCommit = dtoFactory.newDTO(SCMCommit.class) - .setTime(commit.getTimestamp()) - .setUser(user.getId()) - .setUserEmail(userEmail) - .setRevId(commit.getCommitId()) - .setParentRevId(commit.getParentCommit()) - .setComment(commit.getComment().trim()) - .setChanges(tmpChanges); - - commits.add(tmpCommit); - } - } - return commits; - } - - private SCMRepository getSCMRepository(GitSCM gitData, AbstractBuild build) { - SCMRepository result = null; - String url = null; - String branch = null; - if (gitData != null && gitData.getBuildData(build) != null) { - BuildData buildData = gitData.getBuildData(build); - if (!buildData.getRemoteUrls().isEmpty()) { - url = (String) buildData.getRemoteUrls().toArray()[0]; - } - if (buildData.getLastBuiltRevision() != null && !buildData.getLastBuiltRevision().getBranches().isEmpty()) { - branch = ((Branch) buildData.getLastBuiltRevision().getBranches().toArray()[0]).getName(); - } - result = dtoFactory.newDTO(SCMRepository.class) - .setType(SCMType.GIT) - .setUrl(url) - .setBranch(branch); - } - return result; - } - - private SCMRepository getSCMRepository(List buildData) { - SCMRepository result = null; - String url = null; - String branch = null; - if (!buildData.get(0).getRemoteUrls().isEmpty()) { - url = (String) buildData.get(0).getRemoteUrls().toArray()[0]; - } - if (buildData.get(0).getLastBuiltRevision() != null && !buildData.get(0).getLastBuiltRevision().getBranches().isEmpty()) { - branch = ((Branch)buildData.get(0).getLastBuiltRevision().getBranches().toArray()[0]).getName(); - } - result = dtoFactory.newDTO(SCMRepository.class) - .setType(SCMType.GIT) - .setUrl(url) - .setBranch(branch); - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessor.java deleted file mode 100644 index 268ccbe719..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hp.application.automation.tools.octane.model.processors.scm; - -import com.hp.octane.integrations.dto.scm.SCMData; -import hudson.model.AbstractBuild; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.util.List; - -/** - * Created by gullery on 31/03/2015. - */ - -public interface SCMProcessor { - SCMData getSCMData(AbstractBuild build); - List getSCMData(WorkflowRun run); -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessors.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessors.java deleted file mode 100644 index b89dd3e1bf..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SCMProcessors.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.scm; - -import com.hp.application.automation.tools.settings.OctaneServerSettingsBuilder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Created by gullery on 31/03/2015. - */ - -public enum SCMProcessors { - NONE("hudson.scm.NullSCM", null), - GIT("hudson.plugins.git.GitSCM", GitSCMProcessor.class), - SVN("hudson.scm.SubversionSCM", SvnSCMProcessor.class); - - private static Logger logger = LogManager.getLogger(OctaneServerSettingsBuilder.class); - private String targetSCMPluginClassName; - private Class processorClass; - - SCMProcessors(String targetSCMPluginClassName, Class processorClass) { - this.targetSCMPluginClassName = targetSCMPluginClassName; - this.processorClass = processorClass; - } - - public static SCMProcessor getAppropriate(String className) { - SCMProcessor result = null; - - // skip any processing if NULL SCM declared - if (!className.startsWith(NONE.targetSCMPluginClassName)) { - for (SCMProcessors p : values()) { - if (className.startsWith(p.targetSCMPluginClassName)) - try { - result = p.processorClass.newInstance(); - break; - } catch (InstantiationException | IllegalAccessException e) { - logger.error("failed to instantiate SCM processor of type '" + p.targetSCMPluginClassName, e); - } - } - if (result == null) { - result = getGenericSCMProcessor(className); - } - } - - return result; - } - - private static SCMProcessor getGenericSCMProcessor(String className) { - SCMProcessor genericSCMProcessor = null; - try { - genericSCMProcessor = (GenericSCMProcessor.class).newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - logger.error("failed to instantiate SCM processor of type '" + className, e); - } - return genericSCMProcessor; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java b/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java deleted file mode 100644 index f88fb0e9ff..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.model.processors.scm; - - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.scm.SCMChange; -import com.hp.octane.integrations.dto.scm.SCMCommit; -import com.hp.octane.integrations.dto.scm.SCMData; -import com.hp.octane.integrations.dto.scm.SCMRepository; -import com.hp.octane.integrations.dto.scm.SCMType; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.User; -import hudson.model.UserProperty; -import hudson.scm.ChangeLogSet; -import hudson.scm.SubversionChangeLogSet; -import hudson.scm.SubversionSCM; -import hudson.tasks.Mailer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Created by benmeior on 5/15/2016. - */ -@SuppressWarnings({"squid:S2221","squid:S00105"}) -public class SvnSCMProcessor implements SCMProcessor { - private static final Logger logger = LogManager.getLogger(SvnSCMProcessor.class); - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - public static final int PARENT_COMMIT_INDEX = 1; - - @Override - public SCMData getSCMData(AbstractBuild build) { - AbstractProject project = build.getProject(); - SCMData result = null; - SubversionSCM svnData; - SCMRepository scmRepository; - ArrayList tmpCommits; - ChangeLogSet changes = build.getChangeSet(); - String builtRevId; - - if (project.getScm() instanceof SubversionSCM) { - svnData = (SubversionSCM) project.getScm(); - scmRepository = getSCMRepository(svnData); - - builtRevId = getBuiltRevId(build, svnData, scmRepository.getUrl()); - - tmpCommits = buildScmCommits(changes); - - result = dtoFactory.newDTO(SCMData.class) - .setRepository(scmRepository) - .setBuiltRevId(builtRevId) - .setCommits(tmpCommits); - } - return result; - } - - @Override - public List getSCMData(WorkflowRun run) { - // todo: add implementatiohn - yanivl - return null; - } - - private ArrayList buildScmCommits(ChangeLogSet changes) { - ArrayList tmpCommits; - List tmpChanges; - SCMChange tmpChange; - tmpCommits = new ArrayList<>(); - for (ChangeLogSet.Entry c : changes) { - if (c instanceof SubversionChangeLogSet.LogEntry) { - SubversionChangeLogSet.LogEntry commit = (SubversionChangeLogSet.LogEntry) c; - User user = commit.getAuthor(); - String userEmail = null; - - tmpChanges = new ArrayList<>(); - for (SubversionChangeLogSet.Path item : commit.getAffectedFiles()) { - tmpChange = dtoFactory.newDTO(SCMChange.class) - .setType(item.getEditType().getName()) - .setFile(item.getPath()); - tmpChanges.add(tmpChange); - } - - for (UserProperty property : user.getAllProperties()) { - if (property instanceof Mailer.UserProperty) { - userEmail = ((Mailer.UserProperty) property).getAddress(); - } - } - - String parentRevId = getParentRevId(commit); - - SCMCommit tmpCommit = dtoFactory.newDTO(SCMCommit.class) - .setTime(commit.getTimestamp()) - .setUser(commit.getAuthor().getId()) - .setUserEmail(userEmail) - .setRevId(commit.getCommitId()) - .setParentRevId(parentRevId) - .setComment(commit.getMsg().trim()) - .setChanges(tmpChanges); - tmpCommits.add(tmpCommit); - } - } - return tmpCommits; - } - - private String getBuiltRevId(AbstractBuild build, SubversionSCM svnData, String scmRepositoryUrl) { - String builtRevId = null; - - try { - - String revisionStateStr = String.valueOf(svnData.calcRevisionsFromBuild(build, null, null)); - builtRevId = getRevisionIdFromBuild(revisionStateStr, scmRepositoryUrl); - } catch (IOException|InterruptedException e) { - logger.error("failed to get revision state", e); - } - return builtRevId; - } - - private static String getParentRevId(SubversionChangeLogSet.LogEntry commit) { - String parentRevId = null; - - try { - parentRevId = commit.getParent().getLogs().get(PARENT_COMMIT_INDEX).getCommitId(); - } catch (Exception e){ - logger.error("Could not retrieve parentRevId",e); - } - - return parentRevId; - } - - private static String getRevisionIdFromBuild(String revisionStateStr, String repositoryUrl) { - Matcher m = Pattern.compile("(\\d+)").matcher( - revisionStateStr.substring(revisionStateStr.indexOf(repositoryUrl) + repositoryUrl.length() + 1) - ); - if (!m.find()) { - return null; - } - return m.group(1); - } - - private static SCMRepository getSCMRepository(SubversionSCM svnData) { - SCMRepository result; - String url = null; - if (svnData.getLocations().length == 1) { - url = svnData.getLocations()[0].getURL(); - } - result = dtoFactory.newDTO(SCMRepository.class) - .setType(SCMType.SVN) - .setUrl(url); - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java b/src/main/java/com/hp/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java deleted file mode 100644 index bf73e65eac..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import hudson.model.AsyncPeriodicWork; -import hudson.model.TaskListener; - -import java.io.IOException; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -public abstract class AbstractSafeLoggingAsyncPeriodWork extends AsyncPeriodicWork { - - private static Logger logger = Logger.getLogger(AbstractSafeLoggingAsyncPeriodWork.class.getName()); - - protected AbstractSafeLoggingAsyncPeriodWork(String name) { - super(name); - } - - @Override - protected void execute(TaskListener listener) throws IOException, InterruptedException { - try { - doExecute(listener); - } catch (IOException|InterruptedException e) { - // by default this ends up in log file and is rewritten on each execution - // we want this in the regular Jenkins log in order to be able to troubleshoot - logError(e); - } catch (Throwable t) { - // by default this ends up on the console as uncaught exception - // we want this in the regular Jenkins log in order to be able to troubleshoot - logError(t); - } - } - - protected abstract void doExecute(TaskListener listener) throws IOException, InterruptedException; - - private void logError(Throwable t) { - LogRecord lr = new LogRecord(this.getErrorLoggingLevel(), "{0} thread failed with error"); - lr.setThrown(t); - lr.setParameters(new Object[] { name }); - logger.log(lr); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/HPRunnerType.java b/src/main/java/com/hp/application/automation/tools/octane/tests/HPRunnerType.java deleted file mode 100644 index faa33f9d56..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/HPRunnerType.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -/** - * Created by franksha on 05/01/2017. - */ -public enum HPRunnerType { - StormRunner, - UFT, - NONE -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/MqmTestsExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/MqmTestsExtension.java deleted file mode 100644 index 28585d9d39..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/MqmTestsExtension.java +++ /dev/null @@ -1,22 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests; - -import hudson.ExtensionList; -import hudson.ExtensionPoint; -import hudson.model.Hudson; -import hudson.model.Run; - -import java.io.IOException; - -public abstract class MqmTestsExtension implements ExtensionPoint { - - public abstract boolean supports(Run build) throws IOException, InterruptedException; - - - public abstract TestResultContainer getTestResults(Run build, HPRunnerType hpRunnerType, String jenkinsRootUrl) throws IOException, InterruptedException, TestProcessingException; - - public static ExtensionList all() { - return Hudson.getInstance().getExtensionList(MqmTestsExtension.class); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestAbstractResultQueue.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestAbstractResultQueue.java deleted file mode 100644 index 15d1fa65cc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestAbstractResultQueue.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.AbstractResultQueueImpl; -import hudson.Extension; -import jenkins.model.Jenkins; -import org.springframework.util.Assert; - -import java.io.File; -import java.io.IOException; - -@Extension -@SuppressWarnings("squid:S2259") -public class TestAbstractResultQueue extends AbstractResultQueueImpl { - - public TestAbstractResultQueue() throws IOException { - Jenkins instance =Jenkins.getInstance(); - if(instance==null){ - Assert.isNull(instance); - } - File queueFile = new File(instance.getRootDir(), "octane-test-result-queue.dat"); - init(queueFile); - } - - /* - * To be used in tests only. - */ - TestAbstractResultQueue(File queueFile) throws IOException { - init(queueFile); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestApi.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestApi.java deleted file mode 100644 index 9a27f7c288..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestApi.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.mqm.client.LogOutput; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.RequestException; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.FilePath; -import hudson.model.AbstractBuild; -import hudson.model.Item; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.io.IOUtils; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.kohsuke.stapler.export.Flavor; - -import javax.servlet.ServletException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607"}) -public class TestApi { - - private AbstractBuild build; - private JenkinsMqmRestClientFactory clientFactory; - - public TestApi(AbstractBuild build, JenkinsMqmRestClientFactory clientFactory) { - this.build = build; - this.clientFactory = clientFactory; - } - - public void doAudit(StaplerRequest req, StaplerResponse res) throws IOException, ServletException, InterruptedException { - // audit log contains possibly sensitive information (location, domain and project): require configure permission - build.getProject().getACL().checkPermission(Item.CONFIGURE); - serveFile(res, TestDispatcher.TEST_AUDIT_FILE, Flavor.JSON); - } - - public void doXml(StaplerRequest req, StaplerResponse res) throws IOException, ServletException, InterruptedException { - build.getACL().checkPermission(Item.READ); - serveFile(res, TestListener.TEST_RESULT_FILE, Flavor.XML); - } - - public void doLog(StaplerRequest req, final StaplerResponse res) throws IOException, ServletException, InterruptedException { - build.getACL().checkPermission(Item.READ); - FilePath auditFile = new FilePath(new File(build.getRootDir(), TestDispatcher.TEST_AUDIT_FILE)); - if (!auditFile.exists()) { - res.sendError(404, "Audit file is not present, log information is not available"); - return; - } - JSONArray audit = JSONArray.fromObject(auditFile.readToString()); - JSONObject lastAudit = audit.getJSONObject(audit.size() - 1); - if (!lastAudit.getBoolean("pushed")) { - res.sendError(404, "Last audited push didn't succeed, log information is not available"); - return; - } - long id = lastAudit.getLong("id"); - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - String location = lastAudit.getString("location"); - if (!location.equals(configuration.location)) { - res.sendError(404, "Server configuration has changed, log information is not available"); - return; - } - MqmRestClient restClient = clientFactory.obtain(configuration.location, configuration.sharedSpace, configuration.username, configuration.password); - res.setStatus(200); - try { - restClient.getTestResultLog(id, new JenkinsLogOutput(res)); - } catch (RequestException e) { - if ("testbox.not_found".equals(e.getErrorCode())) { - res.sendError(404, "Log information is not available. It either expired or shared space was re-created on the server."); - return; - } - throw e; - } - } - - private void serveFile(StaplerResponse res, String relativePath, Flavor flavor) throws IOException, InterruptedException { - FilePath file = new FilePath(new File(build.getRootDir(), relativePath)); - if (!file.exists()) { - res.sendError(404, "Information not available"); - return; - } - res.setStatus(200); - res.setContentType(flavor.contentType); - InputStream is = file.read(); - IOUtils.copy(is, res.getOutputStream()); - IOUtils.closeQuietly(is); - } - - private static class JenkinsLogOutput implements LogOutput { - - private StaplerResponse res; - - JenkinsLogOutput(StaplerResponse res) { - this.res = res; - } - - @Override - public OutputStream getOutputStream() throws IOException { - return res.getOutputStream(); - } - - @Override - public void setContentType(String contentType) { - res.setContentType(contentType); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestDispatcher.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestDispatcher.java deleted file mode 100644 index e68146a141..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestDispatcher.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.google.inject.Inject; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.SharedSpaceNotExistException; -import com.hp.mqm.client.exception.FileNotFoundException; -import com.hp.mqm.client.exception.LoginException; -import com.hp.mqm.client.exception.RequestException; -import com.hp.mqm.client.exception.TemporarilyUnavailableException; -import com.hp.application.automation.tools.octane.ResultQueue; -import com.hp.application.automation.tools.octane.client.EventPublisher; -import com.hp.application.automation.tools.octane.client.JenkinsInsightEventPublisher; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactoryImpl; -import com.hp.application.automation.tools.octane.client.RetryModel; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.Extension; -import hudson.FilePath; -import hudson.matrix.MatrixRun; -import hudson.model.*; -import hudson.util.TimeUnit2; -import jenkins.YesNoMaybe; -import jenkins.model.Jenkins; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.time.DateFormatUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.*; -import java.util.Date; - -@Extension(dynamicLoadable = YesNoMaybe.NO) -public class TestDispatcher extends AbstractSafeLoggingAsyncPeriodWork { - private static Logger logger = LogManager.getLogger(TestDispatcher.class); - - static final String TEST_AUDIT_FILE = "mqmTests_audit.json"; - - @Inject - private RetryModel retryModel; - - private ResultQueue queue; - - private JenkinsMqmRestClientFactory clientFactory; - - private EventPublisher eventPublisher; - - public TestDispatcher() { - super("MQM Test Dispatcher"); - } - - @Override - protected void doExecute(TaskListener listener) throws IOException, InterruptedException { - if (queue.peekFirst() == null) { - return; - } - if (retryModel.isQuietPeriod()) { - logger.info("There are pending test results, but we are in quiet period"); - return; - } - MqmRestClient client = null; - ServerConfiguration configuration = null; - ResultQueue.QueueItem item; - while ((item = queue.peekFirst()) != null) { - if (client == null) { - configuration = ConfigurationService.getServerConfiguration(); - if (StringUtils.isEmpty(configuration.location)) { - logger.warn("There are pending test results, but MQM server location is not specified, results can't be submitted"); - return; - } - if (eventPublisher.isSuspended()) { - logger.warn("There are pending test results, but event dispatching is suspended"); - return; - } - logger.info("There are pending test results, connecting to the MQM server"); - client = clientFactory.obtain( - configuration.location, - configuration.sharedSpace, - configuration.username, - configuration.password); - try { - client.validateConfigurationWithoutLogin(); - } catch (SharedSpaceNotExistException e) { - logger.warn("Invalid shared space. Pending test results can't be submitted", e); - retryModel.failure(); - return; - } catch (LoginException e) { - logger.warn("Login failed, pending test results can't be submitted", e); - retryModel.failure(); - return; - } catch (RequestException e) { - logger.warn("Problem with communication with MQM server. Pending test results can't be submitted", e); - retryModel.failure(); - return; - } - - retryModel.success(); - } - Job project = (Job) Jenkins.getInstance().getItemByFullName(item.getProjectName()); - // AbstractProject project1 = (AbstractProject) Jenkins.getInstance().getItemByFullName(item.getProjectName()); - if (project == null) { - logger.warn("Project [" + item.getProjectName() + "] no longer exists, pending test results can't be submitted"); - queue.remove(); - continue; - } - Run build = project.getBuildByNumber(item.getBuildNumber()); - //AbstractBuild build = project.getBuildByNumber(item.getBuildNumber()); - if (build == null) { - logger.warn("Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] no longer exists, pending test results can't be submitted"); - queue.remove(); - continue; - } - - String jobName; - if (build instanceof MatrixRun) { - jobName = ((MatrixRun) build).getProject().getParent().getName(); - } else { - jobName = build.getParent().getName(); - } - - Boolean needTestResult = client.isTestResultRelevant(ConfigurationService.getModel().getIdentity(), jobName); - - if (needTestResult) { - try { - Long id = null; - try { - File resultFile = new File(build.getRootDir(), TestListener.TEST_RESULT_FILE); - id = client.postTestResult(resultFile, false); - } catch (TemporarilyUnavailableException e) { - logger.warn("Server temporarily unavailable, will try later", e); - audit(configuration, build, null, true); - break; - } catch (RequestException e) { - logger.warn("Failed to submit test results [" + build.getParent().getName()/*build.getProject().getName()*/ + "#" + build.getNumber() + "]", e); - } - - if (id != null) { - logger.info("Successfully pushed test results of build [" + item.getProjectName() + "#" + item.getBuildNumber() + "]"); - queue.remove(); - } else { - logger.warn("Failed to push test results of build [" + item.getProjectName() + "#" + item.getBuildNumber() + "]"); - if (!queue.failed()) { - logger.warn("Maximum number of attempts reached, operation will not be re-attempted for this build"); - } - client = null; - } - audit(configuration, build, id, false); - } catch (FileNotFoundException e) { - logger.warn("File no longer exists, failed to push test results of build [" + item.getProjectName() + "#" + item.getBuildNumber() + "]"); - queue.remove(); - } - } else { - logger.info("Test result not needed for build [" + item.getProjectName() + "#" + item.getBuildNumber() + "]"); - queue.remove(); - } - } - } - - private void audit(ServerConfiguration configuration, Run build, Long id, boolean temporarilyUnavailable) throws IOException, InterruptedException { - FilePath auditFile = new FilePath(new File(build.getRootDir(), TEST_AUDIT_FILE)); - JSONArray audit; - if (auditFile.exists()) { - InputStream is = auditFile.read(); - audit = JSONArray.fromObject(IOUtils.toString(is, "UTF-8")); - IOUtils.closeQuietly(is); - } else { - audit = new JSONArray(); - } - JSONObject event = new JSONObject(); - event.put("id", id); - event.put("pushed", id != null); - event.put("date", DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(new Date())); - event.put("location", configuration.location); - event.put("sharedSpace", configuration.sharedSpace); - if (temporarilyUnavailable) { - event.put("temporarilyUnavailable", true); - } - audit.add(event); - auditFile.write(audit.toString(), "UTF-8"); - } - - @Override - public long getRecurrencePeriod() { - String value = System.getProperty("MQM.TestDispatcher.Period"); - if (!StringUtils.isEmpty(value)) { - return Long.valueOf(value); - } - return TimeUnit2.SECONDS.toMillis(10); - } - - @Inject - public void setMqmRestClientFactory(JenkinsMqmRestClientFactoryImpl clientFactory) { - this.clientFactory = clientFactory; - } - - @Inject - public void setTestResultQueue(TestAbstractResultQueue queue) { - this.queue = queue; - } - - @Inject - public void setEventPublisher(JenkinsInsightEventPublisher eventPublisher) { - this.eventPublisher = eventPublisher; - } - - - void _setMqmRestClientFactory(JenkinsMqmRestClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - - void _setTestResultQueue(ResultQueue queue) { - this.queue = queue; - } - - - void _setRetryModel(RetryModel retryModel) { - this.retryModel = retryModel; - } - - - void _setEventPublisher(EventPublisher eventPublisher) { - this.eventPublisher = eventPublisher; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestListener.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestListener.java deleted file mode 100644 index 03a5d18ba4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestListener.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.ResultQueue; -import com.hp.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; -import com.hp.application.automation.tools.octane.tests.build.BuildHandlerUtils; -import com.hp.application.automation.tools.octane.tests.detection.UFTExtension; -import com.hp.application.automation.tools.octane.tests.xml.TestResultXmlWriter; -import hudson.Extension; -import hudson.FilePath; -import hudson.model.AbstractBuild; -import hudson.model.Result; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.tasks.Builder; -import jenkins.model.Jenkins; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.xml.stream.XMLStreamException; -import java.util.List; - -@Extension -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872"}) -public class TestListener { - private static Logger logger = LogManager.getLogger(TestListener.class); - - static final String TEST_RESULT_FILE = "mqmTests.xml"; - public static final String JENKINS_STORM_TEST_RUNNER_CLASS = "com.hpe.sr.plugins.jenkins.StormTestRunner"; - - private ResultQueue queue; - - public void processBuild(Run build, TaskListener listener) { - - FilePath resultPath = new FilePath(new FilePath(build.getRootDir()), TEST_RESULT_FILE); - TestResultXmlWriter resultWriter = new TestResultXmlWriter(resultPath, build); - boolean success = false; - boolean hasTests = false; - String jenkinsRootUrl = Jenkins.getInstance().getRootUrl(); - HPRunnerType hpRunnerType = HPRunnerType.NONE; - List builders = JobProcessorFactory.getFlowProcessor(build.getParent()).tryGetBuilders(); - if (builders != null) { - for (Builder builder : builders) { - if (builder.getClass().getName().equals(JENKINS_STORM_TEST_RUNNER_CLASS)) { - hpRunnerType = HPRunnerType.StormRunner; - break; - } - if (builder.getClass().getName().equals(UFTExtension.RUN_FROM_FILE_BUILDER) || builder.getClass().getName().equals(UFTExtension.RUN_FROM_ALM_BUILDER)) { - hpRunnerType = HPRunnerType.UFT; - break; - } - } - } - - try { - for (MqmTestsExtension ext : MqmTestsExtension.all()) { - try { - if (ext.supports(build)) { - - List buildsList = BuildHandlerUtils.getBuildPerWorkspaces(build); - for(Run buildX : buildsList){ - TestResultContainer testResultContainer = ext.getTestResults(buildX, hpRunnerType, jenkinsRootUrl); - if (testResultContainer != null && testResultContainer.getIterator().hasNext()) { - resultWriter.writeResults(testResultContainer); - hasTests = true; - } - } - } - } catch (IllegalArgumentException e) { - listener.error(e.getMessage()); - if (!build.getResult().isWorseOrEqualTo(Result.UNSTABLE)) { - build.setResult(Result.UNSTABLE); - } - return; - } catch (InterruptedException ie) { - logger.error("Interrupted processing test results in " + ext.getClass().getName(), ie); - Thread.currentThread().interrupt(); - return; - } catch (Exception e) { - // extensibility involved: catch both checked and RuntimeExceptions - logger.error("Error processing test results in " + ext.getClass().getName(), e); - return; - } - } - success = true; - } finally { - try { - resultWriter.close(); - if (success && hasTests) { - String projectFullName = BuildHandlerUtils.getProjectFullName(build); - if (projectFullName != null) { - queue.add(projectFullName, build.getNumber()); - } - } - } catch (XMLStreamException xmlse) { - logger.error("Error processing test results", xmlse); - } - } - } - - private boolean isUFTRunner(AbstractBuild build) { - UFTExtension uftExtension = new UFTExtension(); - return uftExtension.detect(build) != null; - } - - @Inject - public void setTestResultQueue(TestAbstractResultQueue queue) { - this.queue = queue; - } - - /* - * To be used in tests only. - */ - public void _setTestResultQueue(ResultQueue queue) { - this.queue = queue; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestProcessingException.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestProcessingException.java deleted file mode 100644 index 0a5b535a52..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestProcessingException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -/** - * Created by franksha on 05/01/2017. - */ -public class TestProcessingException extends Exception { - - public TestProcessingException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/TestResultContainer.java b/src/main/java/com/hp/application/automation/tools/octane/tests/TestResultContainer.java deleted file mode 100644 index 5b5c6329e6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/TestResultContainer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.tests.detection.ResultFields; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; - -import java.util.Iterator; - -public class TestResultContainer { - - private Iterator iterator; - private ResultFields resultFields; - - public TestResultContainer(Iterator iterator, ResultFields resultFields) { - this.iterator = iterator; - this.resultFields = resultFields; - } - - public Iterator getIterator() { - return iterator; - } - - public ResultFields getResultFields() { - return resultFields; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildDescriptor.java b/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildDescriptor.java deleted file mode 100644 index e803d148df..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildDescriptor.java +++ /dev/null @@ -1,40 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests.build; - -public final class BuildDescriptor { - - private final String jobId; - private final String jobName; - private final String buildId; - private final String buildName; - private final String subType; - - public BuildDescriptor(String jobId, String jobName, String buildId, String buildName, String subType) { - this.jobId = jobId; - this.jobName = jobName; - this.buildId = buildId; - this.buildName = buildName; - this.subType = subType; - } - - public String getJobId() { - return jobId; - } - - public String getJobName() { - return jobName; - } - - public String getBuildId() { - return buildId; - } - - public String getBuildName() { - return buildName; - } - - public String getSubType() { - return subType; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerExtension.java deleted file mode 100644 index 1bd60b2d41..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerExtension.java +++ /dev/null @@ -1,21 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests.build; - -import hudson.ExtensionList; -import hudson.ExtensionPoint; -import hudson.model.Hudson; -import hudson.model.Run; - -public abstract class BuildHandlerExtension implements ExtensionPoint { - - public abstract boolean supports(Run build); - - public abstract BuildDescriptor getBuildType(Run build); - - public abstract String getProjectFullName(Run build); - - public static ExtensionList all() { - return Hudson.getInstance().getExtensionList(BuildHandlerExtension.class); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtils.java b/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtils.java deleted file mode 100644 index a2a065058a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests.build; - -import com.hp.application.automation.tools.octane.workflow.WorkflowBuildAdapter; -import com.hp.application.automation.tools.octane.workflow.WorkflowGraphListener; -import hudson.FilePath; -import hudson.model.AbstractBuild; -import hudson.model.Run; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.util.ArrayList; -import java.util.List; - -public class BuildHandlerUtils { - - public static BuildDescriptor getBuildType(Run build) { - for (BuildHandlerExtension ext : BuildHandlerExtension.all()) { - if (ext.supports(build)) { - return ext.getBuildType(build); - } - } - return new BuildDescriptor( - build.getParent().getName(), - build.getParent().getName(), - String.valueOf(build.getNumber()), - String.valueOf(build.getNumber()), - ""); - } - - public static String getProjectFullName(Run build) { - for (BuildHandlerExtension ext : BuildHandlerExtension.all()) { - if (ext.supports(build)) { - return ext.getProjectFullName(build); - } - } - return build.getParent().getName();//builgetProject().getName(); - } - - public static FilePath getWorkspace(Run build){ - //this.buildId =/*build.getProject()*/((AbstractProject)build.getParent()).getBuilds().getLastBuild().getId(); - if(build.getExecutor()!=null && build.getExecutor().getCurrentWorkspace()!=null){ - return build.getExecutor().getCurrentWorkspace(); - } - if (build instanceof AbstractBuild){ - return ((AbstractBuild) build).getWorkspace(); - } - if(build instanceof WorkflowBuildAdapter){ - return ((WorkflowBuildAdapter)build).getWorkspace(); -// FilePath filePath = new FilePath(new File(((WorkflowRun) build).getParent().getRootDir(). -// getAbsolutePath()+File.separator +"workspace")); -// return filePath; - } - - return null; - } - - public static String getBuildId(Run build){ -// if(build instanceof AbstractBuild){ -// return ((AbstractProject)build.getParent()).getBuilds().getLastBuild().getId(); -// }else{ -// return build.getParent().getLastBuild().getId(); -// } - return build.getParent().getLastBuild().getId(); - } - - public static List getBuildPerWorkspaces(Run build) { - - if(build instanceof WorkflowRun){ - return WorkflowGraphListener.FlowNodeContainer.getFlowNode(build); - - }else { - List runsList = new ArrayList<>(); - runsList.add(build); - return runsList; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/build/MatrixBuildExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/build/MatrixBuildExtension.java deleted file mode 100644 index 2b56568cd4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/build/MatrixBuildExtension.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.build; - -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.application.automation.tools.octane.model.ModelFactory; -import com.hp.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; -import hudson.Extension; -import hudson.model.AbstractBuild; -import hudson.model.Run; - -import java.util.List; - -@Extension -public class MatrixBuildExtension extends BuildHandlerExtension { - - @Override - public boolean supports(Run build) { - return "hudson.matrix.MatrixRun".equals(build.getClass().getName()); - } - - @Override - public BuildDescriptor getBuildType(Run build) { - AbstractBuild matrixRun = (AbstractBuild) build; - List parameters = ParameterProcessors.getInstances(build); - String subBuildName = ModelFactory.generateSubBuildName(parameters); - return new BuildDescriptor( - matrixRun.getRootBuild().getProject().getName(), - matrixRun.getRootBuild().getProject().getName(), - String.valueOf(build.getNumber()), - String.valueOf(build.getNumber()), - subBuildName); - } - - @Override - public String getProjectFullName(Run build) { - AbstractBuild matrixRun = (AbstractBuild) build; - return matrixRun.getRootBuild().getProject().getName() + "/" + matrixRun.getProject().getName(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/build/MavenBuildExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/build/MavenBuildExtension.java deleted file mode 100644 index d7dc132f3b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/build/MavenBuildExtension.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.build; - -import hudson.Extension; -import hudson.model.AbstractBuild; -import hudson.model.Run; - -@Extension -public class MavenBuildExtension extends BuildHandlerExtension { - - @Override - public boolean supports(Run build) { - return "hudson.maven.MavenBuild".equals(build.getClass().getName()) || - "hudson.maven.MavenModuleSetBuild".equals(build.getClass().getName()); - } - - @Override - public BuildDescriptor getBuildType(Run build) { - return new BuildDescriptor( - ((AbstractBuild)build).getRootBuild().getProject().getName(), - ((AbstractBuild)build).getProject().getName(), - String.valueOf(build.getNumber()), - String.valueOf(build.getNumber()), - ""); - } - - @Override - public String getProjectFullName(Run build) { - if ("hudson.maven.MavenBuild".equals(build.getClass().getName())) { - // we don't push individual maven module results (although we create the file) - return null; - } else { - return ((AbstractBuild)build).getProject().getName(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFields.java b/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFields.java deleted file mode 100644 index 82fe02f51b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFields.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - - -public class ResultFields { - - private String framework; - private String testingTool; - private String testLevel; - - public ResultFields() { - } - - public ResultFields(final String framework, final String testingTool, final String testLevel) { - this.framework = framework; - this.testingTool = testingTool; - this.testLevel = testLevel; - } - - public String getFramework() { - return framework; - } - - public String getTestingTool() { - return testingTool; - } - - public String getTestLevel() { - return testLevel; - } - - public void setFramework(final String framework) { - this.framework = framework; - } - - public void setTestLevel(final String testLevel) { - this.testLevel = testLevel; - } - - public void setTestingTool(final String testingTool) { - this.testingTool = testingTool; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final ResultFields that = (ResultFields) o; - - if (framework != null ? !framework.equals(that.framework) : that.framework != null) { - return false; - } - if (testingTool != null ? !testingTool.equals(that.testingTool) : that.testingTool != null) { - return false; - } - return !(testLevel != null ? !testLevel.equals(that.testLevel) : that.testLevel != null); - - } - - @Override - public int hashCode() { - int result = framework != null ? framework.hashCode() : 0; - result = 31 * result + (testingTool != null ? testingTool.hashCode() : 0); - result = 31 * result + (testLevel != null ? testLevel.hashCode() : 0); - return result; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java deleted file mode 100644 index f25fc3bc61..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import hudson.ExtensionList; -import hudson.ExtensionPoint; -import hudson.model.Hudson; -import hudson.model.Run; - -import java.io.IOException; - -public abstract class ResultFieldsDetectionExtension implements ExtensionPoint { - - public abstract ResultFields detect(Run build) throws IOException, InterruptedException; - - public static ExtensionList all() { - return Hudson.getInstance().getExtensionList(ResultFieldsDetectionExtension.class); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java b/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java deleted file mode 100644 index cc1c243857..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import hudson.model.Run; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Service used for auto detection of test results global parameters like test-framework, testing-tool, etc. - */ -public class ResultFieldsDetectionService { - private static Logger logger = LogManager.getLogger(ResultFieldsDetectionService.class); - - public ResultFields getDetectedFields(Run build) throws InterruptedException { - for (ResultFieldsDetectionExtension ext : ResultFieldsDetectionExtension.all()) { - try { - ResultFields fields = ext.detect(build); - if (fields != null) { - return fields; - } - } catch (InterruptedException e) { - logger.error("Interrupted during running of detection service: " + ext.getClass().getName(), e); - throw e; - } catch (Exception e) { - logger.error("Error during running of detection service: " + ext.getClass().getName(), e); - } - } - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtension.java deleted file mode 100644 index b8a7ba6705..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtension.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import com.hp.application.automation.tools.octane.tests.build.BuildHandlerUtils; -import hudson.Extension; -import hudson.FilePath; -import hudson.Util; -import hudson.maven.MavenBuild; -import hudson.maven.MavenModule; -import hudson.maven.MavenModuleSetBuild; -import hudson.model.AbstractBuild; -import hudson.model.Run; -import hudson.remoting.VirtualChannel; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.tasks.test.AbstractTestResultAction; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.types.FileSet; -import org.jenkinsci.remoting.Role; -import org.jenkinsci.remoting.RoleChecker; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@Extension(optional = true) -public class TestNGExtension extends ResultFieldsDetectionExtension { - - private static String TESTNG = "TestNG"; - - private static String TESTNG_RESULT_FILE = "testng-results.xml"; - - private static final List supportedReportFileLocations = Arrays.asList( - "target/surefire-reports/" + TESTNG_RESULT_FILE, - "target/failsafe-reports/" + TESTNG_RESULT_FILE - ); - - - @Override - public ResultFields detect(final Run build) throws IOException, InterruptedException { - if(!(build instanceof AbstractBuild)){ - return new ResultFields(null, null, null); - } -// if(build instanceof WorkflowBuildAdapter){ -// FilePath workspace = BuildHandlerUtils.getWorkspace(build); -// ((TestResultAction)((WorkflowBuildAdapter)build).getAction(TestResultAction.class)).getResult().getSuites(); -// if (BuildHandlerUtils.getWorkspace(build).act(new TestNgPipelineResultsFileFinder(testResultsPattern))) { -// return new ResultFields(TESTNG, null, null); -// } -// } - - final List publishers = ((AbstractBuild) build).getProject().getPublishersList().toList(); - for (Object publisher : publishers) { - if ("hudson.tasks.junit.JUnitResultArchiver".equals(publisher.getClass().getName())) { - JUnitResultArchiver junit = (JUnitResultArchiver) publisher; - String testResultsPattern = junit.getTestResults(); - if (BuildHandlerUtils.getWorkspace(build).act(new TestNgResultsFileFinder(testResultsPattern))) { - return new ResultFields(TESTNG, null, null); - } - } - } - - if ("hudson.maven.MavenBuild".equals(build.getClass().getName())) { - MavenBuild mavenBuild = (MavenBuild) build; - if (findTestNgResultsFile(mavenBuild)) { - return new ResultFields(TESTNG, null, null); - } - } - - if ("hudson.maven.MavenModuleSetBuild".equals(build.getClass().getName())) { - Map moduleLastBuilds = ((MavenModuleSetBuild) build).getModuleLastBuilds(); - for (MavenBuild mavenBuild: moduleLastBuilds.values()) { - if (findTestNgResultsFile(mavenBuild)) { - return new ResultFields(TESTNG, null, null); - } - } - } - return null; - } - - boolean findTestNgResultsFile(MavenBuild mavenBuild) throws IOException, InterruptedException { - AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); - //try finding only if the maven build includes tests - if (action != null && mavenBuild.getWorkspace().act(new TestNgResultsFileMavenFinder())) { - return true; - } - return false; - } - - public static class TestNgResultsFileFinder implements FilePath.FileCallable { - - private String testResultsPattern; - - public TestNgResultsFileFinder(String testResultsPattern) { - this.testResultsPattern = testResultsPattern; - } - - @Override - public Boolean invoke(File workspace, VirtualChannel virtualChannel) throws IOException, InterruptedException { - FileSet fs = Util.createFileSet(workspace, testResultsPattern); - DirectoryScanner ds = fs.getDirectoryScanner(); - String[] includedFiles = ds.getIncludedFiles(); - File baseDir = ds.getBasedir(); - - if (includedFiles.length > 0) { - if (findTestNgResultsFile(baseDir, includedFiles)) { - return true; - } - } - return false; - } - - @Override - public void checkRoles(RoleChecker roleChecker) throws SecurityException { - roleChecker.check(this, Role.UNKNOWN); - } - - boolean findTestNgResultsFile(File baseDir, String[] includedFiles) throws IOException, InterruptedException { - Set directoryCache = new LinkedHashSet(); - - for (String path : includedFiles) { - FilePath file = new FilePath(baseDir).child(path); - if (file.exists() && !directoryCache.contains(file.getParent())) { - directoryCache.add(file.getParent()); - FilePath testNgResulsFile = new FilePath(file.getParent(), TESTNG_RESULT_FILE); - if (testNgResulsFile.exists()) { - return true; - } - } - } - return false; - } - } - - public static class TestNgResultsFileMavenFinder implements FilePath.FileCallable { - - @Override - public Boolean invoke(File workspace, VirtualChannel virtualChannel) throws IOException, InterruptedException { - for (String locationInWorkspace : supportedReportFileLocations) { - File reportFile = new File(workspace, locationInWorkspace); - if (reportFile.exists()) { - return true; - } - } - return false; - } - - @Override - public void checkRoles(RoleChecker roleChecker) throws SecurityException { - roleChecker.check(this, Role.UNKNOWN); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtension.java deleted file mode 100644 index 529224c0e7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtension.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import hudson.Extension; -import hudson.model.FreeStyleProject; -import hudson.model.Run; -import hudson.tasks.Builder; - -@SuppressWarnings("squid:S1872") -@Extension -public class UFTExtension extends ResultFieldsDetectionExtension { - - public static final String UFT = "UFT"; - - public static final String RUN_FROM_FILE_BUILDER = "com.hp.application.automation.tools.run.RunFromFileBuilder"; - public static final String RUN_FROM_ALM_BUILDER = "com.hp.application.automation.tools.run.RunFromAlmBuilder"; - - @Override - public ResultFields detect(final Run build) { - - if (build.getParent() instanceof FreeStyleProject) { - for (Builder builder : ((FreeStyleProject) build.getParent()).getBuilders()) { - if (builder.getClass().getName().equals(RUN_FROM_FILE_BUILDER) || builder.getClass().getName().equals(RUN_FROM_ALM_BUILDER)) { - return new ResultFields(UFT, UFT, null); - } - } - } - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestExtention.java b/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestExtention.java deleted file mode 100644 index 33ce1f8a48..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestExtention.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.gherkin; - -import com.hp.application.automation.tools.octane.actions.cucumber.CucumberTestResultsAction; -import com.hp.application.automation.tools.octane.tests.HPRunnerType; -import com.hp.application.automation.tools.octane.tests.MqmTestsExtension; -import com.hp.application.automation.tools.octane.tests.TestProcessingException; -import com.hp.application.automation.tools.octane.tests.TestResultContainer; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import hudson.Extension; -import hudson.model.Run; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.util.List; - -@Extension -public class GherkinTestExtention extends MqmTestsExtension { - private static Logger logger = LogManager.getLogger(GherkinTestExtention.class); - - @Override - public boolean supports(Run build) throws IOException, InterruptedException { - if (build.getAction(CucumberTestResultsAction.class) != null) { - logger.debug("CucumberTestResultsAction found, gherkin results expected"); - return true; - } else { - logger.debug("CucumberTestResultsAction not found, no gherkin results expected"); - return false; - } - } - - @Override - public TestResultContainer getTestResults(Run build, HPRunnerType hpRunnerType, String jenkinsRootUrl) throws TestProcessingException, IOException, InterruptedException { - try { - List testResults = GherkinTestResultsCollector.collectGherkinTestsResults(build.getRootDir()); - return new TestResultContainer(testResults.iterator(), null); - } catch (IOException e) { - throw e; - } catch (InterruptedException e) { - throw e; - } catch (Exception e) { - throw new TestProcessingException("Error while processing gherkin test results", e); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResult.java b/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResult.java deleted file mode 100644 index 70f010fb3b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResult.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.gherkin; - -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import java.util.HashMap; -import java.util.Map; - -/** - * Created by franksha on 20/03/2016. - */ -public class GherkinTestResult implements TestResult { - private Map attributes; - private Element contentElement; - - public GherkinTestResult(String name, Element xmlElement, long duration, TestResultStatus status) { - this.attributes = new HashMap<>(); - this.attributes.put("name", name); - this.attributes.put("duration", String.valueOf(duration)); - this.attributes.put("status", status.toPrettyName()); - this.contentElement = xmlElement; - } - - public Map getAttributes() { - return attributes; - } - - public Element getXmlElement() { - return contentElement; - } - - @Override - public void writeXmlElement(XMLStreamWriter writer) throws XMLStreamException { - writer.writeStartElement("gherkin_test_run"); - if (attributes != null) { - for (String attrName : attributes.keySet()) { - writer.writeAttribute(attrName, attributes.get(attrName)); - } - } - writeXmlElement(writer, contentElement); - writer.writeEndElement(); - } - - private void writeXmlElement(XMLStreamWriter writer, Element rootElement) throws XMLStreamException { - if (rootElement != null) { - writer.writeStartElement(rootElement.getTagName()); - for (int a = 0; a < rootElement.getAttributes().getLength(); a++) { - String attrName = rootElement.getAttributes().item(a).getNodeName(); - writer.writeAttribute(attrName, rootElement.getAttribute(attrName)); - } - NodeList childNodes = rootElement.getChildNodes(); - for (int c = 0; c < childNodes.getLength(); c++) { - Node child = childNodes.item(c); - if (child instanceof Element) { - writeXmlElement(writer, (Element) child); - } else if (child.getNodeType() == Node.CDATA_SECTION_NODE) { - writer.writeCharacters(child.getNodeValue()); - } - } - writer.writeEndElement(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollector.java b/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollector.java deleted file mode 100644 index d73596ff32..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollector.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.gherkin; - -import com.hp.application.automation.tools.octane.actions.cucumber.CucumberResultsService; -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import hudson.FilePath; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by franksha on 20/03/2016. - */ -public class GherkinTestResultsCollector { - - public static List collectGherkinTestsResults(File buildDir) throws ParserConfigurationException, IOException, InterruptedException, SAXException, TransformerException { - List result = new ArrayList<>(); - - //Retrieve the cucumber results xml - int i = 0; - FilePath gherkinTestResultsFilePath = new FilePath(buildDir).child(CucumberResultsService.getGherkinResultFileName(i)); - - while (gherkinTestResultsFilePath.exists()) { - String gherkinTestResultsPath = buildDir.getAbsolutePath() + File.separator + CucumberResultsService.getGherkinResultFileName(i); - - //parse the xml - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(gherkinTestResultsPath); - doc.getDocumentElement().normalize(); - - validateXMLVersion(doc); - - //Go over the features - NodeList featureNodes = doc.getElementsByTagName("feature"); - for (int f = 0; f < featureNodes.getLength(); f++) { - Element featureElement = (Element) featureNodes.item(f); - FeatureInfo featureInfo = new FeatureInfo(featureElement); - result.add(new GherkinTestResult(featureInfo.getName(), featureElement, featureInfo.getDuration(), featureInfo.getStatus())); - } - - i++; - gherkinTestResultsFilePath = new FilePath(buildDir).child(CucumberResultsService.getGherkinResultFileName(i)); - } //end while - - return result; - } - - private static class FeatureInfo { - private String name; - private List scenarioNames = new ArrayList<>(); - private TestResultStatus status = TestResultStatus.PASSED; - private boolean statusDetermined = false; - private long duration = 0; - - public FeatureInfo(Element featureElement) { - name = featureElement.getAttribute("name"); - NodeList backgroundNodes = featureElement.getElementsByTagName("background"); - Element backgroundElement = backgroundNodes.getLength() > 0 ? (Element)backgroundNodes.item(0) : null; - NodeList backgroundSteps = backgroundElement != null ? backgroundElement.getElementsByTagName("step") : null; - - //Go over the scenarios - NodeList scenarioNodes = featureElement.getElementsByTagName("scenario"); - for (int s = 0; s < scenarioNodes.getLength(); s++) { - Element scenarioElement = (Element) scenarioNodes.item(s); - ScenarioInfo scenarioInfo = new ScenarioInfo(scenarioElement, backgroundSteps); - String scenarioName = scenarioInfo.getName(); - scenarioNames.add(scenarioName); - - duration += scenarioInfo.getDuration(); - if (!statusDetermined && TestResultStatus.SKIPPED.equals(scenarioInfo.getStatus())) { - status = TestResultStatus.SKIPPED; - statusDetermined = true; - } else if (!statusDetermined && TestResultStatus.FAILED.equals(scenarioInfo.getStatus())) { - status = TestResultStatus.FAILED; - statusDetermined = true; - } - } - } - - public String getName() { - return name; - } - - public List getScenarioNames() { - return scenarioNames; - } - - public TestResultStatus getStatus() { - return status; - } - - public long getDuration() { - return duration; - } - - private class ScenarioInfo { - private List stepNames = new ArrayList(); - private long duration = 0; - private TestResultStatus status = TestResultStatus.PASSED; - private boolean statusDetermined = false; - private String name; - - public ScenarioInfo(Element scenarioElement, NodeList backgroundSteps) { - name = getScenarioName(scenarioElement); - - List stepElements = getStepElements(backgroundSteps, scenarioElement); - for (Element stepElement : stepElements) { - addStep(stepElement); - } - - scenarioElement.setAttribute("status", status.toPrettyName()); - - //for surefire report - stepNames.add(name); - stepNames.add("Scenario: " + name); - } - - public List getStepNames() { - return stepNames; - } - - public long getDuration() { - return duration; - } - - public TestResultStatus getStatus() { - return status; - } - - public String getName() { - return name; - } - - private void addStep(Element stepElement) { - String stepName = stepElement.getAttribute("name"); - stepNames.add(stepName); - - String durationStr = stepElement.getAttribute("duration"); - long stepDuration = durationStr != "" ? Long.parseLong(durationStr) : 0; - duration += stepDuration; - - String stepStatus = stepElement.getAttribute("status"); - if (!statusDetermined && "pending".equals(stepStatus)) { - status = TestResultStatus.SKIPPED; - statusDetermined = true; - } else if (!statusDetermined && "failed".equals(stepStatus)) { - status = TestResultStatus.FAILED; - statusDetermined = true; - } - } - - private List getStepElements(NodeList backgroundSteps, Element scenarioElement) { - List stepElements = new ArrayList(); - if(backgroundSteps != null) { - for (int bs = 0; bs < backgroundSteps.getLength(); bs++) { - Element stepElement = (Element) backgroundSteps.item(bs); - stepElements.add(stepElement); - } - } - NodeList stepNodes = scenarioElement.getElementsByTagName("step"); - for (int sn = 0; sn < stepNodes.getLength(); sn++) { - Element stepElement = (Element) stepNodes.item(sn); - stepElements.add(stepElement); - } - - return stepElements; - } - - private String getScenarioName(Element scenarioElement) { - String scenarioName = scenarioElement.getAttribute("name"); - if (scenarioElement.hasAttribute("outlineIndex")) { - String outlineIndexStr = scenarioElement.getAttribute("outlineIndex"); - if (outlineIndexStr != null && !outlineIndexStr.isEmpty()) { - Integer outlineIndex = Integer.valueOf(scenarioElement.getAttribute("outlineIndex")); - if (outlineIndex > 1) { - //we add the index only from 2 and upwards seeing as that is the naming convention in junit xml. - String delimiter = " "; - if (!scenarioName.contains(" ")) { - //we need to use the same logic as used in the junit report - delimiter = "_"; - } - scenarioName = scenarioName + delimiter + scenarioElement.getAttribute("outlineIndex"); - } - } - - } - return scenarioName; - } - } - } - - private static void validateXMLVersion(Document doc) { - String XML_VERSION = "1"; - NodeList featuresNodes = doc.getElementsByTagName("features"); - if(featuresNodes.getLength() > 0) { - String versionAttr = ((Element) featuresNodes.item(0)).getAttribute("version"); - if (versionAttr == null || versionAttr.isEmpty() || versionAttr.compareTo(XML_VERSION) != 0) { - throw new IllegalArgumentException("\n********************************************************\n" + - "Incompatible xml version received from the Octane formatter.\n" + - "expected version = " + XML_VERSION + " actual version = " + versionAttr + ".\n" + - "You may need to update the octane formatter version to the correct version in order to work with this jenkins plugin\n" + - "********************************************************"); - } - } else { - throw new IllegalArgumentException("The file does not contain Octane Gherkin results. Configuration error?"); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java b/src/main/java/com/hp/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java deleted file mode 100644 index db1482b0cc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.impl; - -import hudson.FilePath; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.util.Iterator; -import java.util.NoSuchElementException; - -public class ObjectStreamIterator implements Iterator { - private static Logger logger = LogManager.getLogger(ObjectStreamIterator.class); - - private MyObjectInputStream ois; - private FilePath filePath; - private E next; - - public ObjectStreamIterator(FilePath filePath, boolean deleteOnClose) throws IOException, InterruptedException { - this.filePath = filePath; - ois = new MyObjectInputStream(new BufferedInputStream(filePath.read()), deleteOnClose); - } - - @Override - public boolean hasNext() { - if (next != null) { - return true; - } - try { - next = (E) ois.readObject(); - return true; - } catch (Exception e) { - ois.close(); - return false; - } - } - - @Override - public E next() { - if (hasNext()) { - E value = next; - next = null; - return value; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private class MyObjectInputStream extends ObjectInputStream { - - private boolean deleteOnClose; - - public MyObjectInputStream(InputStream in, boolean deleteOnClose) throws IOException { - super(in); - this.deleteOnClose = deleteOnClose; - } - - @Override - public void close() { - try { - super.close(); - } catch (IOException ioe) { - logger.error("Failed to close the stream", ioe); // NON-NLS - } - if (deleteOnClose) { - try { - filePath.delete(); - } catch (Exception e) { - logger.error("Failed to perform clean up", e); // NON-NLS - } - } - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java deleted file mode 100644 index 67cdcfb46b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import com.hp.application.automation.tools.octane.tests.build.BuildHandlerUtils; -import hudson.FilePath; -import hudson.model.Run; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -public abstract class AbstractMavenModuleDetection implements ModuleDetection { - - protected FilePath rootDir; - protected List pomDirs; - - public AbstractMavenModuleDetection(Run build) { - rootDir = BuildHandlerUtils.getWorkspace(build); - pomDirs = new LinkedList<>(); - - addPomDirectories(build); - } - - protected abstract void addPomDirectories(Run build); - - @Override - public String getModule(FilePath resultFile) throws IOException, InterruptedException { - for (FilePath pomDir: pomDirs) { - if (childOf(pomDir, resultFile)) { - return normalize(locatePom(resultFile, pomDir)); - } - } - // unable to determine module - return null; - } - - protected void addPomDirectory(FilePath pomDir) { - pomDirs.add(pomDir); - } - - protected boolean childOf(FilePath parent, FilePath child) { - while (child != null) { - if (parent.equals(child)) { - return true; - } - child = child.getParent(); - } - return false; - } - - - private String locatePom(FilePath filePath, FilePath pomDir) throws IOException, InterruptedException { - while (filePath != null) { - FilePath parentPath = filePath.getParent(); - if (parentPath.equals(pomDir)) { - // walk up as far as the enclosing pom directory - break; - } - FilePath pomPath = new FilePath(parentPath, "pom.xml"); - if (pomPath.exists()) { - // we found a nested pom directory - return parentPath.getRemote().substring(rootDir.getRemote().length()); - } - filePath = parentPath; - } - // no other pom found in nested directories - return pomDir.getRemote().substring(rootDir.getRemote().length()); - } - - private String normalize(String path) { - return path.replace("\\", "/").replaceFirst("^/", ""); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitExtension.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitExtension.java deleted file mode 100644 index 6f8d9d8bec..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitExtension.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.actions.cucumber.CucumberTestResultsAction; -import com.hp.application.automation.tools.octane.tests.HPRunnerType; -import com.hp.application.automation.tools.octane.tests.MqmTestsExtension; -import com.hp.application.automation.tools.octane.tests.TestResultContainer; -import com.hp.application.automation.tools.octane.tests.build.BuildHandlerUtils; -import com.hp.application.automation.tools.octane.tests.detection.ResultFields; -import com.hp.application.automation.tools.octane.tests.detection.ResultFieldsDetectionService; -import com.hp.application.automation.tools.octane.tests.impl.ObjectStreamIterator; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import hudson.Extension; -import hudson.FilePath; -import hudson.maven.MavenBuild; -import hudson.maven.MavenModule; -import hudson.maven.MavenModuleSetBuild; -import hudson.model.Run; -import hudson.remoting.VirtualChannel; -import hudson.tasks.test.AbstractTestResultAction; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jenkinsci.remoting.Role; -import org.jenkinsci.remoting.RoleChecker; - -import javax.xml.stream.XMLStreamException; -import java.io.*; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -@Extension -public class JUnitExtension extends MqmTestsExtension { - private static Logger logger = LogManager.getLogger(JUnitExtension.class); - - public static final String STORM_RUNNER = "StormRunner"; - public static final String LOAD_RUNNER = "LoadRunner"; - - private static final String JUNIT_RESULT_XML = "junitResult.xml"; // NON-NLS - - private static final String PREFORMANCE_REPORT = "PerformanceReport"; - private static final String TRANSACTION_SUMMARY = "TransactionSummary"; - @Inject - ResultFieldsDetectionService resultFieldsDetectionService; - - public boolean supports(Run build) throws IOException, InterruptedException { - if (build.getAction(CucumberTestResultsAction.class) != null) { - logger.debug("CucumberTestResultsAction found. Will not process JUnit results."); - return false; - } else if (build.getAction(AbstractTestResultAction.class) != null) { - logger.debug("AbstractTestResultAction found, JUnit results expected"); - return true; - } else { - logger.debug("AbstractTestResultAction not found, no JUnit results expected"); - return false; - } - } - - @Override - public TestResultContainer getTestResults(Run build, HPRunnerType hpRunnerType, String jenkinsRootUrl) throws IOException, InterruptedException { - logger.debug("Collecting JUnit results"); - - boolean isLoadRunnerProject = isLoadRunnerProject(build); - FilePath resultFile = new FilePath(build.getRootDir()).child(JUNIT_RESULT_XML); - if (resultFile.exists()) { - logger.debug("JUnit result report found"); - ResultFields detectedFields = null; - if (hpRunnerType.equals(HPRunnerType.StormRunner)) { - detectedFields = new ResultFields(null, STORM_RUNNER, null); - } else if (isLoadRunnerProject) { - detectedFields = new ResultFields(null, LOAD_RUNNER, null); - } else { - //@// TODO: 15/02/2017 - should handle the workflow build - detectedFields = resultFieldsDetectionService.getDetectedFields(build); - } - FilePath filePath= BuildHandlerUtils.getWorkspace(build).act(new GetJUnitTestResults(build, Arrays.asList(resultFile), shallStripPackageAndClass(detectedFields), hpRunnerType, jenkinsRootUrl)); - return new TestResultContainer(new ObjectStreamIterator(filePath, true), detectedFields); - } else { - //avoid java.lang.NoClassDefFoundError when maven plugin is not present - if ("hudson.maven.MavenModuleSetBuild".equals(build.getClass().getName())) { - logger.debug("MavenModuleSetBuild detected, looking for results in maven modules"); - - List resultFiles = new LinkedList(); - Map moduleLastBuilds = ((MavenModuleSetBuild) build).getModuleLastBuilds(); - for (MavenBuild mavenBuild : moduleLastBuilds.values()) { - AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); - if (action != null) { - FilePath moduleResultFile = new FilePath(mavenBuild.getRootDir()).child(JUNIT_RESULT_XML); - if (moduleResultFile.exists()) { - logger.debug("Found results in " + mavenBuild.getFullDisplayName()); - resultFiles.add(moduleResultFile); - } - } - } - if (!resultFiles.isEmpty()) { - ResultFields detectedFields = null; - if (hpRunnerType.equals(HPRunnerType.StormRunner)) { - detectedFields = new ResultFields(null, STORM_RUNNER, null); - } else if (isLoadRunnerProject) { - detectedFields = new ResultFields(null, LOAD_RUNNER, null); - } else { - detectedFields = resultFieldsDetectionService.getDetectedFields(build); - } - FilePath filePath = BuildHandlerUtils.getWorkspace(build).act(new GetJUnitTestResults(build, resultFiles, shallStripPackageAndClass(detectedFields), hpRunnerType, jenkinsRootUrl)); - return new TestResultContainer(new ObjectStreamIterator(filePath, true), detectedFields); - } - } - logger.debug("No JUnit result report found"); - return null; - } - } - - private boolean shallStripPackageAndClass(ResultFields resultFields) { - if (resultFields == null) { - return false; - } - return resultFields.equals(new ResultFields("UFT", "UFT", null)); - } - - private boolean isLoadRunnerProject(Run build) throws IOException, InterruptedException { - FilePath preformanceReportFolder = new FilePath(build.getRootDir()).child(PREFORMANCE_REPORT); - FilePath transactionSummaryFolder = new FilePath(build.getRootDir()).child(TRANSACTION_SUMMARY); - if ((preformanceReportFolder.exists() && preformanceReportFolder.isDirectory()) && (transactionSummaryFolder.exists() && transactionSummaryFolder.isDirectory())) { - return true; - } - return false; - } - - private static class GetJUnitTestResults implements FilePath.FileCallable { - - private final List reports; - private final String jobName; - private final String buildId; - private final String jenkinsRootUrl; - private final HPRunnerType hpRunnerType; - private boolean isUFTProject = false; - private FilePath filePath; - private List moduleDetection; - private long buildStarted; - private FilePath workspace; - private boolean stripPackageAndClass; - - public GetJUnitTestResults( Run build, List reports, boolean stripPackageAndClass, HPRunnerType hpRunnerType, String jenkinsRootUrl) throws IOException, InterruptedException { - this.reports = reports; - this.filePath = new FilePath(build.getRootDir()).createTempFile(getClass().getSimpleName(), null); - this.buildStarted = build.getStartTimeInMillis(); - this.workspace = BuildHandlerUtils.getWorkspace(build);//build.getExecutor().getCurrentWorkspace();//build.getWorkspace(); - this.stripPackageAndClass = stripPackageAndClass; - this.hpRunnerType = hpRunnerType; - this.jenkinsRootUrl = jenkinsRootUrl; - //AbstractProject project = (AbstractProject)build.getParent();/*build.getProject()*/; - this.jobName =build.getParent().getName();// project.getName(); - this.buildId =BuildHandlerUtils.getBuildId(build);///*build.getProject()*/((AbstractProject)build.getParent()).getBuilds().getLastBuild().getId(); - moduleDetection =Arrays.asList( - new MavenBuilderModuleDetection(build), - new MavenSetModuleDetection(build), - new ModuleDetection.Default()); - } - - @Override - public FilePath invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { - OutputStream os = filePath.write(); - BufferedOutputStream bos = new BufferedOutputStream(os); - ObjectOutputStream oos = new ObjectOutputStream(bos); - - try { - for (FilePath report : reports) { - JUnitXmlIterator iterator = new JUnitXmlIterator(report.read(), moduleDetection, workspace, jobName, buildId, buildStarted, stripPackageAndClass, hpRunnerType, jenkinsRootUrl); - while (iterator.hasNext()) { - oos.writeObject(iterator.next()); - } - } - } catch (XMLStreamException e) { - throw new IOException(e); - } - os.flush(); - - oos.close(); - return filePath; - } - - @Override - public void checkRoles(RoleChecker roleChecker) throws SecurityException { - roleChecker.check(this, Role.UNKNOWN); - } - } - - /* - * To be used in tests only. - */ - public void _setResultFieldsDetectionService(ResultFieldsDetectionService detectionService) { - this.resultFieldsDetectionService = detectionService; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitTestResult.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitTestResult.java deleted file mode 100644 index 9b5e215ba0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitTestResult.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import java.io.Serializable; - -final public class JUnitTestResult implements Serializable, TestResult { - - private final String moduleName; - private final String packageName; - private final String className; - private final String testName; - private final TestResultStatus result; - private final long duration; - private final long started; - private final TestError testError; - private final String externalReportUrl; - - public JUnitTestResult(String moduleName, String packageName, String className, String testName, TestResultStatus result, long duration, long started, TestError testError, String externalReportUrl) { - this.moduleName = moduleName; - this.packageName = packageName; - this.className = className; - this.testName = testName; - this.result = result; - this.duration = duration; - this.started = started; - this.testError = testError; - this.externalReportUrl = externalReportUrl; - } - - public String getModuleName() { - return moduleName; - } - - public String getPackageName() { - return packageName; - } - - public String getClassName() { - return className; - } - - public String getTestName() { - return testName; - } - - public TestResultStatus getResult() { - return result; - } - - public long getDuration() { - return duration; - } - - public long getStarted() { - return started; - } - - public TestError getTestError() { - return testError; - } - - public String getExternalReportUrl() {return externalReportUrl;} - - @Override - public void writeXmlElement(XMLStreamWriter writer) throws XMLStreamException { - writer.writeStartElement("test_run"); - writer.writeAttribute("module", moduleName); - writer.writeAttribute("package", packageName); - writer.writeAttribute("class", className); - writer.writeAttribute("name", testName); - writer.writeAttribute("duration", String.valueOf(duration)); - writer.writeAttribute("status", result.toPrettyName()); - writer.writeAttribute("started", String.valueOf(started)); - if(externalReportUrl != null) { - writer.writeAttribute("external_report_url", externalReportUrl); - } - if (result.equals(TestResultStatus.FAILED) && testError != null) { - writer.writeStartElement("error"); - writer.writeAttribute("type", String.valueOf(testError.getErrorType())); - writer.writeAttribute("message", String.valueOf(testError.getErrorMsg())); - writer.writeCharacters(testError.getStackTraceStr()); - writer.writeEndElement(); - } - writer.writeEndElement(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java deleted file mode 100644 index 8d833c6133..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import com.hp.application.automation.tools.octane.tests.HPRunnerType; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.tests.Property; -import com.hp.octane.integrations.dto.tests.TestSuite; -import com.hp.application.automation.tools.octane.tests.xml.AbstractXmlIterator; -import hudson.FilePath; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.Characters; -import javax.xml.stream.events.EndElement; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.text.DecimalFormat; -import java.text.ParseException; -import java.util.List; - -public class JUnitXmlIterator extends AbstractXmlIterator { - private static final Logger logger = LogManager.getLogger(JUnitXmlIterator.class); - - public static final String DASHBOARD_URL = "dashboardUrl"; - private final FilePath workspace; - private final long buildStarted; - private final String buildId; - private final String jobName; - private final HPRunnerType hpRunnerType; - private boolean stripPackageAndClass; - private String moduleName; - private String packageName; - private String className; - private String testName; - private long duration; - private TestResultStatus status; - private String stackTraceStr; - private String errorType; - private String errorMsg; - private String externalURL; - private List moduleDetection; - private String jenkinsRootUrl; - - public JUnitXmlIterator(InputStream read, List moduleDetection, FilePath workspace, String jobName, String buildId, long buildStarted, boolean stripPackageAndClass, HPRunnerType hpRunnerType, String jenkinsRootUrl) throws XMLStreamException { - super(read); - this.stripPackageAndClass = stripPackageAndClass; - this.moduleDetection = moduleDetection; - this.workspace = workspace; - this.buildId = buildId; - this.jobName = jobName; - this.buildStarted = buildStarted; - this.hpRunnerType = hpRunnerType; - this.jenkinsRootUrl = jenkinsRootUrl; - } - - private static long parseTime(String timeString) { - String time = timeString.replace(",", ""); - try { - float seconds = Float.parseFloat(time); - return (long) (seconds * 1000); - } catch (NumberFormatException e) { - try { - return new DecimalFormat().parse(time).longValue(); - } catch (ParseException ex) { - logger.debug("Unable to parse test duration: " + timeString); - } - } - return 0; - } - - private String getStormRunnerURL(String path) { - - String srUrl = null; - File srReport = new File(path); - if (srReport.exists()) { - TestSuite testSuite = DTOFactory.getInstance().dtoFromXmlFile(srReport, TestSuite.class); - - for (Property property : testSuite.getProperties()) { - if (property.getPropertyName().equals(DASHBOARD_URL)) { - srUrl = property.getPropertyValue(); - break; - } - } - } - return srUrl; - } - - @Override - protected void onEvent(XMLEvent event) throws XMLStreamException, IOException, InterruptedException { - if (event instanceof StartElement) { - StartElement element = (StartElement) event; - String localName = element.getName().getLocalPart(); - if ("file".equals(localName)) { // NON-NLS - String path = readNextValue(); - for (ModuleDetection detection : moduleDetection) { - moduleName = detection.getModule(new FilePath(new File(path))); - if (moduleName != null) { - break; - } - } - if (hpRunnerType.equals(HPRunnerType.StormRunner)) { - logger.error("HP Runner: " + hpRunnerType); - externalURL = getStormRunnerURL(path); - } - } else if ("case".equals(localName)) { // NON-NLS - packageName = ""; - className = ""; - testName = ""; - duration = 0; - status = TestResultStatus.PASSED; - stackTraceStr = ""; - errorType = ""; - errorMsg = ""; - } else if ("className".equals(localName)) { // NON-NLS - String fqn = readNextValue(); - int p = fqn.lastIndexOf("."); - className = fqn.substring(p + 1); - if (p > 0) { - packageName = fqn.substring(0, p); - } else { - packageName = ""; - } - } else if ("testName".equals(localName)) { // NON-NLS - testName = readNextValue(); - if (testName.startsWith(workspace.getRemote())) { - // if workspace is prefix of the method name, cut it off - // currently this handling is needed for UFT tests - testName = testName.substring(workspace.getRemote().length()).replaceAll("^[/\\\\]", ""); - } - if (hpRunnerType.equals(HPRunnerType.UFT)) { - externalURL = jenkinsRootUrl + "job/" + jobName + "/" + buildId + "/artifact/UFTReport/" + cleanTestName(testName) + "/run_results.html"; - } - } else if ("duration".equals(localName)) { // NON-NLS - duration = parseTime(readNextValue()); - } else if ("skipped".equals(localName)) { // NON-NLS - if ("true".equals(readNextValue())) { // NON-NLS - status = TestResultStatus.SKIPPED; - } - } else if ("failedSince".equals(localName)) { // NON-NLS - if (!"0".equals(readNextValue()) && !TestResultStatus.SKIPPED.equals(status)) { - status = TestResultStatus.FAILED; - } - } else if ("errorStackTrace".equals(localName)) { // NON-NLS - status = TestResultStatus.FAILED; - stackTraceStr = ""; - if (peek() instanceof Characters) { - stackTraceStr = readNextValue(); - int index = stackTraceStr.indexOf("at "); - if (index >= 0) { - errorType = stackTraceStr.substring(0, index); - } - } - } else if ("errorDetails".equals(localName)) { // NON-NLS - status = TestResultStatus.FAILED; - errorMsg = readNextValue(); - int index = stackTraceStr.indexOf(":"); - if (index >= 0) { - errorType = stackTraceStr.substring(0, index); - } - - } - } else if (event instanceof EndElement) { - EndElement element = (EndElement) event; - String localName = element.getName().getLocalPart(); - - if ("case".equals(localName)) { // NON-NLS - TestError testError = new TestError(stackTraceStr, errorType, errorMsg); - if (stripPackageAndClass) { - //workaround only for UFT - we do not want packageName="All-Tests" and className="<None>" as it comes from JUnit report - addItem(new JUnitTestResult(moduleName, "", "", testName, status, duration, buildStarted, testError, externalURL)); - } else { - addItem(new JUnitTestResult(moduleName, packageName, className, testName, status, duration, buildStarted, testError, externalURL)); - } - } - } - } - - private String cleanTestName(String testName) { - // subfolder\testname - if (testName.contains("\\")) { - return testName.substring(testName.lastIndexOf("\\") + 1); - } - return testName; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java deleted file mode 100644 index 4171172f04..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import hudson.FilePath; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.model.Project; -import hudson.model.Run; -import hudson.tasks.Builder; -import hudson.tasks.Maven; - -import java.io.File; - -public class MavenBuilderModuleDetection extends AbstractMavenModuleDetection { - - public MavenBuilderModuleDetection(Run build) { - super(build); - } - - protected void addPomDirectories(Run build) { - if (build instanceof AbstractBuild) { - - if (((AbstractBuild)build).getProject() instanceof FreeStyleProject || - "hudson.matrix.MatrixConfiguration".equals(((AbstractBuild)build).getProject().getClass().getName())) { - boolean unknownBuilder = false; - for (Builder builder : ((Project) ((AbstractBuild)build).getProject()).getBuilders()) { - if (builder instanceof Maven) { - Maven maven = (Maven) builder; - if (maven.pom != null) { - if (maven.pom.endsWith("/pom.xml") || maven.pom.endsWith("\\pom.xml")) { - addPomDirectory(new FilePath(rootDir, maven.pom.substring(0, maven.pom.length() - 8))); - continue; - } else { - int p = maven.pom.lastIndexOf(File.separatorChar); - if (p > 0) { - addPomDirectory(new FilePath(rootDir, maven.pom.substring(0, p))); - continue; - } - } - } - addPomDirectory(rootDir); - } else { - unknownBuilder = true; - } - } - if (unknownBuilder && !pomDirs.contains(rootDir)) { - // attempt to support shell and batch executions too - // simply assume there is top-level pom file for any non-maven builder - addPomDirectory(rootDir); - } - } - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java deleted file mode 100644 index f9bb13e963..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import hudson.maven.MavenBuild; -import hudson.maven.MavenModuleSetBuild; -import hudson.model.AbstractBuild; -import hudson.model.Run; - -import java.util.Collection; -import java.util.List; - -public class MavenSetModuleDetection extends AbstractMavenModuleDetection { - - public MavenSetModuleDetection(Run build) { - super(build); - } - - protected void addPomDirectories(Run build) { - if (build instanceof MavenModuleSetBuild) { - Collection> builds = ((MavenModuleSetBuild) build).getModuleBuilds().values(); - for (List builds1 : builds) { - for (MavenBuild build2 : builds1) { - addPomDirectory(build2.getWorkspace()); - } - } - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/ModuleDetection.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/ModuleDetection.java deleted file mode 100644 index b79bb9a17f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/ModuleDetection.java +++ /dev/null @@ -1,21 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests.junit; - -import hudson.FilePath; - -import java.io.IOException; -import java.io.Serializable; - -public interface ModuleDetection extends Serializable { - - String getModule(FilePath resultFile) throws IOException, InterruptedException; - - class Default implements ModuleDetection { - - @Override - public String getModule(FilePath resultFile) throws IOException, InterruptedException { - return ""; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestError.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestError.java deleted file mode 100644 index 37c982ad1e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestError.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.junit; - -import java.io.Serializable; - -/** - * Created by lev on 14/03/2016. - */ -public final class TestError implements Serializable { - private final String stackTraceStr; - private final String errorType; - private final String errorMsg; - - public TestError(String stackTraceStr, String errorType, String errorMsg) { - this.stackTraceStr = stackTraceStr; - this.errorType = errorType; - this.errorMsg = errorMsg; - } - - public String getStackTraceStr() { - return stackTraceStr; - } - - public String getErrorType() { - return errorType; - } - - public String getErrorMsg() { - return errorMsg; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestResultStatus.java b/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestResultStatus.java deleted file mode 100644 index 6c48dea46d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/junit/TestResultStatus.java +++ /dev/null @@ -1,29 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests.junit; - -public enum TestResultStatus { - - PASSED("Passed"), - SKIPPED("Skipped"), - FAILED("Failed"); - - private final String prettyName; - - private TestResultStatus(String prettyName) { - this.prettyName = prettyName; - } - - public String toPrettyName() { - return prettyName; - } - - public static TestResultStatus fromPrettyName(String prettyName) { - for (TestResultStatus status : values()) { - if (status.toPrettyName().equals(prettyName)) { - return status; - } - } - throw new IllegalArgumentException("Unsupported TestResultStatus '" + prettyName + "'."); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/testResult/TestResult.java b/src/main/java/com/hp/application/automation/tools/octane/tests/testResult/TestResult.java deleted file mode 100644 index a609ebc15b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/testResult/TestResult.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.testResult; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -public interface TestResult { - - /** - * Writes an XML element from the test result - */ - void writeXmlElement(XMLStreamWriter writer) throws XMLStreamException; -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java b/src/main/java/com/hp/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java deleted file mode 100644 index cab4762fd0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.xml; - -import org.apache.commons.io.IOUtils; - -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.Characters; -import javax.xml.stream.events.EndElement; -import javax.xml.stream.events.XMLEvent; -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedList; -import java.util.NoSuchElementException; - -public abstract class AbstractXmlIterator { - - private InputStream is; - protected XMLEventReader reader; - private LinkedList queue; - private boolean closed; - - public AbstractXmlIterator(InputStream is) throws XMLStreamException { - this.is = is; - reader = createXmlInputFactory().createXMLEventReader(is); - queue = new LinkedList(); - } - - public XMLEvent peek() throws XMLStreamException { - return reader.peek(); - } - - public boolean hasNext() throws XMLStreamException, IOException, InterruptedException { - while (queue.isEmpty() && !closed) { - if (reader.hasNext()) { - onEvent(reader.nextEvent()); - } else { - try { - reader.close(); - } catch (XMLStreamException e) { - // close quietly - } - IOUtils.closeQuietly(is); - closed = true; - } - } - return !queue.isEmpty(); - } - - public E next() throws XMLStreamException, IOException, InterruptedException { - if (!hasNext()) { - throw new NoSuchElementException(); - } else { - return queue.removeFirst(); - } - } - - protected abstract void onEvent(XMLEvent event) throws XMLStreamException, IOException, InterruptedException; - - protected void addItem(E item) { - queue.add(item); - } - - protected String readNextValue() throws XMLStreamException { - XMLEvent nextEvent = reader.nextEvent(); - if(nextEvent instanceof EndElement){ - return ""; - } else { - return ((Characters)nextEvent).getData(); - } - } - - private static XMLInputFactory createXmlInputFactory() { - XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); - xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); - xmlFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); - return xmlFactory; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java b/src/main/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java deleted file mode 100644 index dff5115902..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.xml; - -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.tests.TestResultContainer; -import com.hp.application.automation.tools.octane.tests.build.BuildDescriptor; -import com.hp.application.automation.tools.octane.tests.build.BuildHandlerUtils; -import com.hp.application.automation.tools.octane.tests.detection.ResultFields; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import hudson.FilePath; -import hudson.model.Run; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; - -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; - -@SuppressWarnings("all") -public class TestResultXmlWriter { - - private FilePath targetPath; - //private Run build; - private BuildDescriptor buildDescriptor; - - private XMLStreamWriter writer; - private OutputStream outputStream; - - public TestResultXmlWriter(FilePath targetPath, BuildDescriptor buildDescriptor) { - this.targetPath = targetPath; - this.buildDescriptor = buildDescriptor; - } - - public TestResultXmlWriter(FilePath targetPath, Run build) { - this.targetPath = targetPath; - //this.build = build; - this.buildDescriptor = BuildHandlerUtils.getBuildType(build); - } - - public void writeResults(TestResultContainer testResultContainer) throws InterruptedException, XMLStreamException, IOException { - if (testResultContainer != null) { - ResultFields resultFields = testResultContainer.getResultFields(); - initialize(resultFields); - - Iterator testResults = testResultContainer.getIterator(); - while (testResults.hasNext()) { - TestResult testResult = testResults.next(); - testResult.writeXmlElement(writer); - } - } - } - - public void close() throws XMLStreamException { - if (outputStream != null) { - writer.writeEndElement(); // test_runs - writer.writeEndElement(); // test_result - writer.writeEndDocument(); - writer.close(); - IOUtils.closeQuietly(outputStream); - } - } - - private void initialize(ResultFields resultFields) throws IOException, InterruptedException, XMLStreamException { - if (outputStream == null) { - outputStream = targetPath.write(); - writer = possiblyCreateIndentingWriter(XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream)); - writer.writeStartDocument(); - - writer.writeStartElement("test_result"); - writer.writeStartElement("build"); - writer.writeAttribute("server_id", ConfigurationService.getModel().getIdentity()); - BuildDescriptor descriptor = this.buildDescriptor; - writer.writeAttribute("job_id", descriptor.getJobId()); - writer.writeAttribute("job_name", descriptor.getJobName()); - writer.writeAttribute("build_id", descriptor.getBuildId()); - writer.writeAttribute("build_name", descriptor.getBuildName()); - if (!StringUtils.isEmpty(descriptor.getSubType())) { - writer.writeAttribute("sub_type", descriptor.getSubType()); - } - writer.writeEndElement(); // build - writeFields(resultFields); - writer.writeStartElement("test_runs"); - } - } - - private void writeFields(ResultFields resultFields) throws XMLStreamException { - if (resultFields != null) { - writer.writeStartElement("test_fields"); - writeField("Framework", resultFields.getFramework()); - writeField("Test_Level", resultFields.getTestLevel()); - writeField("Testing_Tool_Type", resultFields.getTestingTool()); - writer.writeEndElement(); - } - } - - private void writeField(String type, String value) throws XMLStreamException { - if (value != null) { - writer.writeStartElement("test_field"); - writer.writeAttribute("type", type); - writer.writeAttribute("value", value); - writer.writeEndElement(); - } - } - - // TODO: check if there is public mechanism yet - private XMLStreamWriter possiblyCreateIndentingWriter(XMLStreamWriter writer) { - try { - Class clazz = Class.forName("com.sun.xml.txw2.output.IndentingXMLStreamWriter"); - XMLStreamWriter xmlStreamWriter = (XMLStreamWriter) clazz.getConstructor(XMLStreamWriter.class).newInstance(writer); - clazz.getMethod("setIndentStep", String.class).invoke(xmlStreamWriter, " "); - return xmlStreamWriter; - } catch (Exception e) { - // do without indentation - return writer; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/workflow/BuildRelations.java b/src/main/java/com/hp/application/automation/tools/octane/workflow/BuildRelations.java deleted file mode 100644 index b2f00405c1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/workflow/BuildRelations.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.workflow; - -import com.hp.octane.integrations.dto.causes.CIEventCause; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/* - * Created by gadiel on 21/06/2016. - */ -public class BuildRelations { - private static BuildRelations instance; - private static Map map; - - private BuildRelations() - { - map = new ConcurrentHashMap(); - } - - public static BuildRelations getInstance() - { - if(instance == null) - instance = new BuildRelations(); - return instance; - } - - public void removePairByKey(String key) - { - if(map.containsKey(key)) - { - map.remove(key); - } - } - public void addBuildRelation(String projectName, CIEventCause ciEventCause) - { - map.put(projectName,ciEventCause); - } - - public boolean containKey(String key) - { - return map.containsKey(key); - } - - public CIEventCause getValue(String key) - { - return (CIEventCause)map.get(key); - } - - public String print() - { - String totalMap=""; - for(String s : map.keySet()) - { - totalMap = totalMap.concat(s+"_"); - } - return totalMap; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowBuildAdapter.java b/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowBuildAdapter.java deleted file mode 100644 index 0ac93aeaf9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowBuildAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.workflow; - -import hudson.*; -import hudson.model.*; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import javax.annotation.Nonnull; -import hudson.model.Job; - -import java.io.File; -import java.io.IOException; - - -/** - * Created by lazara on 31/01/2017. - */ -public class WorkflowBuildAdapter extends Run { - - private WorkflowRun run; - private FilePath workspace; - protected WorkflowBuildAdapter(@Nonnull Job job, WorkflowRun run,FilePath workspace) throws IOException { - super(job); - this.run = run; - this.workspace =workspace; - } - - @Override - public Job getParent() { - return run.getParent(); - } - - @Override - public String getId(){ - return run.getId(); - } - - @Override - public int getNumber() { - return run.getNumber(); - } - - @Override - public Action getAction(Class type){ - return run.getAction(type); - } - @Nonnull - @Override - public File getRootDir() { - return run.getRootDir(); - } - - @Override - public Executor getExecutor() { - return run.getExecutor(); - } - - public FilePath getWorkspace(){ - return workspace; - } -// build.getRootDir() -// build.getParent() -// build.getResult() -// build.getNumber() -// BuildHandlerUtils.getProjectFullName(build) -// build.setResult -} diff --git a/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowGraphListener.java b/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowGraphListener.java deleted file mode 100644 index 778451aed3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/octane/workflow/WorkflowGraphListener.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.workflow; - - -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.causes.CIEventCause; -import com.hp.octane.integrations.dto.causes.CIEventCauseType; - -import hudson.Extension; -import hudson.model.*; -import org.jenkinsci.plugins.workflow.actions.WorkspaceAction; -import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode; -import org.jenkinsci.plugins.workflow.flow.GraphListener; -import org.jenkinsci.plugins.workflow.graph.FlowNode; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import java.io.IOException; -import java.util.*; - -/** - * Created by gadiel on 07/06/2016. - */ -@Extension -public class WorkflowGraphListener implements GraphListener { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); -// private Stack finishedEventsStack = new Stack(); -// String lastDisplayName = ""; -// String lastId = ""; -// CIEventCause lastCIEventCause; - public static FlowNodeContainer container; - public void onNewHead(FlowNode flowNode) { - if (flowNode instanceof StepEndNode) { - //finishAllStartedEvents(); - WorkspaceAction workspaceAction =((StepEndNode) flowNode).getStartNode().getAction(WorkspaceAction.class); - if(workspaceAction!=null){ - - try { - WorkflowRun run = (WorkflowRun) flowNode.getExecution().getOwner().getExecutable(); - //TaskListener listener = flowNode.getExecution().getOwner().getListener(); - WorkflowBuildAdapter adapter = new WorkflowBuildAdapter(run.getParent(), run, workspaceAction.getWorkspace()); - FlowNodeContainer.addFlowNode(adapter); - } catch (IOException e) { - e.printStackTrace(); - } - } -// } else if (StageNodeExt.isStageNode(flowNode)) { -// // its a stage node - it is also a finish of previous stage -// finishAllStartedEvents(); -// // starting an event: -// dispatchStartEvent(flowNode); -// // after the dispatching of the event, we create the finish event and add it to the queue: -// createFinishEvent(flowNode); - } -// else if (flowNode instanceof StepAtomNode) // its outer Job -// { -// if(isItStageStep(flowNode)){ -// // its a stage node - it is also a finish of previous stage -// finishAllStartedEvents(); -// // starting an event: -// dispatchStartEvent(flowNode); -// // after the dispatching of the event, we create the finish event and add it to the queue: -// createFinishEvent(flowNode); -// }else if( isItBuildStep(flowNode)) -// popNewJobEvent(flowNode); // popping a new event (we want to draw it on NGA) -// } - - } - -// private boolean isItBuildStep(FlowNode flowNode) { -// return ((StepAtomNode) flowNode).getDescriptor().getFunctionName().equalsIgnoreCase("build"); -// } -// -// private boolean isItStageStep(FlowNode flowNode) { -// return ((StepAtomNode) flowNode).getDescriptor().getFunctionName().equalsIgnoreCase("stage"); -// } - -// private void popNewJobEvent(FlowNode flowNode) { -// // this option is off at the moment. -// // in general, we want to pop regular jobs that created inside a stage HERE, -// // and not in RunListenerImpl class. -// // the reason for that is that we need to care of the CAUSE issue. -// -// -// // getting real Jenkins object from its name. -// String buildActualName = flowNode.getDisplayName().replace("Building ", ""); -// TopLevelItem jobAsJenkinsObj = Jenkins.getInstance().getItem(buildActualName); -// -// if (jobAsJenkinsObj instanceof AbstractProject) { -// AbstractProject jobAsAbstractProject = (AbstractProject) jobAsJenkinsObj; -// List prevList = new LinkedList(); -// prevList.add(lastCIEventCause); -// CIEventCause cause = dtoFactory.newDTO(CIEventCause.class); -// cause.setType(CIEventCauseType.UPSTREAM) -// .setProject(lastDisplayName) -// .setBuildCiId(lastId) -// .setCauses(prevList); -// List tempList = new LinkedList(); -// tempList.add(cause); -// -// //creating CIEventCause and add it to the map -// List ListForMap = new LinkedList(); -// ListForMap.add(cause); -// CIEventCause causeForMap = dtoFactory.newDTO(CIEventCause.class); -// causeForMap.setType(CIEventCauseType.UPSTREAM) -// .setProject(jobAsAbstractProject.getDisplayName()) -// .setBuildCiId(String.valueOf(jobAsAbstractProject.getLastBuild().getNumber())) -// .setCauses(ListForMap); -// BuildRelations.getInstance().addBuildRelation(jobAsAbstractProject.getDisplayName() + String.valueOf(jobAsAbstractProject.getLastBuild().getNumber() + 1), causeForMap); -// -// -// // start event -// CIEvent event = dtoFactory.newDTO(CIEvent.class) -// .setEventType(CIEventType.STARTED) -// .setProject(jobAsAbstractProject.getDisplayName()) -// .setBuildCiId(String.valueOf(jobAsAbstractProject.getLastBuild().getNumber())) -// .setNumber(String.valueOf(jobAsAbstractProject.getLastBuild().getNumber())) -// .setStartTime(jobAsAbstractProject.getLastBuild().getStartTimeInMillis()) -// .setEstimatedDuration(jobAsAbstractProject.getLastBuild().getEstimatedDuration()) -// .setCauses(tempList); -// EventsService.getExtensionInstance().dispatchEvent(event); -// -// // finishEvent -// CIEventCause endCause = dtoFactory.newDTO(CIEventCause.class); -// endCause.setType(CIEventCauseType.UPSTREAM) -// .setProject(lastDisplayName) -// .setBuildCiId(lastId) -// .setCauses(prevList); -// List endTempList = new LinkedList(); -// endTempList.add(endCause); -// CIEvent endEvent = dtoFactory.newDTO(CIEvent.class) -// .setEventType(CIEventType.FINISHED) -// .setProject(jobAsAbstractProject.getDisplayName()) -// .setBuildCiId(String.valueOf(jobAsAbstractProject.getLastBuild().getNumber())) -// .setNumber(String.valueOf(jobAsAbstractProject.getLastBuild().getNumber())) -// .setStartTime(12345678910L) -// .setEstimatedDuration(12345678910L) -// .setCauses(endTempList) -// .setResult(CIBuildResult.SUCCESS) -// .setDuration(12345678910L); -//// finishedEventsQueue.add(endEvent); -// } -// -// } - - -// private void finishAllStartedEvents() { -// while (!finishedEventsStack.isEmpty()) { -// EventsService.getExtensionInstance().dispatchEvent(finishedEventsStack.pop()); -// } -// } - -// private List extractCauses(Run r) { -// return r.getCauses(); -// } - -// private String getParentName(FlowNode flowNode) { -// -// String url = null; -// try { -// url = flowNode.getUrl(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// String[] words = url.split("/"); -// return words[1]; -// } - - -// private String getParentId(FlowNode flowNode) { -// String url = null; -// try { -// url = flowNode.getUrl(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// String[] words = url.split("/"); -// return words[2]; -// } - -// -// private void dispatchStartEvent(FlowNode flowNode) { -// Long nodeStartTime = 0L; -// if ((flowNode.getAllActions().get(3) instanceof TimingAction)) { -// TimingAction t = (TimingAction) flowNode.getAllActions().get(3); -// nodeStartTime = t.getStartTime(); -// } -// List causeList = getCIEventCause(flowNode); -// CIEvent event = dtoFactory.newDTO(CIEvent.class) -// .setEventType(CIEventType.STARTED) -// .setProject(flowNode.getDisplayName()) -// .setBuildCiId(String.valueOf(flowNode.getId())) -// .setNumber(flowNode.getId()) -// .setStartTime(nodeStartTime) -// .setEstimatedDuration(FlowNodeUtil.getStageExecDuration(flowNode).getPauseDurationMillis()) -// .setCauses(causeList); -// EventsService.getExtensionInstance().dispatchEvent(event); -//// lastDisplayName = flowNode.getDisplayName(); -//// lastId = String.valueOf(flowNode.getId()); -//// lastCIEventCause = causeList.get(0); -// } -//// -// private void createFinishEvent(FlowNode flowNode) { -// String ParentName = getParentName(flowNode); -// String ParentBuildNum = getParentId(flowNode); -// CIEventCause endCause = dtoFactory.newDTO(CIEventCause.class) -// .setType(CIEventCauseType.UPSTREAM) -// .setProject(ParentName) -// .setBuildCiId(ParentBuildNum); -// List endTempList = new LinkedList(); -// endTempList.add(endCause); -// CIEvent endEvent = dtoFactory.newDTO(CIEvent.class) -// .setEventType(CIEventType.FINISHED) -// .setProject(flowNode.getDisplayName()) -// .setBuildCiId(String.valueOf(flowNode.getId())) -// .setNumber(flowNode.getId()) -// .setStartTime(12345678910L) -// .setEstimatedDuration(12345678910L) -// .setCauses(endTempList) -// .setResult(CIBuildResult.SUCCESS) -// .setDuration(12345678910L); -// finishedEventsStack.push(endEvent); -// } - -// private List getCIEventCause(FlowNode flowNode) { -// String ParentName = getParentName(flowNode); -// String ParentBuildNum = getParentId(flowNode); -// CIEventCause cause = dtoFactory.newDTO(CIEventCause.class) -// .setType(CIEventCauseType.UPSTREAM) -// .setProject(ParentName) -// .setBuildCiId(ParentBuildNum); -// List tempList = new LinkedList<>(); -// tempList.add(cause); -// return tempList; -// -// } - - public static class FlowNodeContainer{ - private static Map> map = new HashMap<>(); - - protected static void addFlowNode(Run run){ - String key = getKey(run); - List list = map.get(key); - - if(list == null){ - list = new ArrayList<>(); - map.put(key,list); - } - list.add(run); - } - - public static List getFlowNode(Run run){ - return map.remove(getKey(run)); - } - - private static String getKey(Run run) { - return run.getId() + run.getParent().getName(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcClient.java b/src/main/java/com/hp/application/automation/tools/pc/PcClient.java deleted file mode 100644 index f9f3139204..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcClient.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import hudson.FilePath; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.nio.file.*; -import java.util.ArrayList; -import java.util.Arrays; - -import hudson.console.HyperlinkNote; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.ClientProtocolException; - -import com.hp.application.automation.tools.common.PcException; -import com.hp.application.automation.tools.model.PcModel; -import com.hp.application.automation.tools.run.PcBuilder; - -public class PcClient { - - private PcModel model; - private PcRestProxy restProxy; - private boolean loggedIn; - private PrintStream logger; - - public PcClient(PcModel pcModel, PrintStream logger) { - model = pcModel; - restProxy = new PcRestProxy(model.getPcServerName(), model.getAlmDomain(), model.getAlmProject()); - this.logger = logger; - } - - public PcClient(PcModel pcModel, PrintStream logger, T proxy) { - model = pcModel; - restProxy = proxy; - this.logger = logger; - } - - public boolean login() { - try { - String user = model.getAlmUserName(); - logger.println(String.format("Trying to login\n[PCServer='%s', User='%s']", model.getPcServerName(), user)); - loggedIn = restProxy.authenticate(user, model.getAlmPassword().toString()); - } catch (PcException e) { - logger.println(e.getMessage()); - } catch (Exception e) { - logger.println(e); - } - logger.println(String.format("Login %s", loggedIn ? "succeeded" : "failed")); - return loggedIn; - } - - public boolean isLoggedIn() { - - return loggedIn; - } - - public int startRun() throws NumberFormatException, ClientProtocolException, PcException, IOException { - -// logger.println("Sending run request:\n" + model.runParamsToString()); - PcRunResponse response = restProxy.startRun(Integer.parseInt(model.getTestId()), - Integer.parseInt(model.getTestInstanceId()), - model.getTimeslotDuration(), - model.getPostRunAction().getValue(), - model.isVudsMode()); - logger.println(String.format("\nRun started (TestID: %s, RunID: %s, TimeslotID: %s)\n", - response.getTestID(), response.getID(), response.getTimeslotID())); - return response.getID(); - } - - public PcRunResponse waitForRunCompletion(int runId) throws InterruptedException, ClientProtocolException, PcException, IOException { - - return waitForRunCompletion(runId, 5000); - } - - public PcRunResponse waitForRunCompletion(int runId, int interval) throws InterruptedException, ClientProtocolException, PcException, IOException { - RunState state = RunState.UNDEFINED; - switch (model.getPostRunAction()) { - case DO_NOTHING: - state = RunState.BEFORE_COLLATING_RESULTS; - break; - case COLLATE: - state = RunState.BEFORE_CREATING_ANALYSIS_DATA; - break; - case COLLATE_AND_ANALYZE: - state = RunState.FINISHED; - break; - } - return waitForRunState(runId, state, interval); - } - - - private PcRunResponse waitForRunState(int runId, RunState completionState, int interval) throws InterruptedException, - ClientProtocolException, PcException, IOException { - - int counter = 0; - RunState[] states = {RunState.BEFORE_COLLATING_RESULTS,RunState.BEFORE_CREATING_ANALYSIS_DATA}; - PcRunResponse response = null; - RunState lastState = RunState.UNDEFINED; - do { - response = restProxy.getRunData(runId); - RunState currentState = RunState.get(response.getRunState()); - if (lastState.ordinal() < currentState.ordinal()) { - lastState = currentState; - logger.println(String.format("RunID: %s - State = %s", runId, currentState.value())); - } - - // In case we are in state before collate or before analyze, we will wait 1 minute for the state to change otherwise we exit - // because the user probably stopped the run from PC or timeslot has reached the end. - if (Arrays.asList(states).contains(currentState)){ - counter++; - Thread.sleep(1000); - if(counter > 60 ){ - logger.println(String.format("RunID: %s - Stopped from Performance Center side with state = %s", runId, currentState.value())); - break; - } - }else{ - counter = 0; - Thread.sleep(interval); - } - } while (lastState.ordinal() < completionState.ordinal()); - return response; - } - - public FilePath publishRunReport(int runId, String reportDirectory) throws IOException, PcException, InterruptedException { - PcRunResults runResultsList = restProxy.getRunResults(runId); - if (runResultsList.getResultsList() != null){ - for (PcRunResult result : runResultsList.getResultsList()) { - if (result.getName().equals(PcBuilder.pcReportArchiveName)) { - File dir = new File(reportDirectory); - dir.mkdirs(); - String reportArchiveFullPath = dir.getCanonicalPath() + IOUtils.DIR_SEPARATOR + PcBuilder.pcReportArchiveName; - logger.println("Publishing analysis report"); - restProxy.GetRunResultData(runId, result.getID(), reportArchiveFullPath); - FilePath fp = new FilePath(new File(reportArchiveFullPath)); - fp.unzip(fp.getParent()); - fp.delete(); - FilePath reportFile = fp.sibling(PcBuilder.pcReportFileName); - if (reportFile.exists()) - return reportFile; - } - } - } - logger.println("Failed to get run report"); - return null; - } - - public boolean logout() { - if (!loggedIn) - return true; - - boolean logoutSucceeded = false; - try { - logoutSucceeded = restProxy.logout(); - loggedIn = !logoutSucceeded; - } catch (PcException e) { - logger.println(e.getMessage()); - } catch (Exception e) { - logger.println(e); - } - logger.println(String.format("Logout %s", logoutSucceeded ? "succeeded" : "failed")); - return logoutSucceeded; - } - - public boolean stopRun(int runId) { - boolean stopRunSucceeded = false; - try { - logger.println("Stopping run"); - stopRunSucceeded = restProxy.stopRun(runId, "stop"); - } catch (PcException e) { - logger.println(e.getMessage()); - } catch (Exception e) { - logger.println(e); - } - logger.println(String.format("Stop run %s", stopRunSucceeded ? "succeeded" : "failed")); - return stopRunSucceeded; - } - - public PcRunEventLog getRunEventLog(int runId){ - try { - return restProxy.getRunEventLog(runId); - } catch (PcException e) { - logger.println(e.getMessage()); - } catch (Exception e) { - logger.println(e); - } - return null; - } - - public void addRunToTrendReport(int runId, String trendReportId){ - - TrendReportRequest trRequest = new TrendReportRequest(model.getAlmProject(), runId, null); - logger.println("Adding run: " + runId + " to trend report: " + trendReportId); - try { - restProxy.updateTrendReport(trendReportId, trRequest); - logger.println("Publishing run: " + runId + " on trend report: " + trendReportId); - } - catch (PcException e) { - logger.println("Failed to add run to trend report: " + e.getMessage()); - } - catch (IOException e) { - logger.println("Failed to add run to trend report: Problem connecting to PC Server"); - } - } - - public void waitForRunToPublishOnTrendReport(int runId, String trendReportId) throws PcException,IOException,InterruptedException{ - - ArrayList trendReportMetaDataResultsList; - boolean publishEnded = false; - int counter = 0; - - do { - trendReportMetaDataResultsList = restProxy.getTrendReportMetaData(trendReportId); - - if (trendReportMetaDataResultsList.isEmpty()) break; - - for (PcTrendedRun result : trendReportMetaDataResultsList) { - - if (result.getRunID() != runId) continue; - - if (result.getState().equals(PcBuilder.TRENDED) || result.getState().equals(PcBuilder.ERROR)){ - publishEnded = true; - logger.println("Run: " + runId + " publishing status: "+ result.getState()); - break; - }else{ - Thread.sleep(5000); - logger.println("Publishing..."); - counter++; - if(counter >= 120){ - logger.println("Error: Publishing didn't ended after 10 minutes, aborting..."); - break; - } - } - } - - }while (!publishEnded ); - } - - public boolean downloadTrendReportAsPdf(String trendReportId, String directory) throws PcException { - - - try { - logger.println("Downloading trend report: " + trendReportId + " in PDF format"); - InputStream in = restProxy.getTrendingPDF(trendReportId); - File dir = new File(directory); - if(!dir.exists()){ - dir.mkdirs(); - } - String filePath = directory + IOUtils.DIR_SEPARATOR + "trendReport" + trendReportId + ".pdf"; - Path destination = Paths.get(filePath); - Files.copy(in, destination, StandardCopyOption.REPLACE_EXISTING); - logger.println("Trend report: " + trendReportId + " was successfully downloaded"); - } - catch (Exception e) { - - logger.println("Failed to download trend report: " + e.getMessage()); - throw new PcException(e.getMessage()); - } - - return true; - - } - - public void publishTrendReport(String filePath, String trendReportId){ - - if (filePath == null){return;} - // return String.format( HyperlinkNote.encodeTo(filePath, "View trend report " + trendReportId)); - logger.println( HyperlinkNote.encodeTo(filePath, "View trend report " + trendReportId)); - - } - - -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcErrorResponse.java b/src/main/java/com/hp/application/automation/tools/pc/PcErrorResponse.java deleted file mode 100644 index cf355b8fd3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcErrorResponse.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.thoughtworks.xstream.XStream; - -public class PcErrorResponse { - - @SuppressWarnings("unused") - private String xmlns = PcRestProxy.PC_API_XMLNS; - - public String ExceptionMessage; - - public int ErrorCode; - - public PcErrorResponse(String exceptionMessage, int errorCode) { - ExceptionMessage = exceptionMessage; - ErrorCode = errorCode; - } - - public static PcErrorResponse xmlToObject(String xml) { - XStream xstream = new XStream(); - xstream.setClassLoader(PcErrorResponse.class.getClassLoader()); - xstream.alias("Exception", PcErrorResponse.class); - return (PcErrorResponse) xstream.fromXML(xml); - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRestProxy.java b/src/main/java/com/hp/application/automation/tools/pc/PcRestProxy.java deleted file mode 100644 index 8bfe0cfabc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRestProxy.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.hp.application.automation.tools.common.PcException; -import com.hp.application.automation.tools.model.TimeslotDuration; -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.client.protocol.ClientContext; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.impl.conn.SchemeRegistryFactory; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.apache.commons.httpclient.HttpStatus.*; - -public class PcRestProxy { - - protected static final String BASE_PC_API_URL = "http://%s/LoadTest/rest"; - protected static final String BASE_PC_API_AUTHENTICATION_URL = BASE_PC_API_URL + "/authentication-point"; - protected static final String AUTHENTICATION_LOGIN_URL = BASE_PC_API_AUTHENTICATION_URL + "/authenticate"; - protected static final String AUTHENTICATION_LOGOUT_URL = BASE_PC_API_AUTHENTICATION_URL + "/logout"; - protected static final String PC_API_RESOURCES_TEMPLATE = BASE_PC_API_URL + "/domains/%s/projects/%s"; - protected static final String RUNS_RESOURCE_NAME = "Runs"; - protected static final String RESULTS_RESOURCE_NAME = "Results"; - protected static final String EVENTLOG_RESOURCE_NAME = "EventLog"; - protected static final String TREND_REPORT_RESOURCE_NAME = "TrendReports"; - protected static final String TREND_REPORT_RESOURCE_SUFFIX = "data"; - protected static final String CONTENT_TYPE_XML = "application/xml"; - static final String PC_API_XMLNS = "http://www.hp.com/PC/REST/API"; - - protected static final List validStatusCodes = Arrays.asList(SC_OK, SC_CREATED, SC_ACCEPTED, SC_NO_CONTENT); - - private String baseURL; - private String pcServer; - private String domain; - private String project; - - private HttpClient client; - private HttpContext context; - private CookieStore cookieStore; - - public PcRestProxy(String pcServerName, String almDomain, String almProject) { - - pcServer = pcServerName; - domain = almDomain; - project = almProject; - baseURL = String.format(PC_API_RESOURCES_TEMPLATE, pcServer, domain, project); - - PoolingClientConnectionManager cxMgr = new PoolingClientConnectionManager(SchemeRegistryFactory.createDefault()); - cxMgr.setMaxTotal(100); - cxMgr.setDefaultMaxPerRoute(20); - - client = new DefaultHttpClient(cxMgr); - context = new BasicHttpContext(); - cookieStore = new BasicCookieStore(); - context.setAttribute(ClientContext.COOKIE_STORE, cookieStore); - } - - - public boolean authenticate(String userName, String password) throws PcException, ClientProtocolException, IOException { - - String userNameAndPassword = userName + ":" + password; - String encodedCredentials = Base64Encoder.encode(userNameAndPassword.getBytes()); - HttpGet authRequest = new HttpGet(String.format(AUTHENTICATION_LOGIN_URL, pcServer)); - authRequest.addHeader("Authorization", String.format("Basic %s", encodedCredentials)); - executeRequest(authRequest); - return true; - } - - public PcRunResponse startRun(int testId, int testInstaceId, TimeslotDuration timeslotDuration, - String postRunAction, boolean vudsMode) throws PcException, ClientProtocolException, IOException { - HttpPost startRunRequest = new HttpPost(String.format(baseURL + "/%s", RUNS_RESOURCE_NAME)); - startRunRequest.addHeader(RESTConstants.CONTENT_TYPE, CONTENT_TYPE_XML); - PcRunRequest runRequestData = new PcRunRequest(testId, testInstaceId, 0, timeslotDuration, postRunAction, vudsMode); - startRunRequest.setEntity(new StringEntity(runRequestData.objectToXML(), ContentType.APPLICATION_XML)); - HttpResponse response = executeRequest(startRunRequest); - String startRunResponse = IOUtils.toString(response.getEntity().getContent()); - return PcRunResponse.xmlToObject(startRunResponse); - } - - public boolean stopRun(int runId, String stopMode) throws PcException, ClientProtocolException, IOException { - String stopUrl = String.format(baseURL + "/%s/%s/%s", RUNS_RESOURCE_NAME, runId, stopMode); - HttpPost stopRunRequest = new HttpPost(stopUrl); - ReleaseTimeslot releaseTimesloteRequest = new ReleaseTimeslot(true, "Do Not Collate"); - stopRunRequest.addHeader(RESTConstants.CONTENT_TYPE, CONTENT_TYPE_XML); - stopRunRequest.setEntity(new StringEntity (releaseTimesloteRequest.objectToXML(),ContentType.APPLICATION_XML)); - executeRequest(stopRunRequest); - return true; - } - - public PcRunResponse getRunData(int runId) throws PcException, ClientProtocolException, IOException { - HttpGet getRunDataRequest = new HttpGet(String.format(baseURL + "/%s/%s", RUNS_RESOURCE_NAME, runId)); - HttpResponse response = executeRequest(getRunDataRequest); - String runData = IOUtils.toString(response.getEntity().getContent()); - return PcRunResponse.xmlToObject(runData); - } - - public PcRunResults getRunResults(int runId) throws PcException, ClientProtocolException, IOException { - String getRunResultsUrl = String - .format(baseURL + "/%s/%s/%s", RUNS_RESOURCE_NAME, runId, RESULTS_RESOURCE_NAME); - HttpGet getRunResultsRequest = new HttpGet(getRunResultsUrl); - HttpResponse response = executeRequest(getRunResultsRequest); - String runResults = IOUtils.toString(response.getEntity().getContent()); - return PcRunResults.xmlToObject(runResults); - } - - public boolean GetRunResultData(int runId, int resultId, String localFilePath) throws PcException, ClientProtocolException, IOException { - String getRunResultDataUrl = String.format(baseURL + "/%s/%s/%s/%s/data", RUNS_RESOURCE_NAME, runId, - RESULTS_RESOURCE_NAME, resultId); - HttpGet getRunResultRequest = new HttpGet(getRunResultDataUrl); - HttpResponse response = executeRequest(getRunResultRequest); - OutputStream out = new FileOutputStream(localFilePath); - InputStream in = response.getEntity().getContent(); - IOUtils.copy(in, out); - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); - return true; - } - - - public ArrayList getTrendReportMetaData (String trendReportId) throws PcException, ClientProtocolException, IOException { - String getTrendReportMetaDataUrl = String.format(baseURL + "/%s/%s", TREND_REPORT_RESOURCE_NAME, trendReportId); - HttpGet getTrendReportMetaDataRequest = new HttpGet(getTrendReportMetaDataUrl); - HttpResponse response = executeRequest(getTrendReportMetaDataRequest); - String trendReportMetaData = IOUtils.toString(response.getEntity().getContent()); - return PcTrendReportMetaData.xmlToObject(trendReportMetaData); - } - - - public boolean updateTrendReport(String trendReportId, TrendReportRequest trendReportRequest) throws PcException, IOException { - - String updateTrendReportUrl = String.format(baseURL + "/%s/%s", TREND_REPORT_RESOURCE_NAME, trendReportId); - HttpPost updateTrendReportRequest = new HttpPost(updateTrendReportUrl); - updateTrendReportRequest.addHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_XML); - updateTrendReportRequest.setEntity(new StringEntity(trendReportRequest.objectToXML(), ContentType.APPLICATION_XML)); - executeRequest(updateTrendReportRequest); - return true; - } - - - - public InputStream getTrendingPDF(String trendReportId) throws IOException, PcException { - - String getTrendReportUrl = String.format(baseURL + "/%s/%s/%s", TREND_REPORT_RESOURCE_NAME, trendReportId,TREND_REPORT_RESOURCE_SUFFIX); - HttpGet getTrendReportRequest = new HttpGet(getTrendReportUrl); - executeRequest(getTrendReportRequest); - - HttpResponse response = executeRequest(getTrendReportRequest); - InputStream in = response.getEntity().getContent(); - - return in; - - } - - public PcRunEventLog getRunEventLog(int runId) throws PcException, ClientProtocolException, IOException { - String getRunEventLogUrl = String - .format(baseURL + "/%s/%s/%s", RUNS_RESOURCE_NAME, runId, EVENTLOG_RESOURCE_NAME); - HttpGet getRunEventLogRequest = new HttpGet(getRunEventLogUrl); - HttpResponse response = executeRequest(getRunEventLogRequest); - String runEventLog = IOUtils.toString(response.getEntity().getContent()); - return PcRunEventLog.xmlToObject(runEventLog); - } - - public boolean logout() throws PcException, ClientProtocolException, IOException { - HttpGet logoutRequest = new HttpGet(String.format(AUTHENTICATION_LOGOUT_URL, pcServer)); - executeRequest(logoutRequest); - return true; - } - - protected HttpResponse executeRequest(HttpRequestBase request) throws PcException, IOException { - HttpResponse response = client.execute(request,context); - if (!isOk(response)){ - String message; - try { - String content = IOUtils.toString(response.getEntity().getContent()); - PcErrorResponse exception = PcErrorResponse.xmlToObject(content); - message = String.format("%s Error code: %s", exception.ExceptionMessage, exception.ErrorCode); - } catch (Exception ex) { - message = response.getStatusLine().toString(); - } - throw new PcException(message); - } - return response; - } - - public static boolean isOk (HttpResponse response) { - return validStatusCodes.contains(response.getStatusLine().getStatusCode()); - } - - protected String getBaseURL() { - return baseURL; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLog.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLog.java deleted file mode 100644 index 05386ef6c2..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLog.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import java.util.ArrayList; - -import com.thoughtworks.xstream.XStream; - -public class PcRunEventLog { - - private ArrayList RecordsList; - - public PcRunEventLog() { - RecordsList = new ArrayList(); - } - - public static PcRunEventLog xmlToObject(String xml) - { - XStream xstream = new XStream(); - xstream.alias("Record" , PcRunEventLogRecord.class); - xstream.alias("EventLog" , PcRunEventLog.class); - xstream.addImplicitCollection(PcRunEventLog.class, "RecordsList"); - xstream.setClassLoader(PcRunEventLog.class.getClassLoader()); - return (PcRunEventLog)xstream.fromXML(xml); - } - - public ArrayList getRecordsList() { - return RecordsList; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLogRecord.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLogRecord.java deleted file mode 100644 index fa23ff1f74..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunEventLogRecord.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.thoughtworks.xstream.XStream; - -public class PcRunEventLogRecord { - - private int ID; - - private String Type; - - private String Time; - - private String Name; - - private String Description; - - private String Responsible; - - public static PcRunEventLogRecord xmlToObject(String xml) - { - XStream xstream = new XStream(); - xstream.alias("Record" , PcRunEventLogRecord.class); - return (PcRunEventLogRecord)xstream.fromXML(xml); - } - - public int getID() { - return ID; - } - - public String getType() { - return Type; - } - - public String getTime() { - return Time; - } - - public String getName() { - return Name; - } - - public String getDescription() { - return Description; - } - - public String getResponsible() { - return Responsible; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunRequest.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunRequest.java deleted file mode 100644 index 04f40f51ee..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunRequest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.thoughtworks.xstream.XStream; -import com.hp.application.automation.tools.model.TimeslotDuration; - -public class PcRunRequest { - - @SuppressWarnings("unused") - private String xmlns = PcRestProxy.PC_API_XMLNS; - - private int TestID; - - private int TestInstanceID; - - private int TimeslotID; - - private TimeslotDuration TimeslotDuration; - - private String PostRunAction; - - private boolean VudsMode; - - - public PcRunRequest( - int testID, - int testInstanceID, - int timeslotID, - TimeslotDuration timeslotDuration, - String postRunAction, - boolean vudsMode) { - - TestID = testID; - TestInstanceID = testInstanceID; - TimeslotID = timeslotID; - TimeslotDuration = timeslotDuration; - PostRunAction = postRunAction; - VudsMode = vudsMode; - } - - public PcRunRequest() {} - - public String objectToXML() { - XStream obj = new XStream(); - obj.alias("Run", PcRunRequest.class); - obj.alias("TimeslotDuration", TimeslotDuration.class); - obj.useAttributeFor(PcRunRequest.class, "xmlns"); - return obj.toXML(this); - } - - public int getTestID() { - return TestID; - } - - public int getTestInstanceID() { - return TestInstanceID; - } - - public int getTimeslotID() { - return TimeslotID; - } - - public TimeslotDuration getTimeslotDuration() { - return TimeslotDuration; - } - - public String getPostRunAction() { - return PostRunAction; - } - - public boolean isVudsMode() { - return VudsMode; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunResponse.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunResponse.java deleted file mode 100644 index 403f0a633c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.thoughtworks.xstream.XStream; - -public class PcRunResponse extends PcRunRequest { - - private int ID; - - private int Duration; - - private String RunState; - - private String RunSLAStatus; - - public static PcRunResponse xmlToObject(String xml) { - XStream xstream = new XStream(); - xstream.setClassLoader(PcRunResponse.class.getClassLoader()); - xstream.alias("Run", PcRunResponse.class); - return (PcRunResponse) xstream.fromXML(xml); - - } - - public int getID() { - return ID; - } - - public int getDuration() { - return Duration; - } - - public String getRunState() { - return RunState; - } - - public String getRunSLAStatus() { - return RunSLAStatus; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunResult.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunResult.java deleted file mode 100644 index d9682dd004..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunResult.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import com.thoughtworks.xstream.XStream; - -public class PcRunResult { - - private int ID; - - private String Name; - - private int RunID; - - private String Type; - - public static PcRunResult xmlToObject(String xml) - { - XStream xstream = new XStream(); - xstream.alias("RunResult" , PcRunResult.class); - return (PcRunResult)xstream.fromXML(xml); - } - - public int getID() { - return ID; - } - - public String getName() { - return Name; - } - - public int getRunID() { - return RunID; - } - - public String getType() { - return Type; - } - - -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcRunResults.java b/src/main/java/com/hp/application/automation/tools/pc/PcRunResults.java deleted file mode 100644 index 283aab73cc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcRunResults.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - -import java.util.ArrayList; -import com.thoughtworks.xstream.XStream; - -public class PcRunResults { - - private ArrayList ResultsList; - - public PcRunResults() { - ResultsList = new ArrayList(); - } - - public static PcRunResults xmlToObject(String xml) - { - XStream xstream = new XStream(); - xstream.alias("RunResult" , PcRunResult.class); - xstream.alias("RunResults" , PcRunResults.class); - xstream.addImplicitCollection(PcRunResults.class, "ResultsList"); - xstream.setClassLoader(PcRunResults.class.getClassLoader()); - return (PcRunResults)xstream.fromXML(xml); - } - - public ArrayList getResultsList() { - return ResultsList; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/pc/PcTrendReportMetaData.java b/src/main/java/com/hp/application/automation/tools/pc/PcTrendReportMetaData.java deleted file mode 100644 index d0cdaf0174..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pc/PcTrendReportMetaData.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pc; - - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; -import javax.xml.parsers.*; -import org.xml.sax.*; -import org.w3c.dom.*; - -public class PcTrendReportMetaData { - private static ArrayList Results; - static Document dom; - static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - -// public PcTrendReportMetaData() { -// Results = new ArrayList(); -// } - - public static ArrayList xmlToObject(String xml) - { - Results = new ArrayList(); - try { - DocumentBuilder db = dbf.newDocumentBuilder(); - dom = db.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-8")))); - Element doc = dom.getDocumentElement(); - NodeList nListTrendedRun = doc.getElementsByTagName("TrendedRun"); - - for (int i=0;i extends AbstractStepDescriptorImpl { - - final protected T builderDescriptor; - final private String functionName; - - protected AbstractSvStepDescriptor(Class executionType, String functionName, T builderDescriptor) { - super(executionType); - this.functionName = functionName; - this.builderDescriptor = builderDescriptor; - } - - @Override - public String getFunctionName() { - return functionName; - } - - @Nonnull - @Override - public String getDisplayName() { - return builderDescriptor.getDisplayName(); - } - - @Override - public String getConfigPage() { - return builderDescriptor.getConfigPage(); - } - - public SvServerSettingsModel[] getServers() { - return builderDescriptor.getServers(); - } - - @SuppressWarnings("unused") - public ListBoxModel doFillServerNameItems() { - return builderDescriptor.doFillServerNameItems(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java deleted file mode 100644 index 66d81eed45..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.ResultsPublisherModel; -import com.hp.application.automation.tools.results.RunResultRecorder; -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import hudson.Extension; -import hudson.util.FormValidation; -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.Symbol; -import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; -import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.QueryParameter; - -import javax.annotation.Nonnull; -import java.util.List; -import java.util.Objects; - -/** - * Load runner pipeline step - */ -public class LoadRunnerTestStep extends AbstractStepImpl { - - private final RunFromFileBuilder runFromFileBuilder; - private final RunResultRecorder runResultRecorder; - - /** - * Instantiates a new Lr scenario load step. - * - * @param testPaths the test paths - * @param archiveTestResultsMode the type of archiving the user wants. - */ - @DataBoundConstructor - public LoadRunnerTestStep(String testPaths, String archiveTestResultsMode) { - this.runFromFileBuilder = new RunFromFileBuilder(testPaths); - this.runResultRecorder = new RunResultRecorder(archiveTestResultsMode); - } - - /** - * Gets archive run test results mode. - * - * @return the archive run test results mode - */ - public String getArchiveTestResultsMode() { - return runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); - } - - /** - * Gets controller polling interval. - * - * @return the controller polling interval - */ - public String getControllerPollingInterval() { - return runFromFileBuilder.getRunFromFileModel().getControllerPollingInterval(); - } - - /** - * Sets controller polling interval. - * - * @param controllerPollingInterval the controller polling interval - */ - @DataBoundSetter - public void setControllerPollingInterval(String controllerPollingInterval) { - runFromFileBuilder.setControllerPollingInterval(controllerPollingInterval); - } - - /** - * Gets fs timeout. - * - * @return the fs timeout - */ - public String getFsTimeout() { - return runFromFileBuilder.getRunFromFileModel().getFsTimeout(); - } - - /** - * Sets fs timeout. - * - * @param fsTimeout the fs timeout - */ - @DataBoundSetter - public void setFsTimeout(String fsTimeout) { - runFromFileBuilder.setFsTimeout(fsTimeout); - } - - /** - * Gets per scenario time out. - * - * @return the per scenario time out - */ - public String getPerScenarioTimeOut() { - return runFromFileBuilder.getRunFromFileModel().getPerScenarioTimeOut(); - } - - /** - * Sets per scenario time out. - * - * @param perScenarioTimeOut the per scenario time out - */ - @DataBoundSetter - public void setPerScenarioTimeOut(String perScenarioTimeOut) { - runFromFileBuilder.setPerScenarioTimeOut(perScenarioTimeOut); - } - - /** - * Gets test paths. - * - * @return the test paths - */ - public String getTestPaths() { - return runFromFileBuilder.getRunFromFileModel().getFsTests(); - } - - /** - * Gets ignore error strings. - * - * @return the ignore error strings - */ - public String getIgnoreErrorStrings() { - return runFromFileBuilder.getRunFromFileModel().getIgnoreErrorStrings(); - } - - /** - * Sets ignore error strings. - * - * @param ignoreErrorStrings the ignore error strings - */ - @DataBoundSetter - public void setIgnoreErrorStrings(String ignoreErrorStrings) { - runFromFileBuilder.setIgnoreErrorStrings(ignoreErrorStrings); - } - - /** - * Gets run from file builder. - * - * @return the run from file builder - */ - public RunFromFileBuilder getRunFromFileBuilder() { - return runFromFileBuilder; - } - - public RunResultRecorder getRunResultRecorder() { - return runResultRecorder; - } - - /** - * The type Descriptor. - */ - @Extension - @Symbol("loadRunnerTest") - public static class DescriptorImpl extends AbstractStepDescriptorImpl { - /** - * Instantiates a new Descriptor. - */ - public DescriptorImpl() { - super(LrScenarioLoadStepExecution.class); - } - - @Override - public String getFunctionName() { - return "loadRunnerTest"; - } - - @Nonnull - @Override - public String getDisplayName() { - return "Run LoadRunner performance scenario tests"; - } - - /** - * Gets report archive modes. - * - * @return the report archive modes - */ - public List getReportArchiveModes() { - - return ResultsPublisherModel.archiveModes; - } - - /** - * Do check fs tests form validation. - * - * @param value the value - * @return the form validation - */ - @SuppressWarnings("squid:S1172") - public FormValidation doCheckFsTests(@QueryParameter String value) { - return FormValidation.ok(); - } - - /** - * Do check ignore error strings form validation. - * - * @param value the value - * @return the form validation - */ - @SuppressWarnings("squid:S1172") - public FormValidation doCheckIgnoreErrorStrings(@QueryParameter String value) { - - return FormValidation.ok(); - } - - /** - * Do check fs timeout form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckFsTimeout(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - String val1 = value.trim(); - if (val1.length() > 0 && val1.charAt(0) == '-') { - val1 = val1.substring(1); - } - - if (!StringUtils.isNumeric(val1) && !Objects.equals(val1, "")) { - return FormValidation.error("Timeout name must be a number"); - } - return FormValidation.ok(); - } - - /** - * Do check controller polling interval form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckControllerPollingInterval(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - if (!StringUtils.isNumeric(value)) { - return FormValidation.error("Controller Polling Interval must be a number"); - } - - return FormValidation.ok(); - } - - /** - * Do check per scenario time out form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckPerScenarioTimeOut(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - if (!StringUtils.isNumeric(value)) { - return FormValidation.error("Per Scenario Timeout must be a number"); - } - - return FormValidation.ok(); - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java deleted file mode 100644 index ebfbfcce15..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Result; -import hudson.model.Run; -import hudson.model.TaskListener; -import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; -import org.jenkinsci.plugins.workflow.steps.StepContextParameter; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.HashMap; -import java.util.logging.Logger; - - -/** - * The Load runner pipeline step execution. - */ -public class LrScenarioLoadStepExecution extends AbstractSynchronousNonBlockingStepExecution { - - /** - * Logger. - */ - private static final Logger logger = Logger - .getLogger(LrScenarioLoadStepExecution.class.getName()); - - private static final long serialVersionUID = 1L; - @Inject - @SuppressWarnings("squid:S3306") - private transient LoadRunnerTestStep step; - @StepContextParameter - private transient TaskListener listener; - @StepContextParameter - private transient FilePath ws; - @StepContextParameter - private transient Run build; - @StepContextParameter - private transient Launcher launcher; - - public LrScenarioLoadStepExecution() { - //no need for actual construction - } - - @Override - protected Void run() throws InterruptedException { - listener.getLogger().println("Running LoadRunner Scenario step"); - try { - step.getRunFromFileBuilder().perform(build, ws, launcher, listener); - } catch (IOException e) { - listener.fatalError("LoadRunnner scenario run stage encountered an IOException " + e); - build.setResult(Result.FAILURE); - return null; - } - HashMap resultFilename = new HashMap(0); - resultFilename.put(RunFromFileBuilder.class.getName(), step.getRunFromFileBuilder().getRunResultsFileName()); - - try { - step.getRunResultRecorder().pipelinePerform(build, ws, launcher, listener, resultFilename); - } catch (IOException e) { - listener.fatalError("LoadRunnner scenario run result recorder stage encountered an IOException " + e); - build.setResult(Result.FAILURE); - return null; - } - - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java deleted file mode 100644 index a95252d393..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.results.RunResultRecorder; -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import com.hp.application.automation.tools.run.SseBuilder; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; -import org.jenkinsci.plugins.workflow.steps.StepContextParameter; -import org.apache.commons.lang.StringUtils; -import javax.inject.Inject; -import java.util.HashMap; - -/** - * Copyright (c) 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. - * - * Execution for SseBuildAndPublish - * Created by Roy Lu on 10/20/2016. - */ -public class SseBuilderPublishResultStepExecution extends AbstractSynchronousNonBlockingStepExecution { - - private static final long serialVersionUID = 1L; - - @Inject - private transient SseBuildAndPublishStep step; - - @StepContextParameter - private transient TaskListener listener; - - @StepContextParameter - private transient FilePath ws; - - @StepContextParameter - private transient Run build; - - @StepContextParameter - private transient Launcher launcher; - - @Override - protected Void run() throws Exception { - listener.getLogger().println("Execute HP tests using HP ALM Lab Management"); - - SseBuilder sseBuilder = step.getSseBuilder(); - RunResultRecorder runResultRecorder = step.getRunResultRecorder(); - - String archiveTestResultsMode = runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); - - sseBuilder.perform(build, ws, launcher, listener); - - if (StringUtils.isNotBlank(archiveTestResultsMode)) { - listener.getLogger().println("Publish HP tests result"); - - HashMap resultFilename = new HashMap(0); - resultFilename.put(RunFromFileBuilder.class.getName(), sseBuilder.getRunResultsFileName()); - - runResultRecorder.pipelinePerform(build, ws, launcher, listener, resultFilename); - } - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvChangeModeStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvChangeModeStep.java deleted file mode 100644 index 83b924cefe..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvChangeModeStep.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.model.SvDataModelSelection; -import com.hp.application.automation.tools.model.SvPerformanceModelSelection; -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.application.automation.tools.run.SvChangeModeBuilder; -import com.hp.sv.jsvconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; -import hudson.Extension; -import hudson.util.FormValidation; -import hudson.util.ListBoxModel; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvChangeModeStep extends AbstractSvStep { - private final ServiceRuntimeConfiguration.RuntimeMode mode; - private final SvDataModelSelection dataModel; - private final SvPerformanceModelSelection performanceModel; - private final SvServiceSelectionModel serviceSelection; - - @DataBoundConstructor - public SvChangeModeStep(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, - SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { - super(serverName, force); - this.mode = mode; - this.dataModel = dataModel; - this.performanceModel = performanceModel; - this.serviceSelection = serviceSelection; - } - - public ServiceRuntimeConfiguration.RuntimeMode getMode() { - return mode; - } - - public SvDataModelSelection getDataModel() { - return dataModel; - } - - public SvPerformanceModelSelection getPerformanceModel() { - return performanceModel; - } - - public SvServiceSelectionModel getServiceSelection() { - return serviceSelection; - } - - @Override - protected SimpleBuildStep getBuilder() { - return new SvChangeModeBuilder(serverName, force, mode, dataModel, performanceModel, serviceSelection); - } - - @Extension - public static class DescriptorImpl extends AbstractSvStepDescriptor { - public DescriptorImpl() { - super(SvExecution.class, "svChangeModeStep", new SvChangeModeBuilder.DescriptorImpl()); - } - - @SuppressWarnings("unused") - public FormValidation doCheckDataModel(@QueryParameter String value, @QueryParameter("mode") String mode, - @QueryParameter("serviceSelectionKind") String kind) { - return builderDescriptor.doCheckDataModel(value, mode, kind); - } - - @SuppressWarnings("unused") - public ListBoxModel doFillModeItems() { - return builderDescriptor.doFillModeItems(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvDeployStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvDeployStep.java deleted file mode 100644 index c9ea3e2839..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvDeployStep.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.run.SvDeployBuilder; -import hudson.Extension; -import hudson.util.FormValidation; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvDeployStep extends AbstractSvStep { - private final String service; - private final String projectPath; - private final String projectPassword; - private final boolean firstAgentFallback; - - @DataBoundConstructor - public SvDeployStep(String serverName, boolean force, String service, String projectPath, String projectPassword, boolean firstAgentFallback) { - super(serverName, force); - this.service = service; - this.projectPath = projectPath; - this.projectPassword = projectPassword; - this.firstAgentFallback = firstAgentFallback; - } - - public String getService() { - return service; - } - - public String getProjectPath() { - return projectPath; - } - - public String getProjectPassword() { - return projectPassword; - } - - public boolean isFirstAgentFallback() { - return firstAgentFallback; - } - - @Override - protected SimpleBuildStep getBuilder() { - return new SvDeployBuilder(serverName, force, service, projectPath, projectPassword, firstAgentFallback); - } - - @Extension - public static class DescriptorImpl extends AbstractSvStepDescriptor { - public DescriptorImpl() { - super(SvExecution.class, "svDeployStep", new SvDeployBuilder.DescriptorImpl()); - } - - @SuppressWarnings("unused") - public FormValidation doCheckProjectPath(@QueryParameter String projectPath) { - return builderDescriptor.doCheckProjectPath(projectPath); - } - - @SuppressWarnings("unused") - public FormValidation doCheckService(@QueryParameter String service) { - return builderDescriptor.doCheckService(service); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExecution.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExecution.java deleted file mode 100644 index 7b38a4f0e5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExecution.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import javax.inject.Inject; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; -import org.jenkinsci.plugins.workflow.steps.StepContextParameter; - -public class SvExecution extends AbstractSynchronousNonBlockingStepExecution { - @SuppressWarnings("CdiInjectionPointsInspection") - @Inject - private transient AbstractSvStep step; - @StepContextParameter - private transient TaskListener listener; - @StepContextParameter - private transient FilePath ws; - @StepContextParameter - private transient Run build; - @StepContextParameter - private transient Launcher launcher; - - @Override - protected Void run() throws Exception { - step.getBuilder().perform(build, ws, launcher, listener); - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExportStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExportStep.java deleted file mode 100644 index 1c19e88ebb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvExportStep.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.application.automation.tools.run.SvExportBuilder; -import hudson.Extension; -import hudson.util.FormValidation; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvExportStep extends AbstractSvStep { - private final String targetDirectory; - private final boolean cleanTargetDirectory; - private final SvServiceSelectionModel serviceSelection; - private final boolean switchToStandByFirst; - - @DataBoundConstructor - public SvExportStep(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, - SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst) { - super(serverName, force); - this.targetDirectory = targetDirectory; - this.cleanTargetDirectory = cleanTargetDirectory; - this.serviceSelection = serviceSelection; - this.switchToStandByFirst = switchToStandByFirst; - } - - public String getTargetDirectory() { - return targetDirectory; - } - - public boolean isCleanTargetDirectory() { - return cleanTargetDirectory; - } - - public SvServiceSelectionModel getServiceSelection() { - return serviceSelection; - } - - public boolean isSwitchToStandByFirst() { - return switchToStandByFirst; - } - - @Override - protected SimpleBuildStep getBuilder() { - return new SvExportBuilder(serverName, force, targetDirectory, cleanTargetDirectory, serviceSelection, switchToStandByFirst); - } - - @Extension - public static class DescriptorImpl extends AbstractSvStepDescriptor { - public DescriptorImpl() { - super(SvExecution.class, "svExportStep", new SvExportBuilder.DescriptorImpl()); - } - - @SuppressWarnings("unused") - public FormValidation doCheckTargetDirectory(@QueryParameter String targetDirectory) { - return builderDescriptor.doCheckTargetDirectory(targetDirectory); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvUndeployStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvUndeployStep.java deleted file mode 100644 index 560a89481d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SvUndeployStep.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.application.automation.tools.run.SvUndeployBuilder; -import hudson.Extension; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.DataBoundConstructor; - -public class SvUndeployStep extends AbstractSvStep { - private final boolean continueIfNotDeployed; - private final SvServiceSelectionModel serviceSelection; - - @DataBoundConstructor - public SvUndeployStep(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { - super(serverName, force); - this.continueIfNotDeployed = continueIfNotDeployed; - this.serviceSelection = serviceSelection; - } - - @SuppressWarnings("unused") - public boolean isContinueIfNotDeployed() { - return continueIfNotDeployed; - } - - public SvServiceSelectionModel getServiceSelection() { - return serviceSelection; - } - - @Override - protected SimpleBuildStep getBuilder() { - return new SvUndeployBuilder(serverName, continueIfNotDeployed, force, serviceSelection); - } - - @Extension - public static class DescriptorImpl extends AbstractSvStepDescriptor { - public DescriptorImpl() { - super(SvExecution.class, "svUndeployStep", new SvUndeployBuilder.DescriptorImpl()); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java deleted file mode 100644 index d0f5a2f476..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.ResultsPublisherModel; -import com.hp.application.automation.tools.results.RunResultRecorder; -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import hudson.Extension; -import hudson.util.FormValidation; -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.Symbol; -import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; -import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.QueryParameter; - -import javax.annotation.Nonnull; -import java.util.List; -import java.util.Objects; - -/** - * UFT pipeline step - */ -public class UftScenarioLoadStep extends AbstractStepImpl { - - private final RunFromFileBuilder runFromFileBuilder; - private final RunResultRecorder runResultRecorder; - - /** - * Instantiates a new UFT scenario load step. - * - * @param testPaths the test paths - * @param archiveTestResultsMode the type of archiving the user wants. - */ - @DataBoundConstructor - public UftScenarioLoadStep(String testPaths, String archiveTestResultsMode) { - this.runFromFileBuilder = new RunFromFileBuilder(testPaths); - this.runResultRecorder = new RunResultRecorder(archiveTestResultsMode); - } - - /** - * Gets archive test result mode. - * - * @return the archive run test results mode - */ - public String getArchiveTestResultsMode() { - return runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); - } - - /** - * Gets fsTimeout - * - * @return fsTimeout value - */ - public String getFsTimeout() { - return runFromFileBuilder.getRunFromFileModel().getFsTimeout(); - } - - /** - * Sets fsTimeout value - * - * @param fsTimeout the fsTimeout value - */ - @DataBoundSetter - public void setFsTimeout(String fsTimeout) { - runFromFileBuilder.setFsTimeout(fsTimeout); - } - - /** - * Gets test paths. - * - * @return the test paths - */ - public String getTestPaths() { - return runFromFileBuilder.getRunFromFileModel().getFsTests(); - } - - /** - * Gets run from file builder. - * - * @return the run from file builder - */ - public RunFromFileBuilder getRunFromFileBuilder() { - return runFromFileBuilder; - } - - /** - * Gets run result builder - * - * @return the run result builder - */ - public RunResultRecorder getRunResultRecorder() { - return runResultRecorder; - } - - /** - * The type Descriptor. - */ - @Extension - @Symbol("UftScenarioLoad") - public static class DescriptorImpl extends AbstractStepDescriptorImpl { - - /** - * Instantiates a new Descriptor. - */ - public DescriptorImpl() { - super(UftScenarioLoadStepExecution.class); - } - - @Override - public String getFunctionName() { - return "uftScenarioLoad"; - } - - @Nonnull - @Override - public String getDisplayName() { - return "Run UFT scenario"; - } - - /** - * Gets report archive modes. - * - * @return the report archive modes - */ - public List getReportArchiveModes() { - - return ResultsPublisherModel.archiveModes; - } - - /** - * Do check test paths validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckTestPaths(@QueryParameter String value) { - - if (StringUtils.isBlank(value)) { - return FormValidation.error("Test path must be set"); - } - - return FormValidation.ok(); - } - - /** - * Do check fs tests form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckFsTests(@QueryParameter String value) { - - if (StringUtils.isBlank(value)) { - return FormValidation.error("Test path must be set"); - } - - return FormValidation.ok(); - } - - /** - * Do check fs timeout validation - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckFsTimeout(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - String val1 = value.trim(); - if (val1.length() > 0 && val1.charAt(0) == '-') { - val1 = val1.substring(1); - } - - if (!StringUtils.isNumeric(val1) && !Objects.equals(val1, "")) { - return FormValidation.error("Timeout name must be a number"); - } - - return FormValidation.ok(); - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java b/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java deleted file mode 100644 index 060b5ce8f9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.pipelineSteps; - -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; -import org.jenkinsci.plugins.workflow.steps.StepContextParameter; - -import javax.inject.Inject; -import java.util.HashMap; - - -/** - * The UFT pipeline step execution. - */ -public class UftScenarioLoadStepExecution extends AbstractSynchronousNonBlockingStepExecution { - - private static final long serialVersionUID = 1L; - @Inject - - private transient UftScenarioLoadStep step; - - @StepContextParameter - private transient TaskListener listener; - - @StepContextParameter - private transient FilePath ws; - - @StepContextParameter - private transient Run build; - - @StepContextParameter - private transient Launcher launcher; - - public UftScenarioLoadStepExecution() { - //no need for actual construction - } - - @Override - protected Void run() throws Exception { - listener.getLogger().println("Running UFT Scenario step"); - step.getRunFromFileBuilder().perform(build, ws, launcher, listener); - - HashMap resultFilename = new HashMap(0); - resultFilename.put(RunFromFileBuilder.class.getName(), step.getRunFromFileBuilder().getRunResultsFileName()); - step.getRunResultRecorder().pipelinePerform(build, ws, launcher, listener, resultFilename); - - return null; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/rest/RESTConstants.java b/src/main/java/com/hp/application/automation/tools/rest/RESTConstants.java deleted file mode 100644 index 66ef26bcff..0000000000 --- a/src/main/java/com/hp/application/automation/tools/rest/RESTConstants.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hp.application.automation.tools.rest; - -/** - * - * @author Amir Zahavi - * - */ -public interface RESTConstants { - - // HttpHeaders - String PtaL = "PtAL"; - String PvaL = "PvAL"; - String CONTENT_TYPE = "Content-Type"; - String SET_COOKIE = "Set-Cookie"; - String ACCEPT = "Accept"; - String AUTHORIZATION = "Authorization"; - String APP_XML = "application/xml"; - String TEXT_PLAIN = "text/plain"; - String APP_XML_BULK = "application/xml;type=collection"; - - String REST_PROTOCOL = "rest"; - - String GET = "GET"; - String POST = "POST"; - String PUT = "PUT"; - String COOKIE = "Cookie"; -} diff --git a/src/main/java/com/hp/application/automation/tools/rest/RestClient.java b/src/main/java/com/hp/application/automation/tools/rest/RestClient.java deleted file mode 100644 index 6e59ec2fa6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/rest/RestClient.java +++ /dev/null @@ -1,480 +0,0 @@ -package com.hp.application.automation.tools.rest; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Authenticator; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.commons.lang.StringUtils; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.HttpRequestDecorator; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class RestClient implements Client { - - private final String _serverUrl; - protected Map _cookies = new HashMap(); - private final String _restPrefix; - private final String _webuiPrefix; - private final String _username; - private ProxyInfo proxyInfo; - - /** - * Configure SSL context for the client. - */ - static { - // First create a trust manager that won't care. - X509TrustManager trustManager = new X509TrustManager() { - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - // Don't do anything. - } - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - // Don't do anything. - } - @Override - public X509Certificate[] getAcceptedIssuers() { - // Don't do anything. - return null; - } - - }; - // Now put the trust manager into an SSLContext. - SSLContext sslcontext; - try { - sslcontext = SSLContext.getInstance("SSL"); - sslcontext.init(null, new TrustManager[] { trustManager }, null); - } catch (KeyManagementException | NoSuchAlgorithmException e) { - throw new SSEException(e); - } - - HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory()); - - //Ignore hostname verify - HttpsURLConnection.setDefaultHostnameVerifier( - new HostnameVerifier(){ - public boolean verify(String hostname, SSLSession sslSession) { - return true; - } - } - ); - } - - public RestClient(String url, String domain, String project, String username) { - - if (!url.endsWith("/")) { - url = String.format("%s/", url); - } - _serverUrl = url; - _username = username; - _restPrefix = - getPrefixUrl( - "rest", - String.format("domains/%s", domain), - String.format("projects/%s", project)); - _webuiPrefix = getPrefixUrl("webui/alm", domain, project); - } - - /** - * Constructor for setting rest client properties including proxy info. - */ - public RestClient(String url, String domain, String project, String username, ProxyInfo proxyInfo) { - - if (!url.endsWith("/")) { - url = String.format("%s/", url); - } - _serverUrl = url; - _username = username; - this.proxyInfo = proxyInfo; - _restPrefix = - getPrefixUrl( - "rest", - String.format("domains/%s", domain), - String.format("projects/%s", project)); - _webuiPrefix = getPrefixUrl("webui/alm", domain, project); - } - - @Override - public String build(String suffix) { - - return String.format("%1$s%2$s", _serverUrl, suffix); - } - - @Override - public String buildRestRequest(String suffix) { - - return String.format("%1$s/%2$s", _restPrefix, suffix); - } - - @Override - public String buildWebUIRequest(String suffix) { - - return String.format("%1$s/%2$s", _webuiPrefix, suffix); - } - - @Override - public Response httpGet( - String url, - String queryString, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - Response ret = null; - try { - ret = doHttp(RESTConstants.GET, url, queryString, null, headers, resourceAccessLevel); - } catch (Exception cause) { - throw new SSEException(cause); - } - - return ret; - } - - @Override - public Response httpPost( - String url, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - Response ret = null; - try { - ret = doHttp(RESTConstants.POST, url, null, data, headers, resourceAccessLevel); - } catch (Exception cause) { - throw new SSEException(cause); - } - - return ret; - } - - @Override - public Response httpPut( - String url, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - Response ret = null; - try { - ret = doHttp(RESTConstants.PUT, url, null, data, headers, resourceAccessLevel); - } catch (Exception cause) { - throw new SSEException(cause); - } - - return ret; - } - - @Override - public String getServerUrl() { - - return _serverUrl; - } - - private String getPrefixUrl(String protocol, String domain, String project) { - - return String.format("%s%s/%s/%s", _serverUrl, protocol, domain, project); - } - - /** - * @param type - * http operation: get post put delete - * @param url - * to work on - * @param queryString - * @param data - * to write, if a writable operation - * @param headers - * to use in the request - * @param cookies - * to use in the request and update from the response - * @return http response - */ - private Response doHttp( - String type, - String url, - String queryString, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - Response ret; - if ((queryString != null) && !queryString.isEmpty()) { - url += "?" + queryString; - } - try { - HttpURLConnection connection = (HttpURLConnection) openConnection(proxyInfo, url); - - connection.setRequestMethod(type); - - Map decoratedHeaders = new HashMap(); - if (headers != null) { - decoratedHeaders.putAll(headers); - } - - HttpRequestDecorator.decorateHeaderWithUserInfo( - decoratedHeaders, - getUsername(), - resourceAccessLevel); - - prepareHttpRequest(connection, decoratedHeaders, data); - connection.connect(); - ret = retrieveHtmlResponse(connection); - updateCookies(ret); - } catch (Exception cause) { - throw new SSEException(cause); - } - - return ret; - } - - /** - * @param connnection - * connection to set the headers and bytes in - * @param headers - * to use in the request, such as content-type - * @param bytes - * the actual data to post in the connection. - */ - private void prepareHttpRequest( - HttpURLConnection connnection, - Map headers, - byte[] bytes) { - - // set all cookies for request - connnection.setRequestProperty(RESTConstants.COOKIE, getCookies()); - - setConnectionHeaders(connnection, headers); - - setConnectionData(connnection, bytes); - } - - private void setConnectionData(HttpURLConnection connnection, byte[] bytes) { - - if (bytes != null && bytes.length > 0) { - connnection.setDoOutput(true); - try { - OutputStream out = connnection.getOutputStream(); - out.write(bytes); - out.flush(); - out.close(); - } catch (Exception cause) { - throw new SSEException(cause); - } - } - } - - private void setConnectionHeaders(HttpURLConnection connnection, Map headers) { - - if (headers != null) { - Iterator> headersIterator = headers.entrySet().iterator(); - while (headersIterator.hasNext()) { - Entry header = headersIterator.next(); - connnection.setRequestProperty(header.getKey(), header.getValue()); - } - } - } - - /** - * @param connection - * that is already connected to its url with an http request, and that should contain - * a response for us to retrieve - * @return a response from the server to the previously submitted http request - */ - private Response retrieveHtmlResponse(HttpURLConnection connection) { - - Response ret = new Response(); - - try { - ret.setStatusCode(connection.getResponseCode()); - ret.setHeaders(connection.getHeaderFields()); - } catch (Exception cause) { - throw new SSEException(cause); - } - - InputStream inputStream; - // select the source of the input bytes, first try 'regular' input - try { - inputStream = connection.getInputStream(); - } - // if the connection to the server somehow failed, for example 404 or 500, - // con.getInputStream() will throw an exception, which we'll keep. - // we'll also store the body of the exception page, in the response data. */ - catch (Exception e) { - inputStream = connection.getErrorStream(); - ret.setFailure(e); - } - - // this takes data from the previously set stream (error or input) - // and stores it in a byte[] inside the response - ByteArrayOutputStream container = new ByteArrayOutputStream(); - byte[] buf = new byte[1024]; - int read; - try { - while ((read = inputStream.read(buf, 0, 1024)) > 0) { - container.write(buf, 0, read); - } - ret.setData(container.toByteArray()); - } catch (Exception ex) { - throw new SSEException(ex); - } - - return ret; - } - - private void updateCookies(Response response) { - - Iterable newCookies = response.getHeaders().get(RESTConstants.SET_COOKIE); - if (newCookies != null) { - for (String cookie : newCookies) { - int equalIndex = cookie.indexOf('='); - int semicolonIndex = cookie.indexOf(';'); - String cookieKey = cookie.substring(0, equalIndex); - String cookieValue = cookie.substring(equalIndex + 1, semicolonIndex); - _cookies.put(cookieKey, cookieValue); - } - } - } - - private String getCookies() { - - StringBuilder ret = new StringBuilder(); - if (!_cookies.isEmpty()) { - for (Entry entry : _cookies.entrySet()) { - ret.append(entry.getKey()).append("=").append(entry.getValue()).append(";"); - } - } - - return ret.toString(); - } - - @Override - public String getUsername() { - - return _username; - } - - public static URLConnection openConnection(final ProxyInfo proxyInfo, String urlString) throws IOException { - Proxy proxy = null; - URL url = new URL(urlString); - - if (proxyInfo != null && StringUtils.isNotBlank(proxyInfo._host) && StringUtils.isNotBlank(proxyInfo._port)) { - int port = Integer.parseInt(proxyInfo._port.trim()); - proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyInfo._host, port)); - } - - if (proxy != null && StringUtils.isNotBlank(proxyInfo._userName) && StringUtils.isNotBlank(proxyInfo._password)) { - Authenticator authenticator = new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(proxyInfo._userName, proxyInfo._password.toCharArray()); //To change body of overridden methods use File | Settings | File Templates. - } - }; - Authenticator.setDefault(authenticator); - } - - if (proxy == null) { - return url.openConnection(); - } - - - return url.openConnection(proxy); - } - - /** - * Set proxy configuration. - * @param host - * @param port - * @param userName - * @param password - * @return proxyinfo instance - */ - public static ProxyInfo setProxyCfg(String host, String port, String userName, String password) { - return new ProxyInfo(host, port, userName, password); - } - - public static ProxyInfo setProxyCfg(String host, String port) { - - ProxyInfo proxyInfo = new ProxyInfo(); - - proxyInfo._host = host; - proxyInfo._port = port; - - return proxyInfo; - } - - public static ProxyInfo setProxyCfg(String address, String userName, String password) { - ProxyInfo proxyInfo = new ProxyInfo(); - - if (address != null) { - String host = address; - - if (address.endsWith("/")) { - int end = address.lastIndexOf('/'); - host = address.substring(0, end); - } - - int index = host.lastIndexOf(':'); - if (index > 0) { - proxyInfo._host = host.substring(0, index); - proxyInfo._port = host.substring(index + 1, host.length()); - } else { - proxyInfo._host = host; - proxyInfo._port = "80"; - } - } - proxyInfo._userName = userName; - proxyInfo._password = password; - - return proxyInfo; - } - - static class ProxyInfo { - String _host; - String _port; - String _userName; - String _password; - - public ProxyInfo() { - //Keep the non parameter constructor. - } - - public ProxyInfo(String host, String port, String userName, String password) { - _host = host; - _port = port; - _userName = userName; - _password = password; - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/DetailReport.java b/src/main/java/com/hp/application/automation/tools/results/DetailReport.java deleted file mode 100644 index 690599fb0f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/DetailReport.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.hp.application.automation.tools.results; - -import hudson.model.DirectoryBrowserSupport; -import hudson.model.ModelObject; -import hudson.model.Run; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import java.io.IOException; - -public class DetailReport implements ModelObject { - - private String name = ""; - private String color = ""; - private String duration = ""; - private String pass = ""; - private String fail = ""; - private Run build = null; - private DirectoryBrowserSupport _directoryBrowserSupport = null; - - public DetailReport(Run build, String name, DirectoryBrowserSupport directoryBrowserSupport) { - this.build = build; - this.name = name; - _directoryBrowserSupport = directoryBrowserSupport; - } - - @Override - public String getDisplayName() { - return name; - } - - @SuppressWarnings("squid:S1452") - public Run getBuild() { - return build; - } - - public String getName() { - return name; - } - - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - - if (_directoryBrowserSupport != null) - _directoryBrowserSupport.generateResponse(req, rsp, this); - } - - public String getColor() { - return color; - } - - public void setColor(String value) { - color = value; - } - - public String getDuration() { - return duration; - } - - public void setDuration(String value) { - duration = value; - } - - public String getPass() { - return pass; - } - - public void setPass(String value) { - pass = value; - } - - public String getFail() { - return fail; - } - - public void setFail(String value) { - fail = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/HtmlBuildReportAction.java b/src/main/java/com/hp/application/automation/tools/results/HtmlBuildReportAction.java deleted file mode 100644 index 185c6806f9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/HtmlBuildReportAction.java +++ /dev/null @@ -1,126 +0,0 @@ - -/* - * MIT License - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results; - - -import hudson.model.Action; -import hudson.model.Run; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by betzalel on 28/06/2015. - */ - -public class HtmlBuildReportAction implements Action { - private static final String REPORTMETADATE_XML = "report_metadata.xml"; - private Run build; - private List reportMetaDataList = new ArrayList(); - - - //public HtmlBuildReportAction(AbstractBuild build, BuildListener listener, List reportMetaData) - //NOTE: if parameter has BuildListener, the build cannot be serilize normally. - - public HtmlBuildReportAction(Run build) throws IOException, SAXException, ParserConfigurationException { - this.build = build; - - File reportMetaData_XML = new File(build.getRootDir(), REPORTMETADATE_XML); - if (reportMetaData_XML.exists()) { - readReportFromXMLFile(reportMetaData_XML.getAbsolutePath(), this.reportMetaDataList); - } - - } - - @SuppressWarnings("squid:S1452") - public final Run getBuild() { - return build; - } - - protected File reportFile() { - return getBuildHtmlReport(this.build); - } - - private File getBuildHtmlReport(Run run) { - return new File(new File(new File(run.getRootDir(),"archive"), "UFTReport"), "index.html"); - } - - @Override - public String getDisplayName() { - return "UFT Report"; - } - - @Override - public String getUrlName() { - return "uft-report"; - } - - @Override - public String getIconFileName() { - return "/plugin/hp-application-automation-tools-plugin/icons/24x24/uft_report.png"; - } - - // other property of the report - public List getAllReports() { - return this.reportMetaDataList; - } - - - private void readReportFromXMLFile(String filename, List listReport) throws ParserConfigurationException, IOException, SAXException { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder; - Document doc; - builder = dbf.newDocumentBuilder(); - doc = builder.parse(filename); - - Element root = doc.getDocumentElement(); - NodeList reportList = root.getElementsByTagName("report"); - for (int i = 0; i < reportList.getLength(); i++) { - ReportMetaData reportmetadata = new ReportMetaData(); - Element report = (Element) reportList.item(i); - String disPlayName = report.getAttribute("disPlayName"); - String urlName = report.getAttribute("urlName"); - String resourceURL = report.getAttribute("resourceURL"); - String dateTime = report.getAttribute("dateTime"); - String status = report.getAttribute("status"); - String isHtmlreport = report.getAttribute("isHtmlreport"); - - reportmetadata.setDisPlayName(disPlayName); - reportmetadata.setUrlName(urlName); - reportmetadata.setResourceURL(resourceURL); - reportmetadata.setDateTime(dateTime); - reportmetadata.setStatus(status); - reportmetadata.setIsHtmlReport("true".equals(isHtmlreport)); - listReport.add(reportmetadata); - - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/PerformanceJobReportAction.java b/src/main/java/com/hp/application/automation/tools/results/PerformanceJobReportAction.java deleted file mode 100644 index d396c67dd6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/PerformanceJobReportAction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results; - -import com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; -import com.hp.application.automation.tools.results.projectparser.performance.LrJobResults; -import hudson.model.Action; -import hudson.model.InvisibleAction; -import hudson.model.Run; -import jenkins.tasks.SimpleBuildStep; -import net.minidev.json.JSONObject; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - - -/** - * Holds LoadRunner infomation on a specific Job Run / Build - */ -public class PerformanceJobReportAction extends InvisibleAction implements SimpleBuildStep.LastBuildAction { - - private Run build; - private JSONObject jobDataSet; - private LrJobResults _resultFiles; - - /** - * Instantiates a new Performance job report action. - * - * @param build the build - * @param resultFiles the result dataset - */ - public PerformanceJobReportAction(Run build, LrJobResults resultFiles) { - this.build = build; - this._resultFiles = resultFiles; - } - - /** - * Merge results of several runs - espcially useful in pipeline jobs with multiple LR steps - * - * @param resultFiles the result files - */ - public void mergeResults(LrJobResults resultFiles) - { - for(JobLrScenarioResult scenarioResult : resultFiles.getLrScenarioResults().values()) - { - this._resultFiles.addScenario(scenarioResult); - } - } - - /** - * Gets lr result build dataset. - * - * @return the lr result build dataset - */ - public LrJobResults getLrResultBuildDataset() { - return _resultFiles; - } - - /** - * Gets json data. - * - * @return the json data - */ - public JSONObject getJsonData() - { - return jobDataSet; - } - - - @Override - public Collection getProjectActions() { - List projectActions = new ArrayList(); - projectActions.add(new PerformanceProjectAction(build.getParent())); - return projectActions; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/PerformanceReportAction.java b/src/main/java/com/hp/application/automation/tools/results/PerformanceReportAction.java deleted file mode 100644 index 68581fe6f7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/PerformanceReportAction.java +++ /dev/null @@ -1,145 +0,0 @@ - -/* - * MIT License - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results; - -import hudson.FilePath; -import hudson.model.Action; -import hudson.model.DirectoryBrowserSupport; -import hudson.model.Run; -import hudson.tasks.test.TestResultProjectAction; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - - -public class PerformanceReportAction implements Action, SimpleBuildStep.LastBuildAction { - - private static final String PERFORMANCE_REPORT_FOLDER = "PerformanceReport"; - private static final String REPORT_INDEX = "report.index"; - - private Map detailReportMap = new LinkedHashMap(); - private final List projectActionList; - - - private final Run build; - - public PerformanceReportAction(Run build) throws IOException { - this.build = build; - File reportFolder = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); - if (reportFolder.exists()) { - File indexFile = new File(reportFolder, REPORT_INDEX); - if (indexFile.exists()) { - File file = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); - DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, new FilePath(file), "report", "graph.gif", false); - - - createPreformanceIndexFile(build, indexFile, dbs); - } - } - projectActionList = new ArrayList(); - } - - private void createPreformanceIndexFile(Run build, File indexFile, DirectoryBrowserSupport dbs) throws IOException { - BufferedReader br = new BufferedReader(new FileReader(indexFile)); - String line; - boolean rolling = true; - while ((line = br.readLine()) != null) { - String[] values = line.split("\t"); - if (values.length < 1) - continue; - DetailReport report = new DetailReport(build, values[0], dbs); - if (rolling) { - report.setColor("#FFF"); - rolling = false; - } else { - report.setColor("#F1F1F1"); - rolling = true; - } - if (values.length >= 2) - report.setDuration(values[1]); - else - report.setDuration("##"); - if (values.length >= 3) - report.setPass(values[2]); - else - report.setPass("##"); - if (values.length >= 4) - report.setFail(values[3]); - else - report.setFail("##"); - detailReportMap.put(values[0], report); - } - br.close(); - } - - @Override - public String getIconFileName() { - return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/LoadRunner.png"; - } - - @Override - public String getDisplayName() { - return "Performance Report"; - } - - @Override - public String getUrlName() { - return "PerformanceReport"; - } - - @SuppressWarnings("squid:S1452") - public Run getBuild() { - return build; - } - - public Map getDetailReportMap() { - return detailReportMap; - } - - - public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { - if (detailReportMap.containsKey(name)) - return detailReportMap.get(name); - return null; - } - - @Override - public Collection getProjectActions() { -// List projectActions = new ArrayList<>(); -// projectActions.add(new PerformanceProjectAction(build.getParent())); -// projectActions.add(new TestResultProjectAction(build.getParent())); -// return projectActions; - return Collections.emptySet(); - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/ReportMetaData.java b/src/main/java/com/hp/application/automation/tools/results/ReportMetaData.java deleted file mode 100644 index 28ff8281ef..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/ReportMetaData.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.hp.application.automation.tools.results; - -/** - * Created by xueli on 7/23/2015. - */ -public class ReportMetaData { - - - - private String folderPath; //slave path of report folder(only for html report format) - private String disPlayName; - private String urlName; - private String resourceURL; - private String dateTime; - private String status; - private Boolean isHtmlReport; - - public String getFolderPath() { - return folderPath; - } - - public void setFolderPath(String folderPath) { - this.folderPath = folderPath; - } - - public String getDisPlayName() { - return disPlayName; - } - - public void setDisPlayName(String disPlayName) { - this.disPlayName = disPlayName; - } - - public String getUrlName() { - return urlName; - } - - public void setUrlName(String urlName) { - this.urlName = urlName; - } - - public String getResourceURL() { - return resourceURL; - } - - public void setResourceURL(String resourceURL) { - this.resourceURL = resourceURL; - } - - public String getDateTime() { - return dateTime; - } - - public void setDateTime(String dateTime) { - this.dateTime = dateTime; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Boolean getIsHtmlReport() { - return isHtmlReport; - } - - public void setIsHtmlReport(Boolean isHtmlReport) { - this.isHtmlReport = isHtmlReport; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/RunResultRecorder.java b/src/main/java/com/hp/application/automation/tools/results/RunResultRecorder.java deleted file mode 100644 index e9670927e9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/RunResultRecorder.java +++ /dev/null @@ -1,1335 +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. - -package com.hp.application.automation.tools.results; - -import com.hp.application.automation.tools.common.RuntimeUtils; -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.ResultsPublisherModel; -import com.hp.application.automation.tools.results.projectparser.performance.AvgTransactionResponseTime; -import com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; -import com.hp.application.automation.tools.results.projectparser.performance.LrJobResults; -import com.hp.application.automation.tools.results.projectparser.performance.LrTest; -import com.hp.application.automation.tools.results.projectparser.performance.PercentileTransactionWholeRun; -import com.hp.application.automation.tools.results.projectparser.performance.TimeRange; -import com.hp.application.automation.tools.results.projectparser.performance.TimeRangeResult; -import com.hp.application.automation.tools.results.projectparser.performance.WholeRunResult; -import com.hp.application.automation.tools.run.PcBuilder; -import com.hp.application.automation.tools.run.RunFromAlmBuilder; -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import com.hp.application.automation.tools.run.SseBuilder; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.matrix.MatrixAggregatable; -import hudson.matrix.MatrixAggregator; -import hudson.matrix.MatrixBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.model.Project; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Builder; -import hudson.tasks.Publisher; -import hudson.tasks.Recorder; -import hudson.tasks.junit.CaseResult; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.tasks.junit.SuiteResult; -import hudson.tasks.junit.TestResult; -import hudson.tasks.junit.TestResultAction; -import hudson.tasks.test.TestResultAggregator; -import jenkins.tasks.SimpleBuildStep; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.kohsuke.stapler.DataBoundConstructor; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.annotation.Nonnull; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileFilter; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import static com.hp.application.automation.tools.results.projectparser.performance.XmlParserUtil.getNode; -import static com.hp.application.automation.tools.results.projectparser.performance.XmlParserUtil.getNodeAttr; - -/** - * using {@link JUnitResultArchiver}; - * - * @author Thomas Maurel - */ -public class RunResultRecorder extends Recorder implements Serializable, MatrixAggregatable, SimpleBuildStep { - - public static final String REPORT_NAME_FIELD = "report"; - public static final int SECS_IN_DAY = 86400; - public static final int SECS_IN_HOUR = 3600; - public static final int SECS_IN_MINUTE = 60; - private static final long serialVersionUID = 1L; - private static final String PERFORMANCE_REPORT_FOLDER = "PerformanceReport"; - private static final String IE_REPORT_FOLDER = "IE"; - private static final String HTML_REPORT_FOLDER = "HTML"; - private static final String INDEX_HTML_NAME = "index.html"; - private static final String REPORT_INDEX_NAME = "report.index"; - private static final String REPORTMETADATE_XML = "report_metadata.xml"; - private static final String TRANSACTION_SUMMARY_FOLDER = "TransactionSummary"; - private static final String TRANSACTION_REPORT_NAME = "Report3"; - public static final String SLA_ACTUAL_VALUE_LABEL = "ActualValue"; - public static final String SLA_GOAL_VALUE_LABEL = "GoalValue"; - public static final String SLA_ULL_NAME = "FullName"; - public static final String ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR = - "Archiving test reports failed due to xml parsing error: "; - private final ResultsPublisherModel _resultsPublisherModel; - private List runReportList; - - /** - * Instantiates a new Run result recorder. - * - * @param archiveTestResultsMode the archive test results mode - */ - @DataBoundConstructor - public RunResultRecorder(String archiveTestResultsMode) { - - _resultsPublisherModel = new ResultsPublisherModel(archiveTestResultsMode); - - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - /** - * Pipeline perform. - * - * @param build the build - * @param workspace the workspace - * @param launcher the launcher - * @param listener the listener - * @param builderResultNames the builder result names - * @throws IOException the io exception - * @throws InterruptedException the interrupted exception - */ - // temporary solution to deal with lack of support in builder list when Project is replaced by job type in pipeline. - // Should be dealt with general refactoring - making this a job property or change folder structure to scan instead - // of passing file name from builder. - @SuppressWarnings("squid:S1160") - public void pipelinePerform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, - @Nonnull TaskListener listener, @Nonnull Map builderResultNames) - throws IOException, InterruptedException { - final List mergedResultNames = new ArrayList(); - runReportList = new ArrayList(); - final List fileSystemResultNames = new ArrayList(); - fileSystemResultNames.add(builderResultNames.get(RunFromFileBuilder.class.getName())); - - mergedResultNames.addAll(builderResultNames.values()); - - if (mergedResultNames.isEmpty()) { - listener.getLogger().println("RunResultRecorder: no results xml File provided"); - return; - } - - recordRunResults(build, workspace, launcher, listener, mergedResultNames, fileSystemResultNames); - return; - } - - /** - * Records LR test results copied in JUnit format - * - * @param build - * @param workspace - * @param launcher - * @param listener - * @param mergedResultNames - * @param fileSystemResultNames - * @throws InterruptedException - * @throws IOException - */ - private void recordRunResults(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, - @Nonnull TaskListener listener, List mergedResultNames, - List fileSystemResultNames) throws InterruptedException, IOException { - - - for (String resultFile : mergedResultNames) { - JUnitResultArchiver jUnitResultArchiver = new JUnitResultArchiver(resultFile); - jUnitResultArchiver.setKeepLongStdio(true); - jUnitResultArchiver.setAllowEmptyResults(true); - jUnitResultArchiver.perform(build, workspace, launcher, listener); - } - - final TestResultAction tempAction = build.getAction(TestResultAction.class); - if (tempAction == null || tempAction.getResult() == null) { - listener.getLogger().println("RunResultRecorder: didn't find any test results to record"); - return; - } - - TestResult result = tempAction.getResult(); - - - try { - archiveTestsReport(build, listener, fileSystemResultNames, result, workspace); - } catch (ParserConfigurationException | SAXException e) { - listener.error(ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR + e); - } - - if ((runReportList != null) && !(runReportList.isEmpty())) { - LrJobResults jobDataSet = null; - try { - jobDataSet = buildJobDataset(listener); - } catch (ParserConfigurationException | SAXException e) { - listener.error(ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR + e); - } - - if ((jobDataSet != null && !jobDataSet.getLrScenarioResults().isEmpty())) { - PerformanceJobReportAction performanceJobReportAction = build.getAction(PerformanceJobReportAction.class); - if (performanceJobReportAction != null) { - performanceJobReportAction.mergeResults(jobDataSet); - } else { - performanceJobReportAction = new PerformanceJobReportAction(build, jobDataSet); - } - build.replaceAction(performanceJobReportAction); - } - } - publishLrReports(build); - } - - /** - * Adds the html reports actions to the left side menu. - * - * @param build - */ - private void publishLrReports(@Nonnull Run build) throws IOException { - File reportDirectory = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); - if (reportDirectory.exists()) { - File htmlIndexFile = new File(reportDirectory, INDEX_HTML_NAME); - if (htmlIndexFile.exists()) { - build.replaceAction(new PerformanceReportAction(build)); - } - } - - File summaryDirectory = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); - if (summaryDirectory.exists()) { - File htmlIndexFile = new File(summaryDirectory, INDEX_HTML_NAME); - if (htmlIndexFile.exists()) { - build.replaceAction(new TransactionSummaryAction(build)); - } - } - } - - /** - * copies, archives and creates the Test reports of LR and UFT runs. - * - * @param build - * @param listener - * @param resultFiles - * @param testResult - * @param runWorkspace - * @throws ParserConfigurationException - * @throws SAXException - * @throws IOException - * @throws InterruptedException - */ - @SuppressWarnings({"squid:S134", "squid:S135"}) - private void archiveTestsReport( - Run build, - TaskListener listener, - List resultFiles, - TestResult testResult, FilePath runWorkspace) throws ParserConfigurationException, SAXException, - IOException, InterruptedException { - - if ((resultFiles == null) || (resultFiles.isEmpty())) { - return; - } - - ArrayList zipFileNames = new ArrayList(); - ArrayList reportFolders = new ArrayList(); - List reportNames = new ArrayList(); - - listener.getLogger().println( - "Report archiving mode is set to: " - + _resultsPublisherModel.getArchiveTestResultsMode()); - - FilePath projectWS = runWorkspace; - - // get the artifacts directory where we will upload the zipped report - // folder - File artifactsDir = new File(build.getRootDir(), "archive"); - artifactsDir.mkdirs(); - - // read each result.xml - /* - * The structure of the result file is: - * - * - * - * - * - */ - - // add previous report names for aggregation when using pipelines. - for (SuiteResult suiteResult : testResult.getSuites()) { - String[] temp = suiteResult.getName().split("_"); - reportNames.add(temp[temp.length - 1]); - } - - for (String resultsFilePath : resultFiles) { - FilePath resultsFile = projectWS.child(resultsFilePath); - - List ReportInfoToCollect = new ArrayList(); - - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - - Document doc = dBuilder.parse(resultsFile.read()); - doc.getDocumentElement().normalize(); - - Node testSuiteNode = doc.getElementsByTagName("testsuite").item(0); - Element testSuiteElement = (Element) testSuiteNode; - if (testSuiteElement.hasAttribute("name") && - testSuiteElement.getAttribute("name").endsWith(".lrs")) { // LR test - NodeList testSuiteNodes = doc.getElementsByTagName("testsuite"); - for (int i = 0; i < testSuiteNodes.getLength(); i++) { - testSuiteNode = testSuiteNodes.item(i); - testSuiteElement = (Element) testSuiteNode; - if (!testSuiteElement.hasAttribute("name")) { - continue; - } - String testFolderPath = testSuiteElement.getAttribute("name"); - String testStatus = ("0".equals(testSuiteElement.getAttribute("failures"))) ? "pass" : "fail"; - - Node testCaseNode = testSuiteElement.getElementsByTagName("testcase").item(0); - if (testCaseNode == null) { - listener.getLogger().println("No report folder was found in results"); - return; - } - if (testCaseNode.getNodeType() == Node.ELEMENT_NODE) { - - Element testCaseElement = (Element) testCaseNode; - - if (!testCaseElement.hasAttribute(REPORT_NAME_FIELD)) { - continue; - } - - String reportFolderPath = testCaseElement.getAttribute(REPORT_NAME_FIELD); - FilePath reportFolder = new FilePath(projectWS.getChannel(), reportFolderPath); - reportFolders.add(reportFolder); - - FilePath testFolder = new FilePath(projectWS.getChannel(), testFolderPath); - String zipFileName = getUniqueZipFileNameInFolder(zipFileNames, testFolder.getName()); - FilePath archivedFile = new FilePath(new FilePath(artifactsDir), zipFileName); - - if (archiveFolder(reportFolder, testStatus, archivedFile, listener)) { - zipFileNames.add(zipFileName); - } - - createHtmlReport(reportFolder, testFolderPath, artifactsDir, reportNames, testResult); - createTransactionSummary(reportFolder, testFolderPath, artifactsDir, reportNames, testResult); - try { - FilePath testSla = copyRunReport(reportFolder, build.getRootDir(), - testFolder.getName()); - runReportList.add(testSla); - } catch (IOException | InterruptedException e) { - listener.getLogger().println(e.getMessage()); - } - } - } - } else { // UFT Test - boolean reportIsHtml = false; - NodeList testCasesNodes = ((Element) testSuiteNode).getElementsByTagName("testcase"); - for (int i = 0; i < testCasesNodes.getLength(); i++) { - - Node nNode = testCasesNodes.item(i); - - if (nNode.getNodeType() == Node.ELEMENT_NODE) { - - Element eElement = (Element) nNode; - - if (!eElement.hasAttribute(REPORT_NAME_FIELD)) { - continue; - } - - String reportFolderPath = - eElement.getAttribute(REPORT_NAME_FIELD); // e.g. "C:\UFTTest\GuiTest1\Report" - String testFolderPath = eElement.getAttribute("name"); // e.g. "C:\UFTTest\GuiTest1" - String testStatus = eElement.getAttribute("status"); // e.g. "pass" - - Node nodeSystemInfo = eElement.getElementsByTagName("system-out").item(0); - String sysinfo = nodeSystemInfo.getFirstChild().getNodeValue(); - String testDateTime = sysinfo.substring(0, 19); - - FilePath reportFolder = new FilePath(projectWS.getChannel(), reportFolderPath); - - reportFolders.add(reportFolder); - - String archiveTestResultMode = - _resultsPublisherModel.getArchiveTestResultsMode(); - boolean archiveTestResult = false; - - //check for the new html report - FilePath htmlReport = new FilePath(reportFolder, "run_results.html"); - FilePath rrvReport = new FilePath(reportFolder, "Results.xml"); - if (htmlReport.exists()) { - reportIsHtml = true; - String htmlReportDir = reportFolder.getRemote(); - - ReportMetaData reportMetaData = new ReportMetaData(); - reportMetaData.setFolderPath(htmlReportDir); - reportMetaData.setIsHtmlReport(true); - reportMetaData.setDateTime(testDateTime); - reportMetaData.setStatus(testStatus); - - File testFileFullName = new File(testFolderPath); - String testName = org.apache.commons.io.FilenameUtils.getName(testFileFullName.getPath()); - String resourceUrl = "artifact/UFTReport/" + testName; - reportMetaData.setResourceURL(resourceUrl); - reportMetaData.setDisPlayName(testName); // use the name, not the full path - //don't know reportMetaData's URL path yet, we will generate it later. - ReportInfoToCollect.add(reportMetaData); - - listener.getLogger() - .println("add html report info to ReportInfoToCollect: " + "[date]" + testDateTime); - } - - archiveTestResult = isArchiveTestResult(testStatus, archiveTestResultMode); - - if (archiveTestResult && rrvReport.exists()) { - - if (reportFolder.exists()) { - - FilePath testFolder = new FilePath(projectWS.getChannel(), testFolderPath); - - String zipFileName = getUniqueZipFileNameInFolder(zipFileNames, testFolder.getName()); - zipFileNames.add(zipFileName); - - listener.getLogger().println( - "Zipping report folder: " + reportFolderPath); - - ByteArrayOutputStream outstr = new ByteArrayOutputStream(); - - //don't use FileFilter for zip, or it will cause bug when files are on slave - reportFolder.zip(outstr); - - /* - * I did't use copyRecursiveTo or copyFrom due to - * bug in - * jekins:https://issues.jenkins-ci.org/browse - * /JENKINS-9189 //(which is cleaimed to have been - * fixed, but not. So I zip the folder to stream and - * copy it to the master. - */ - - ByteArrayInputStream instr = new ByteArrayInputStream(outstr.toByteArray()); - - FilePath archivedFile = new FilePath(new FilePath(artifactsDir), zipFileName); - archivedFile.copyFrom(instr); - listener.getLogger().println( - "copy from slave to master: " + archivedFile); - outstr.close(); - instr.close(); - - // add to Report list - ReportMetaData reportMetaData = new ReportMetaData(); - reportMetaData.setIsHtmlReport(false); - // reportMetaData.setFolderPath(htmlReportDir); //no need for RRV - File testFileFullName = new File(testFolderPath); - String testName = testFileFullName.getName(); - reportMetaData.setDisPlayName(testName); // use the name, not the full path - String zipFileUrlName = "artifact/" + zipFileName; - reportMetaData.setUrlName( - zipFileUrlName); // for RRV, the file url and resource url are the same. - reportMetaData.setResourceURL(zipFileUrlName); - reportMetaData.setDateTime(testDateTime); - reportMetaData.setStatus(testStatus); - ReportInfoToCollect.add(reportMetaData); - - } else { - listener.getLogger().println( - "No report folder was found in: " + reportFolderPath); - } - } - - } - } - - if (reportIsHtml && !ReportInfoToCollect.isEmpty()) { - - listener.getLogger().println("begin to collectAndPrepareHtmlReports"); - collectAndPrepareHtmlReports(build, listener, ReportInfoToCollect, runWorkspace); - } - - if (!ReportInfoToCollect.isEmpty()) { - // serialize report metadata - File reportMetaDataXmlFile = new File(artifactsDir.getParent(), REPORTMETADATE_XML); - String reportMetaDataXml = reportMetaDataXmlFile.getAbsolutePath(); - writeReportMetaData2XML(ReportInfoToCollect, reportMetaDataXml, listener); - - // Add UFT report action - try { - listener.getLogger().println("Adding a report action to the current build."); - HtmlBuildReportAction reportAction = new HtmlBuildReportAction(build); - build.addAction(reportAction); - - } catch (IOException | SAXException | ParserConfigurationException ex ) { - listener.getLogger().println("a problem adding action: " + ex); - } - } - } - } - } - - private void writeReportMetaData2XML(List htmlReportsInfo, String xmlFile, TaskListener _logger) { - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = null; - try { - builder = dbf.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - _logger.error("Failed creating xml doc report: " + e); - return; - } - Document doc = builder.newDocument(); - Element root = doc.createElement("reports_data"); - doc.appendChild(root); - - for (ReportMetaData htmlReportInfo : htmlReportsInfo) { - String disPlayName = htmlReportInfo.getDisPlayName(); - String urlName = htmlReportInfo.getUrlName(); - String resourceURL = htmlReportInfo.getResourceURL(); - String dateTime = htmlReportInfo.getDateTime(); - String status = htmlReportInfo.getStatus(); - String isHtmlReport = htmlReportInfo.getIsHtmlReport() ? "true" : "false"; - Element elmReport = doc.createElement(REPORT_NAME_FIELD); - elmReport.setAttribute("disPlayName", disPlayName); - elmReport.setAttribute("urlName", urlName); - elmReport.setAttribute("resourceURL", resourceURL); - elmReport.setAttribute("dateTime", dateTime); - elmReport.setAttribute("status", status); - elmReport.setAttribute("isHtmlreport", isHtmlReport); - root.appendChild(elmReport); - - } - - try { - write2XML(doc, xmlFile); - } catch (TransformerException e) { - _logger.error("Failed transforming xml file: " + e); - } catch (FileNotFoundException e) { - _logger.error("Failed to find " + xmlFile + ": " + e); - } - } - - private void write2XML(Document document, String filename) throws TransformerException, FileNotFoundException { - document.normalize(); - - TransformerFactory tFactory = TransformerFactory.newInstance(); - Transformer transformer = tFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - - DOMSource source = new DOMSource(document); - PrintWriter pw = new PrintWriter(new FileOutputStream(filename)); - StreamResult result = new StreamResult(pw); - transformer.transform(source, result); - - } - - private Boolean collectAndPrepareHtmlReports(Run build, TaskListener listener, List htmlReportsInfo, - FilePath runWorkspace) - throws IOException, InterruptedException { - File reportDir = new File(new File(build.getRootDir(), "archive"), "UFTReport"); - - FilePath rootTarget = new FilePath(reportDir); - - try { - for (ReportMetaData htmlReportInfo : htmlReportsInfo) { - - // make sure it's a html report - if (!htmlReportInfo.getIsHtmlReport()) { - continue; - } - String htmlReportDir = htmlReportInfo.getFolderPath(); // C:\UFTTest\GuiTest1\Report - - listener.getLogger().println("collectAndPrepareHtmlReports, collecting:" + htmlReportDir); - listener.getLogger().println("workspace: " + runWorkspace); - - // copy to the subdirs of master - FilePath source = new FilePath(runWorkspace, htmlReportDir); - listener.getLogger().println("source: " + source); - String testName = htmlReportInfo.getDisPlayName(); // like "GuiTest1" - String dest = testName; - FilePath targetPath = new FilePath(rootTarget, dest); // target path is something like "C:\Program Files - // (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\GuiTest1" - - // zip copy and unzip - ByteArrayOutputStream outstr = new ByteArrayOutputStream(); - - // don't use FileFilter for zip, or it will cause bug when files are on slave - source.zip(outstr); - ByteArrayInputStream instr = new ByteArrayInputStream(outstr.toByteArray()); - - String zipFileName = "UFT_Report_HTML_tmp.zip"; - FilePath archivedFile = new FilePath(rootTarget, zipFileName); - - archivedFile.copyFrom(instr); - - listener.getLogger().println("copy from slave to master: " + archivedFile); - outstr.close(); - instr.close(); - - // unzip - archivedFile.unzip(rootTarget); - archivedFile.delete(); - - // now,all the files are in the C:\Program Files (x86) - // \Jenkins\jobs\testAction\builds\35\archive\UFTReport\Report - // we need to rename the above path to targetPath. - // So at last we got files in C:\Program Files (x86) - // \Jenkins\jobs\testAction\builds\35\archive\UFTReport\GuiTest - - String unzippedFileName = org.apache.commons.io.FilenameUtils.getName(htmlReportDir); - FilePath unzippedFolderPath = new FilePath(rootTarget, unzippedFileName); // C:\Program Files - // (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\Report - // FilePath unzippedFolderPath = new FilePath(rootTarget, source.getName()); //C:\Program Files - // (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\Report - unzippedFolderPath.renameTo(targetPath); - listener.getLogger() - .println("UnzippedFolderPath is: " + unzippedFolderPath + " targetPath is: " + targetPath); - // end zip copy and unzip - - // fill in the urlName of this report. we need a network path not a FS path - String resourceUrl = htmlReportInfo.getResourceURL(); - String urlName = resourceUrl + "/run_results.html"; // like artifact/UFTReport/GuiTest1/run_results.html - - listener.getLogger().println("set the report urlName to " + urlName); - htmlReportInfo.setUrlName(urlName); - - } - } catch (Exception ex) { - listener.getLogger().println("catch exception in collectAndPrepareHtmlReports: " + ex); - } - - return true; - } - - private FilePath copyRunReport(FilePath reportFolder, File buildDir, String - scenerioName) - throws IOException, InterruptedException { - FilePath slaReportFilePath = new FilePath(reportFolder, "RunReport.xml"); - if (slaReportFilePath.exists()) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - slaReportFilePath.zip(baos); - File slaDirectory = new File(buildDir, "RunReport"); - if (!slaDirectory.exists()) { - slaDirectory.mkdir(); - } - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - FilePath slaDirectoryFilePath = new FilePath(slaDirectory); - FilePath tmpZipFile = new FilePath(slaDirectoryFilePath, "runReport.zip"); - tmpZipFile.copyFrom(bais); - bais.close(); - baos.close(); - tmpZipFile.unzip(slaDirectoryFilePath); - FilePath slaFile = new FilePath(slaDirectoryFilePath, "RunReport.xml"); - slaFile.getBaseName(); - slaFile.renameTo(new FilePath(slaDirectoryFilePath, scenerioName + ".xml")); - - slaFile = new FilePath(slaDirectoryFilePath, scenerioName + ".xml"); - - return slaFile; - } - throw (new IOException("no RunReport.xml file was created")); - } - - private boolean archiveFolder(FilePath reportFolder, - String testStatus, - FilePath archivedFile, - TaskListener listener) throws IOException, InterruptedException { - String archiveTestResultMode = _resultsPublisherModel.getArchiveTestResultsMode(); - boolean archiveTestResult; - - archiveTestResult = isArchiveTestResult(testStatus, archiveTestResultMode); - - if (archiveTestResult) { - - if (reportFolder.exists()) { - - listener.getLogger().println( - "Zipping report folder: " + reportFolder); - - ByteArrayOutputStream outstr = new ByteArrayOutputStream(); - reportFolder.zip(outstr); - - /* - * I did't use copyRecursiveTo or copyFrom due to - * bug in - * jekins:https://issues.jenkins-ci.org/browse - * /JENKINS-9189 //(which is cleaimed to have been - * fixed, but not. So I zip the folder to stream and - * copy it to the master. - */ - - ByteArrayInputStream instr = new ByteArrayInputStream(outstr.toByteArray()); - - archivedFile.copyFrom(instr); - - outstr.close(); - instr.close(); - return true; - } else { - listener.getLogger().println( - "No report folder was found in: " + reportFolder); - } - } - - return false; - } - - private boolean isArchiveTestResult(String testStatus, String archiveTestResultMode) { - if (archiveTestResultMode.equals(ResultsPublisherModel.alwaysArchiveResults.getValue()) || - archiveTestResultMode.equals(ResultsPublisherModel.CreateHtmlReportResults.getValue())) { - return true; - } else if (archiveTestResultMode.equals(ResultsPublisherModel.ArchiveFailedTestsResults.getValue())) { - if ("fail".equals(testStatus)) { - return true; - } else if (archiveTestResultMode.equals(ResultsPublisherModel.dontArchiveResults.getValue())) { - return false; - } - } - return false; - } - - /** - * Copy Summary Html reports created by LoadRunner - * - * @param reportFolder - * @param testFolderPath - * @param artifactsDir - * @param reportNames - * @param testResult - * @throws IOException - * @throws InterruptedException - */ - @SuppressWarnings("squid:S134") - private void createHtmlReport(FilePath reportFolder, - String testFolderPath, - File artifactsDir, - List reportNames, - TestResult testResult) throws IOException, InterruptedException { - String archiveTestResultMode = - _resultsPublisherModel.getArchiveTestResultsMode(); - boolean createReport = archiveTestResultMode.equals(ResultsPublisherModel.CreateHtmlReportResults.getValue()); - - - if (createReport) { - File testFolderPathFile = new File(testFolderPath); - FilePath srcDirectoryFilePath = new FilePath(reportFolder, HTML_REPORT_FOLDER); - if (srcDirectoryFilePath.exists()) { - FilePath srcFilePath = new FilePath(srcDirectoryFilePath, IE_REPORT_FOLDER); - if (srcFilePath.exists()) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - srcFilePath.zip(baos); - File reportDirectory = new File(artifactsDir.getParent(), PERFORMANCE_REPORT_FOLDER); - if (!reportDirectory.exists()) { - reportDirectory.mkdir(); - } - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - FilePath reportDirectoryFilePath = new FilePath(reportDirectory); - FilePath tmpZipFile = new FilePath(reportDirectoryFilePath, "tmp.zip"); - tmpZipFile.copyFrom(bais); - bais.close(); - baos.close(); - tmpZipFile.unzip(reportDirectoryFilePath); - String newFolderName = org.apache.commons.io.FilenameUtils.getName(testFolderPathFile.getPath()); - FileUtils.moveDirectory(new File(reportDirectory, IE_REPORT_FOLDER), - new File(reportDirectory, newFolderName)); - tmpZipFile.delete(); - outputReportFiles(reportNames, reportDirectory, testResult, false); - } - } - } - } - - /** - * creates index files as index for the different scenarios. - * - * @param reportNames - * @param reportDirectory - * @param testResult - * @param tranSummary - * @throws IOException - */ - private void outputReportFiles(List reportNames, File reportDirectory, TestResult testResult, - boolean tranSummary) throws IOException { - - if (reportNames.isEmpty()) { - return; - } - String title = (tranSummary) ? "Transaction Summary" : "Performance Report"; - String htmlFileName = (tranSummary) ? (TRANSACTION_REPORT_NAME + ".html") : "HTML.html"; - File htmlIndexFile = new File(reportDirectory, INDEX_HTML_NAME); - BufferedWriter writer = new BufferedWriter(new FileWriter(htmlIndexFile)); - writer.write("%n"); - writer.write("%n"); - writer.write("%n"); - writer.write(String.format("%s%n", title)); - writer.write("%n"); - writer.write("%n"); - writer.write( - "%n"); - writer.write( - "%n"); - boolean rolling = true; - for (String report : reportNames) { - if (rolling) { - writer.write(String.format( - "%n", - report, htmlFileName, report)); - rolling = false; - } else { - writer.write(String.format( - "%n", - report, htmlFileName, report)); - rolling = true; - } - } - writer.write("
Name
%s
%s
%n"); - writer.write("%n"); - writer.flush(); - writer.close(); - - File indexFile = new File(reportDirectory, REPORT_INDEX_NAME); - writer = new BufferedWriter(new FileWriter(indexFile)); - - Iterator resultIterator = null; - if ((testResult != null) && (!testResult.getSuites().isEmpty())) { - resultIterator = testResult.getSuites().iterator();//get the first - } - for (String report : reportNames) { - SuiteResult suitResult = null; - if ((resultIterator != null) && resultIterator.hasNext()) { - suitResult = resultIterator.next(); - } - if (suitResult == null) { - writer.write(report + "\t##\t##\t##%n"); - } else { - int iDuration = (int) suitResult.getDuration(); - StringBuilder bld = new StringBuilder(); - String duration = ""; - if ((iDuration / SECS_IN_DAY) > 0) { - bld.append(String.format("%dday ", iDuration / SECS_IN_DAY)); - iDuration = iDuration % SECS_IN_DAY; - } - if ((iDuration / SECS_IN_HOUR) > 0) { - bld.append(String.format("%02dhr ", iDuration / SECS_IN_HOUR)); - iDuration = iDuration % SECS_IN_HOUR; - } else if (!duration.isEmpty()) { - bld.append("00hr "); - } - if ((iDuration / SECS_IN_MINUTE) > 0) { - bld.append(String.format("%02dmin ", iDuration / SECS_IN_MINUTE)); - iDuration = iDuration % SECS_IN_MINUTE; - } else if (!duration.isEmpty()) { - bld.append("00min "); - } - bld.append(String.format("%02dsec", iDuration)); - duration = bld.toString(); - int iPassCount = 0; - int iFailCount = 0; - for (Iterator i = suitResult.getCases().iterator(); i.hasNext(); ) { - CaseResult caseResult = (CaseResult) i.next(); - iPassCount += caseResult.getPassCount(); - iFailCount += caseResult.getFailCount(); - } - writer.write( - String.format("%s\t%s\t%d\t%d%n", - report, - duration, - iPassCount, - iFailCount)); - } - } - writer.flush(); - writer.close(); - } - - /** - * Copies and creates the transaction summery on the master - * - * @param reportFolder - * @param testFolderPath - * @param artifactsDir - * @param reportNames - * @param testResult - * @throws IOException - * @throws InterruptedException - */ - private void createTransactionSummary(FilePath reportFolder, - String testFolderPath, - File artifactsDir, - List reportNames, - TestResult testResult) throws IOException, InterruptedException { - - File testFolderPathFile = new File(testFolderPath); - String subFolder = HTML_REPORT_FOLDER + File.separator + IE_REPORT_FOLDER + File.separator + HTML_REPORT_FOLDER; - FilePath htmlReportPath = new FilePath(reportFolder, subFolder); - if (htmlReportPath.exists()) { - File reportDirectory = new File(artifactsDir.getParent(), TRANSACTION_SUMMARY_FOLDER); - if (!reportDirectory.exists()) { - reportDirectory.mkdir(); - } - String newFolderName = org.apache.commons.io.FilenameUtils.getName(testFolderPathFile.getPath()); - File testDirectory = new File(reportDirectory, newFolderName); - if (!testDirectory.exists()) { - testDirectory.mkdir(); - } - - FilePath dstReportPath = new FilePath(testDirectory); - FileFilter reportFileFilter = new WildcardFileFilter(TRANSACTION_REPORT_NAME + ".*"); - List reporFiles = htmlReportPath.list(reportFileFilter); - for (FilePath fileToCopy : reporFiles) { - FilePath dstFilePath = new FilePath(dstReportPath, fileToCopy.getName()); - fileToCopy.copyTo(dstFilePath); - } - FilePath cssFilePath = new FilePath(htmlReportPath, "Properties.css"); - if (cssFilePath.exists()) { - FilePath dstFilePath = new FilePath(dstReportPath, cssFilePath.getName()); - cssFilePath.copyTo(dstFilePath); - } - FilePath pngFilePath = new FilePath(htmlReportPath, "tbic_toexcel.png"); - if (pngFilePath.exists()) { - FilePath dstFilePath = new FilePath(dstReportPath, pngFilePath.getName()); - pngFilePath.copyTo(dstFilePath); - } - - outputReportFiles(reportNames, reportDirectory, testResult, true); - - } - - } - - /* - * if we have a directory with file name "file.zip" we will return "file_1.zip" - */ - private String getUniqueZipFileNameInFolder(ArrayList names, String fileName) - throws IOException, InterruptedException { - - String result = fileName + "_Report.zip"; - - int index = 0; - - while (names.indexOf(result) > -1) { - result = fileName + "_" + (++index) + "_Report.zip"; - } - - return result; - } - - - private LrJobResults buildJobDataset(TaskListener listener) - throws ParserConfigurationException, SAXException, - IOException, InterruptedException { - listener.getLogger().println( - "Parsing test run dataset for perfomrance report"); - LrJobResults jobResults = new LrJobResults(); - - // read each RunReport.xml - for (FilePath reportFilePath : runReportList) { - JobLrScenarioResult jobLrScenarioResult = parseScenarioResults(reportFilePath); - jobResults.addScenario(jobLrScenarioResult); - } - - return jobResults; - } - - private JobLrScenarioResult parseScenarioResults(FilePath slaFilePath) - throws ParserConfigurationException, SAXException, IOException, InterruptedException { - JobLrScenarioResult jobLrScenarioResult = new JobLrScenarioResult(slaFilePath.getBaseName()); - - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - - Document doc = dBuilder.parse(slaFilePath.read()); -// doc.getDocumentElement().normalize(); - - processSLA(jobLrScenarioResult, doc); - processLrScenarioStats(jobLrScenarioResult, doc); - //TODO: add fail / Pass count - return jobLrScenarioResult; - } - - private void processLrScenarioStats(JobLrScenarioResult jobLrScenarioResult, Document doc) { - - NodeList rootNodes = doc.getChildNodes(); - Node root = getNode("Runs", rootNodes); - Element generalNode = (Element) getNode("General", root.getChildNodes()); - NodeList generalNodeChildren = generalNode.getChildNodes(); - - extractVUserScenarioReult(jobLrScenarioResult, generalNodeChildren); - extractTransactionScenarioResult(jobLrScenarioResult, generalNodeChildren); - extractConnectionsScenarioResult(jobLrScenarioResult, generalNodeChildren); - extractDuration(jobLrScenarioResult, generalNodeChildren); - } - - private void extractDuration(JobLrScenarioResult jobLrScenarioResult, NodeList generalNodeChildren) { - Node ScenrioDurationNode = getNode("Time", generalNodeChildren); - String scenarioDurationAttr = getNodeAttr("Duration", ScenrioDurationNode); - jobLrScenarioResult.setScenarioDuration(Long.valueOf(scenarioDurationAttr)); - } - - private void extractConnectionsScenarioResult(JobLrScenarioResult jobLrScenarioResult, - NodeList generalNodeChildren) { - Node connections = getNode("Connections", generalNodeChildren); - jobLrScenarioResult.setConnectionMax(Integer.valueOf(getNodeAttr("MaxCount", connections))); - } - - private void extractTransactionScenarioResult(JobLrScenarioResult jobLrScenarioResult, - NodeList generalNodeChildren) { - int atrrCount; - Node transactions = getNode("Transactions", generalNodeChildren); - atrrCount = transactions.getAttributes().getLength(); - for (int atrrIndx = 0; atrrIndx < atrrCount; atrrIndx++) { - Node vUserAttr = transactions.getAttributes().item(atrrIndx); - jobLrScenarioResult.transactionSum.put(vUserAttr.getNodeName(), Integer.valueOf(vUserAttr.getNodeValue())); - } - - NodeList transactionNodes = transactions.getChildNodes(); - int transactionNodesCount = transactionNodes.getLength(); - for (int transIdx = 0; transIdx < transactionNodesCount; transIdx++) { - if (transactionNodes.item(transIdx).getNodeType() != Node.ELEMENT_NODE) { - continue; - } - Element transaction = (Element) transactionNodes.item(transIdx); - TreeMap transactionData = new TreeMap(); - transactionData.put("Pass", Integer.valueOf(transaction.getAttribute("Pass"))); - transactionData.put("Fail", Integer.valueOf(transaction.getAttribute("Fail"))); - transactionData.put("Stop", Integer.valueOf(transaction.getAttribute("Stop"))); - jobLrScenarioResult.transactionData.put(transaction.getAttribute("Name"), transactionData); - } - } - - private void extractVUserScenarioReult(JobLrScenarioResult jobLrScenarioResult, NodeList generalNodeChildren) { - Node vUser = getNode("VUsers", generalNodeChildren); - int atrrCount = vUser.getAttributes().getLength(); - for (int atrrIndx = 0; atrrIndx < atrrCount; atrrIndx++) { - Node vUserAttr = vUser.getAttributes().item(atrrIndx); - jobLrScenarioResult.vUserSum.put(vUserAttr.getNodeName(), Integer.valueOf(vUserAttr.getNodeValue())); - } - } - - private void processSLA(JobLrScenarioResult jobLrScenarioResult, Document doc) { - Node slaRuleNode; - Element slaRuleElement; - - NodeList rootNodes = doc.getChildNodes(); - Node root = getNode("Runs", rootNodes); - Element slaRoot = (Element) getNode("SLA", root.getChildNodes()); - NodeList slaRuleResults = slaRoot.getChildNodes(); - - - for (int j = 0; j < slaRuleResults.getLength(); j++) { - slaRuleNode = slaRuleResults.item(j); - if (slaRuleNode.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - slaRuleElement = (Element) slaRuleNode; - //check type by mesurment field: - LrTest.SLA_GOAL slaGoal = LrTest.SLA_GOAL.checkGoal(slaRuleElement.getAttribute("Measurement")); - - processSlaRule(jobLrScenarioResult, slaRuleElement, slaGoal); - } - - } - - private void processSlaRule(JobLrScenarioResult jobLrScenarioResult, Element slaRuleElement, - LrTest.SLA_GOAL slaGoal) { - switch (slaGoal) { - case AverageThroughput: - WholeRunResult averageThroughput = new WholeRunResult(); - averageThroughput.setSlaGoal(LrTest.SLA_GOAL.AverageThroughput); - averageThroughput.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); - averageThroughput.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); - averageThroughput.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - averageThroughput.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getTextContent())); - jobLrScenarioResult.scenarioSlaResults.add(averageThroughput); - break; - case TotalThroughput: - WholeRunResult totalThroughput = new WholeRunResult(); - totalThroughput.setSlaGoal(LrTest.SLA_GOAL.TotalThroughput); - totalThroughput.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); - totalThroughput.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); - totalThroughput.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - totalThroughput.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getTextContent())); - jobLrScenarioResult.scenarioSlaResults.add(totalThroughput); - - break; - case AverageHitsPerSecond: - WholeRunResult averageHitsPerSecond = new WholeRunResult(); - averageHitsPerSecond.setSlaGoal(LrTest.SLA_GOAL.AverageHitsPerSecond); - averageHitsPerSecond.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); - averageHitsPerSecond.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); - averageHitsPerSecond.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - averageHitsPerSecond.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getTextContent())); - jobLrScenarioResult.scenarioSlaResults.add(averageHitsPerSecond); - - break; - case TotalHits: - WholeRunResult totalHits = new WholeRunResult(); - totalHits.setSlaGoal(LrTest.SLA_GOAL.TotalHits); - totalHits.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); - totalHits.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); - totalHits.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - totalHits.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getTextContent())); - jobLrScenarioResult.scenarioSlaResults.add(totalHits); - - break; - case ErrorsPerSecond: - TimeRangeResult errPerSec = new AvgTransactionResponseTime(); - errPerSec.setSlaGoal(LrTest.SLA_GOAL.ErrorsPerSecond); - errPerSec.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - errPerSec.setLoadThrashold(slaRuleElement.getAttribute("SLALoadThresholdValue")); - errPerSec.setStatus(LrTest.SLA_STATUS.checkStatus( - slaRuleElement.getFirstChild().getTextContent())); //Might not work due to time ranges - addTimeRanges(errPerSec, slaRuleElement); - jobLrScenarioResult.scenarioSlaResults.add(errPerSec); - - break; - case PercentileTRT: - PercentileTransactionWholeRun percentileTransactionWholeRun = new PercentileTransactionWholeRun(); - percentileTransactionWholeRun.setSlaGoal(LrTest.SLA_GOAL.PercentileTRT); - percentileTransactionWholeRun.setName(slaRuleElement.getAttribute("TransactionName")); - percentileTransactionWholeRun - .setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); - percentileTransactionWholeRun.setGoalValue(Double.valueOf(slaRuleElement.getAttribute( - SLA_GOAL_VALUE_LABEL))); - percentileTransactionWholeRun.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - percentileTransactionWholeRun.setPrecentage(Double.valueOf(slaRuleElement.getAttribute("Percentile"))); - percentileTransactionWholeRun.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getTextContent())); - jobLrScenarioResult.scenarioSlaResults.add(percentileTransactionWholeRun); - - break; - case AverageTRT: - AvgTransactionResponseTime transactionTimeRange = new AvgTransactionResponseTime(); - transactionTimeRange.setSlaGoal(LrTest.SLA_GOAL.AverageTRT); - transactionTimeRange.setName(slaRuleElement.getAttribute("TransactionName")); - transactionTimeRange.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); - transactionTimeRange.setLoadThrashold(slaRuleElement.getAttribute("SLALoadThresholdValue")); - transactionTimeRange.setStatus(LrTest.SLA_STATUS.checkStatus( - slaRuleElement.getFirstChild().getTextContent())); //Might not work due to time ranges - addTimeRanges(transactionTimeRange, slaRuleElement); - jobLrScenarioResult.scenarioSlaResults.add(transactionTimeRange); - break; - case Bad: - break; - } - } - - private static void addTimeRanges(TimeRangeResult transactionTimeRange, Element slaRuleElement) { - Node timeRangeNode; - Element timeRangeElement; - NodeList timeRanges = slaRuleElement.getElementsByTagName("TimeRangeInfo"); - - //Taking the goal per transaction - - double generalGoalValue = Double.parseDouble(((Element) timeRanges.item(0)).getAttribute(SLA_GOAL_VALUE_LABEL)); - transactionTimeRange.setGoalValue(generalGoalValue); - - for (int k = 0; k < timeRanges.getLength(); k++) { - timeRangeNode = timeRanges.item(k); - timeRangeElement = (Element) timeRangeNode; - double actualValue = Double.parseDouble(timeRangeElement.getAttribute(SLA_ACTUAL_VALUE_LABEL)); - double goalValue = Double.parseDouble(timeRangeElement.getAttribute(SLA_GOAL_VALUE_LABEL)); - int loadValue = Integer.parseInt(timeRangeElement.getAttribute("LoadValue")); - double startTime = Double.parseDouble(timeRangeElement.getAttribute("StartTime")); - double endTIme = Double.parseDouble(timeRangeElement.getAttribute("EndTime")); - transactionTimeRange.incActualValue(actualValue); - LrTest.SLA_STATUS slaStatus = - LrTest.SLA_STATUS.checkStatus(timeRangeElement.getFirstChild().getTextContent()); - TimeRange timeRange = new TimeRange(actualValue, goalValue, slaStatus, loadValue, startTime, endTIme); - transactionTimeRange.getTimeRanges().add(timeRange); - } - } - - @Override - public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, - @Nonnull TaskListener listener) throws InterruptedException, IOException { - final List mergedResultNames = new ArrayList(); - - Project project = RuntimeUtils.cast(build.getParent()); - List builders = project.getBuilders(); - runReportList = new ArrayList(); - final List almResultNames = new ArrayList(); - final List fileSystemResultNames = new ArrayList(); - final List almSSEResultNames = new ArrayList(); - final List pcResultNames = new ArrayList(); - - // Get the TestSet report files names of the current build - for (Builder builder : builders) { - if (builder instanceof RunFromAlmBuilder) { - almResultNames.add(((RunFromAlmBuilder) builder).getRunResultsFileName()); - } else if (builder instanceof RunFromFileBuilder) { - fileSystemResultNames.add(((RunFromFileBuilder) builder).getRunResultsFileName()); - } else if (builder instanceof SseBuilder) { - String resultsFileName = ((SseBuilder) builder).getRunResultsFileName(); - if (resultsFileName != null) { - almSSEResultNames.add(resultsFileName); - } - } else if (builder instanceof PcBuilder) { - String resultsFileName = ((PcBuilder) builder).getRunResultsFileName(); - if (resultsFileName != null) { - pcResultNames.add(resultsFileName); - } - } - } - - mergedResultNames.addAll(almResultNames); - mergedResultNames.addAll(fileSystemResultNames); - mergedResultNames.addAll(almSSEResultNames); - mergedResultNames.addAll(pcResultNames); - - // Has any QualityCenter builder been set up? - if (mergedResultNames.isEmpty()) { - listener.getLogger().println("RunResultRecorder: no results xml File provided"); - return; - } - - recordRunResults(build, workspace, launcher, listener, mergedResultNames, fileSystemResultNames); - return; - } - - @Override - public MatrixAggregator createAggregator( - MatrixBuild build, - Launcher launcher, - BuildListener listener) { - - return new TestResultAggregator(build, launcher, listener); - } - - @Override - public BuildStepMonitor getRequiredMonitorService() { - - return BuildStepMonitor.BUILD; - } - - /** - * Gets results publisher model. - * - * @return the results publisher model - */ - public ResultsPublisherModel getResultsPublisherModel() { - - return _resultsPublisherModel; - } - - /** - * The type Descriptor. - */ - @Extension - public static class DescriptorImpl extends BuildStepDescriptor { - - /** - * Instantiates a new Descriptor. - */ - public DescriptorImpl() { - - load(); - } - - @Override - public String getDisplayName() { - - return "Publish HP tests result"; - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - - return true; - } - - /** - * Gets report archive modes. - * - * @return the report archive modes - */ - public List getReportArchiveModes() { - - return ResultsPublisherModel.archiveModes; - } - } - - /** - * The type Rrv file filter. - */ - public class RRVFileFilter implements FileFilter { - private final String[] excludedFilenames = - new String[]{"run_results.xml", "run_results.html", "diffcompare", "Resources"}; - private final String[] excludedDirnames = new String[]{"diffcompare", "Resources", "CheckPoints", "Snapshots"}; - - @Override - public boolean accept(File file) { - boolean bRet = true; - - for (String filename : excludedFilenames) { - if (file.getName().equals(filename)) { - bRet = false; - break; - } - } - - if (bRet) { - for (String parentname : excludedDirnames) { - if (file.getParent().contains(parentname)) { - bRet = false; - break; - } - } - } - return bRet; - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/SlaRuleTypes.java b/src/main/java/com/hp/application/automation/tools/results/SlaRuleTypes.java deleted file mode 100644 index 768a55e575..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/SlaRuleTypes.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hp.application.automation.tools.results; - -/** - * Created by kazaky on 07/07/2016. - */ -public enum SlaRuleTypes -{ - SIMPLE_WHOLE_RUN, - WHOLE_RUN, - TIME_RANGE_TRANSACTION, - SIMPLE_TIME_RANGE, - TRANSACTION_PERCENTILE; -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/results/SummaryReport.java b/src/main/java/com/hp/application/automation/tools/results/SummaryReport.java deleted file mode 100644 index 531d12d52c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/SummaryReport.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.hp.application.automation.tools.results; - -import hudson.model.DirectoryBrowserSupport; -import hudson.model.ModelObject; -import hudson.model.Run; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.ServletException; -import java.io.IOException; - -/** - * Models the HTML summary reports - */ -public class SummaryReport implements ModelObject { - - private String name = ""; - private String color = ""; - private String duration = ""; - private String pass = ""; - private String fail = ""; - private Run build = null; - private DirectoryBrowserSupport _directoryBrowserSupport = null; - - /** - * Instantiates a new Summary report. - * - * @param build the build - * @param name the name - * @param directoryBrowserSupport the directory browser support - */ - public SummaryReport(Run build, String name, DirectoryBrowserSupport directoryBrowserSupport) { - this.build = build; - this.name = name; - _directoryBrowserSupport = directoryBrowserSupport; - } - - @Override - public String getDisplayName() { - return name; - } - - /** - * Gets build. - * - * @return the build - */ - public Run getBuild() { - return build; - } - - /** - * Gets name. - * - * @return the name - */ - public String getName() { - return name; - } - - /** - * Do dynamic. - * - * @param req the req - * @param rsp the rsp - * @throws IOException the io exception - * @throws ServletException the servlet exception - */ - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - - if (_directoryBrowserSupport != null) - _directoryBrowserSupport.generateResponse(req, rsp, this); - } - - /** - * Gets color. - * - * @return the color - */ - public String getColor() { - return color; - } - - /** - * Sets color. - * - * @param value the value - */ - public void setColor(String value) { - color = value; - } - - /** - * Gets duration. - * - * @return the duration - */ - public String getDuration() { - return duration; - } - - /** - * Sets duration. - * - * @param value the value - */ - public void setDuration(String value) { - duration = value; - } - - /** - * Gets pass. - * - * @return the pass - */ - public String getPass() { - return pass; - } - - /** - * Sets pass. - * - * @param value the value - */ - public void setPass(String value) { - pass = value; - } - - /** - * Gets fail. - * - * @return the fail - */ - public String getFail() { - return fail; - } - - /** - * Sets fail. - * - * @param value the value - */ - public void setFail(String value) { - fail = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/TestResultToALMUploader.java b/src/main/java/com/hp/application/automation/tools/results/TestResultToALMUploader.java deleted file mode 100644 index bde2d62796..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/TestResultToALMUploader.java +++ /dev/null @@ -1,291 +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. - -package com.hp.application.automation.tools.results; - -import hudson.Extension; -import hudson.Launcher; -import hudson.matrix.MatrixAggregatable; -import hudson.matrix.MatrixAggregator; -import hudson.matrix.MatrixBuild; -import hudson.model.Action; -import hudson.model.BuildListener; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.Hudson; -import hudson.model.Result; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Publisher; -import hudson.tasks.Recorder; -import hudson.tasks.test.TestResultAggregator; -import hudson.tasks.test.TestResultProjectAction; -import hudson.util.FormValidation; - -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.apache.tools.ant.DirectoryScanner; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import com.hp.application.automation.tools.model.AlmServerSettingsModel; -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.UploadTestResultToAlmModel; -import com.hp.application.automation.tools.results.service.AlmRestInfo; -import com.hp.application.automation.tools.results.service.AlmRestTool; -import com.hp.application.automation.tools.results.service.DefaultExternalEntityUploadServiceImpl; -import com.hp.application.automation.tools.results.service.ExternalEntityUploadLogger; -import com.hp.application.automation.tools.results.service.IExternalEntityUploadService; -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; - -/** - - * - * @author Jacky Zhu - */ -public class TestResultToALMUploader extends Recorder implements Serializable, MatrixAggregatable { - - private static final long serialVersionUID = 1L; - private final UploadTestResultToAlmModel uploadTestResultToAlmModel; - - @DataBoundConstructor - public TestResultToALMUploader( - String almServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String testingFramework, - String testingTool, - String almTestFolder, - String almTestSetFolder, - String almTimeout, - String testingResultFile, - String jenkinsServerUrl) { - - uploadTestResultToAlmModel = new UploadTestResultToAlmModel( almServerName, almUserName, - almPassword, almDomain, almProject, testingFramework, testingTool, - almTestFolder, almTestSetFolder, almTimeout, testingResultFile, jenkinsServerUrl); - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - public AlmServerSettingsModel getAlmServerSettingsModel() { - for (AlmServerSettingsModel almServer : getDescriptor().getAlmServers()) { - if (this.uploadTestResultToAlmModel != null - && uploadTestResultToAlmModel.getAlmServerName().equals(almServer.getAlmServerName())) { - return almServer; - } - } - return null; - } - - public UploadTestResultToAlmModel getUploadTestResultToAlmModel() { - return uploadTestResultToAlmModel; - } - - private String getAlmServerUrl(String almServerName) { - AlmServerSettingsModel[] almServers = Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - if(almServers != null && almServers.length >0) { - for(AlmServerSettingsModel almServerModel: almServers) { - if(almServerName.equalsIgnoreCase(almServerModel.getAlmServerName())) { - return almServerModel.getAlmServerUrl(); - } - } - } - - return ""; - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) - throws InterruptedException, IOException { - - ExternalEntityUploadLogger logger = new ExternalEntityUploadLogger(listener.getLogger()); - - logger.log("INFO: 'Upload test result to ALM' Post Build Step is being invoked."); - if(uploadTestResultToAlmModel == null){ - logger.log("ERROR: No configuration for 'Upload test reslt to ALM' step"); - } - - - String serverUrl = getAlmServerUrl(uploadTestResultToAlmModel.getAlmServerName()); - String runUrl = ""; - String tempUrl = uploadTestResultToAlmModel.getJenkinsServerUrl(); - if(tempUrl != null && tempUrl.length() >0 ) { - if(tempUrl.charAt(tempUrl.length() -1) != '/') { - runUrl= tempUrl + "/" + build.getUrl(); - } else { - runUrl = tempUrl + build.getUrl(); - } - } - - File root = build.getRootDir(); - DirectoryScanner ds = new DirectoryScanner(); - ds.setBasedir(root); - ds.setIncludes( new String[] {uploadTestResultToAlmModel.getTestingResultFile()}); - - ds.scan(); - if (ds.getIncludedFilesCount() == 0) { - logger.log("INFO: No Test Report found."); - } else { - logger.log("INFO: "+ ds.getIncludedFilesCount() +" test result file found."); - String[] files = ds.getIncludedFiles(); - for(String fileName : files) { - String fullpath = root.getAbsolutePath() + File.separator + fileName; - AlmRestInfo loginInfo = new AlmRestInfo( - serverUrl, - uploadTestResultToAlmModel.getAlmDomain(), - uploadTestResultToAlmModel.getAlmProject(), - uploadTestResultToAlmModel.getAlmUserName(), - uploadTestResultToAlmModel.getAlmPassword(), - uploadTestResultToAlmModel.getAlmTestSetFolder() - ); - AlmRestTool u = new AlmRestTool(loginInfo, logger); - logger.log("INFO: Start to upload "+fullpath); - IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, logger ); - try { - service.UploadExternalTestSet(loginInfo, - fullpath, - uploadTestResultToAlmModel.getAlmTestSetFolder(), - uploadTestResultToAlmModel.getAlmTestFolder(), - uploadTestResultToAlmModel.getTestingFramework(), - uploadTestResultToAlmModel.getTestingTool(), - String.valueOf(build.getNumber()), - build.getParent().getDisplayName(), - runUrl - ); - logger.log("INFO: Uploaded "+fullpath + "."); - } catch (Exception e) { - logger.log("WARN: there's exception while uploading "+fullpath + "."); - build.setResult(Result.UNSTABLE); - } - - } - } - - logger.log("INFO: 'Upload test result to ALM' Completed."); - - return true; - } - - - - - @Override - public Action getProjectAction(AbstractProject project) { - - return new TestResultProjectAction(project); - } - - @Override - public MatrixAggregator createAggregator( - MatrixBuild build, - Launcher launcher, - BuildListener listener) { - - return new TestResultAggregator(build, launcher, listener); - } - - @Override - public BuildStepMonitor getRequiredMonitorService() { - - return BuildStepMonitor.BUILD; - } - - @Extension - public static class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - - load(); - } - - @Override - public String getDisplayName() { - - return "Upload test result to ALM"; - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - - return true; - } - - public boolean hasAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).hasAlmServers(); - } - - public AlmServerSettingsModel[] getAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - } - - public FormValidation doCheckAlmUserName(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("User name must be set"); - } - - return FormValidation.ok(); - } - public FormValidation doCheckAlmDomain(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Domain must be set"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmProject(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Project must be set"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmTestFolder(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("TestFolder are missing"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmTestSetFolder(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("TestSetFolder are missing"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckTestingResultFile(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Testing result file must be set"); - } - - return FormValidation.ok(); - } - - public List getTestingFrameworks() { - return UploadTestResultToAlmModel.testingFrameworks; - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/TransactionSummaryAction.java b/src/main/java/com/hp/application/automation/tools/results/TransactionSummaryAction.java deleted file mode 100644 index 7550829ec3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/TransactionSummaryAction.java +++ /dev/null @@ -1,164 +0,0 @@ - -/* - * MIT License - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results; - -import hudson.FilePath; -import hudson.model.Action; -import hudson.model.DirectoryBrowserSupport; -import hudson.model.Run; -import hudson.tasks.test.TestResultProjectAction; -import jenkins.tasks.SimpleBuildStep; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Generates the transaction summary reports and adds them to the run - */ -public class TransactionSummaryAction implements Action, SimpleBuildStep.LastBuildAction { - - private static final String TRANSACTION_SUMMARY_FOLDER = "TransactionSummary"; - private static final String REPORT_INDEX = "report.index"; - - private Map summaryReportMap = new LinkedHashMap(); - private final List projectActionList; - - private Run build; - - /** - * Instantiates a new Transaction summary action. - * - * @param build the build - */ - public TransactionSummaryAction(Run build) throws IOException { - this.build = build; - File reportFolder = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); - if (reportFolder.exists()) { - File indexFile = new File(reportFolder, REPORT_INDEX); - if (indexFile.exists()) { - File file = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); - DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, new FilePath(file), "report", "graph.gif", false); - - - createTransactionIndex(build, indexFile, dbs); - - - } - } - projectActionList = new ArrayList(); - } - - private void createTransactionIndex(Run build, File indexFile, DirectoryBrowserSupport dbs) throws IOException { - BufferedReader br = new BufferedReader(new FileReader(indexFile)); - String line; - boolean rolling = true; - while ((line = br.readLine()) != null) { - String[] values = line.split("\t"); - if (values.length < 1) - continue; - SummaryReport report = new SummaryReport(build, values[0], dbs); - if (rolling) { - report.setColor("#FFF"); - rolling = false; - } else { - report.setColor("#F1F1F1"); - rolling = true; - } - if (values.length >= 2) - report.setDuration(values[1]); - else - report.setDuration("##"); - if (values.length >= 3) - report.setPass(values[2]); - else - report.setPass("##"); - if (values.length >= 4) - report.setFail(values[3]); - else - report.setFail("##"); - summaryReportMap.put(values[0], report); - } - br.close(); - } - - @Override - public String getIconFileName() { - return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/LoadRunner.png"; - } - - @Override - public String getDisplayName() { - return "Transaction Summary"; - } - - @Override - public String getUrlName() { - return "TransactionSummary"; - } - - /** - * Gets build. - * - * @return the build - */ - public Run getBuild() { - return build; - } - - /** - * Gets summary report map. - * - * @return the summary report map - */ - public Map getSummaryReportMap() { - return summaryReportMap; - } - - /** - * Gets dynamic. - * - * @param name the name - * @param req the req - * @param rsp the rsp - * @return the dynamic - */ - public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { - if (summaryReportMap.containsKey(name)) - return summaryReportMap.get(name); - return null; - } - - @Override - public Collection getProjectActions() { - return Collections.emptySet(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParseException.java b/src/main/java/com/hp/application/automation/tools/results/parser/ReportParseException.java deleted file mode 100644 index 1c5c609e49..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParseException.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hp.application.automation.tools.results.parser; - -public class ReportParseException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public ReportParseException(){ - - } - - public ReportParseException(Throwable cause) { - - super(cause); - } - - public ReportParseException(String message) { - - super(message); - } - - public ReportParseException(String message, Throwable cause) { - - super(message, cause); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParser.java b/src/main/java/com/hp/application/automation/tools/results/parser/ReportParser.java deleted file mode 100644 index 551be92517..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParser.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; - -public interface ReportParser { - String TESTING_FRAMEWORK_JUNIT = "JUnit"; - String EXTERNAL_TEST_TYPE = "EXTERNAL-TEST"; - String REPORT_FORMAT_JENKINS_JUNIT_PLUGIN = "Jenkins JUnit Plugin"; - String REPORT_FORMAT_ANT = "Ant"; - String REPORT_FORMAT_MAVEN_SUREFIRE_PLUGIN = "Maven Surefire Plugin"; - String EXTERNAL_TEST_SET_TYPE_ID = "hp.qc.test-set.external"; - String EXTERNAL_TEST_INSTANCE_TYPE_ID = "hp.qc.test-instance.external-test"; - String EXTERNAL_RUN_TYPE_ID = "hp.qc.run.external-test"; - - List parseTestSets(InputStream reportInputStream, String testingFramework, String testingTool) throws ReportParseException; -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParserManager.java b/src/main/java/com/hp/application/automation/tools/results/parser/ReportParserManager.java deleted file mode 100644 index ee3db4b810..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/ReportParserManager.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hp.application.automation.tools.results.parser; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import com.hp.application.automation.tools.results.parser.antjunit.AntJUnitReportParserImpl; -import com.hp.application.automation.tools.results.parser.jenkinsjunit.JenkinsJUnitReportParserImpl; -import com.hp.application.automation.tools.results.parser.mavensurefire.MavenSureFireReportParserImpl; -import com.hp.application.automation.tools.results.parser.nunit.NUnitReportParserImpl; -import com.hp.application.automation.tools.results.parser.testngxml.TestNGXmlReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; - -public class ReportParserManager { - - private static ReportParserManager instance = new ReportParserManager(); - - List parserList = new ArrayList (); - - private ReportParserManager() { - parserList.add(new JenkinsJUnitReportParserImpl()); - parserList.add(new MavenSureFireReportParserImpl()); - parserList.add(new TestNGXmlReportParserImpl()); - parserList.add(new NUnitReportParserImpl()); - parserList.add(new AntJUnitReportParserImpl()); - } - - public static ReportParserManager getInstance() { - return instance; - } - - public List parseTestSets(String reportFilePath, String testingFramework, String testingTool) { - List testsets = null; - - for(ReportParser reportParser : parserList) { - try { - InputStream in = new FileInputStream(reportFilePath); - - testsets = reportParser.parseTestSets(in, testingFramework, testingTool); - break; - } catch (Exception e) { - - e.printStackTrace(); - - } - } - - return testsets; - } - - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java deleted file mode 100644 index e1b82f708c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.hp.application.automation.tools.results.parser.antjunit; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import com.hp.application.automation.tools.results.parser.ReportParseException; -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.parser.util.ParserUtil; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; - -public class AntJUnitReportParserImpl implements ReportParser { - - public List parseTestSets(InputStream reportInputStream, - String testingFramework, String testingTool) throws ReportParseException { - - try { - return parseTestSetsFromAntJUnitReport(reportInputStream, testingFramework, testingTool); - } catch (Exception e) { - - e.printStackTrace(); - throw new ReportParseException(); - } - } - - private Testsuites parseFromAntJUnitReport(InputStream reportInputStream) throws JAXBException { - JAXBContext jaxbContext = JAXBContext.newInstance(Testsuites.class); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - return (Testsuites)unmarshaller.unmarshal(reportInputStream); - } - - private AlmTest createExternalTestForAntJUnit(Testcase tc, String testingFramework, String testingTool) { - - return ParserUtil.createExternalTest(tc.getClassname(), tc.getName(), testingFramework, testingTool); - } - - private String getRunDetail(Testcase tc){ - String detail = ParserUtil.marshallerObject(Testcase.class, tc); - return Base64Encoder.encode(detail.getBytes()); - } - - - private ArrayList parseTestSetsFromAntJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { - Testsuites testsuites = parseFromAntJUnitReport(reportInputStream); - - ArrayList testSets = new ArrayList(); - - for(Testsuite ts : testsuites.getTestsuite()) { - AlmTestSet testSet = new AlmTestSetImpl(); - testSet.setFieldValue(AlmTestSet.TESTSET_NAME, ParserUtil.replaceInvalidCharsForTestSetName(ts.getName())); - testSet.setFieldValue(AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); - testSets.add(testSet); - - for (Testcase tc: ts.getTestcase()) { - AlmTestInstance testInstance = new AlmTestInstanceImpl(); - testInstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); - testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); - - AlmTest test = createExternalTestForAntJUnit(tc, testingFramework, testingTool); - testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); - - AlmRun run = ParserUtil.createRun(getRunStatus(tc), - ts.getTimestamp(), - tc.getTime(), - getRunDetail (tc)); - testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); - } - } - - return testSets; - } - - private String getRunStatus(Testcase testcase){ - - - if(testcase.getError().size()>0) { - return IAlmConsts.IStatuses.FAILED; - } - if(testcase.getFailure().size()>0) { - return IAlmConsts.IStatuses.FAILED; - } - if(testcase.getStatus() == null) { - return IAlmConsts.IStatuses.PASSED; - } - - String status = testcase.getStatus(); - if(status != null ){ - status = status.trim(); - if (status.length()>0){ - return status; - } else { - return IAlmConsts.IStatuses.PASSED; - } - } else { - return IAlmConsts.IStatuses.PASSED; - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Error.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Error.java deleted file mode 100644 index 71839b418f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Error.java +++ /dev/null @@ -1,123 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "error") -public class Error { - - @XmlValue - protected String content; - @XmlAttribute(name = "type") - protected String type; - @XmlAttribute(name = "message") - protected String message; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Failure.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Failure.java deleted file mode 100644 index fa9679b5e1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Failure.java +++ /dev/null @@ -1,123 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "failure") -public class Failure { - - @XmlValue - protected String content; - @XmlAttribute(name = "type") - protected String type; - @XmlAttribute(name = "message") - protected String message; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/ObjectFactory.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/ObjectFactory.java deleted file mode 100644 index 2f9d3caa1b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/ObjectFactory.java +++ /dev/null @@ -1,128 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the generated package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _SystemOut_QNAME = new QName("", "system-out"); - private final static QName _Skipped_QNAME = new QName("", "skipped"); - private final static QName _SystemErr_QNAME = new QName("", "system-err"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link Failure } - * - */ - public Failure createFailure() { - return new Failure(); - } - - /** - * Create an instance of {@link Testsuites } - * - */ - public Testsuites createTestsuites() { - return new Testsuites(); - } - - /** - * Create an instance of {@link Testsuite } - * - */ - public Testsuite createTestsuite() { - return new Testsuite(); - } - - /** - * Create an instance of {@link Properties } - * - */ - public Properties createProperties() { - return new Properties(); - } - - /** - * Create an instance of {@link Property } - * - */ - public Property createProperty() { - return new Property(); - } - - /** - * Create an instance of {@link Testcase } - * - */ - public Testcase createTestcase() { - return new Testcase(); - } - - /** - * Create an instance of {@link Error } - * - */ - public Error createError() { - return new Error(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "system-out") - public JAXBElement createSystemOut(String value) { - return new JAXBElement(_SystemOut_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "skipped") - public JAXBElement createSkipped(String value) { - return new JAXBElement(_Skipped_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "system-err") - public JAXBElement createSystemErr(String value) { - return new JAXBElement(_SystemErr_QNAME, String.class, null, value); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Properties.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Properties.java deleted file mode 100644 index eec834a934..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Properties.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}property" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "property" -}) -@XmlRootElement(name = "properties") -public class Properties { - - @XmlElement(required = true) - protected List property; - - /** - * Gets the value of the property property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the property property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getProperty().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Property } - * - * - */ - public List getProperty() { - if (property == null) { - property = new ArrayList(); - } - return this.property; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Property.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Property.java deleted file mode 100644 index 51627633f4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Property.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "property") -public class Property { - - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "value", required = true) - protected String value; - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(String value) { - this.value = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testcase.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testcase.java deleted file mode 100644 index 3de4cc2b55..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testcase.java +++ /dev/null @@ -1,338 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}skipped" minOccurs="0"/>
- *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "skipped", - "error", - "failure", - "systemOut", - "systemErr" -}) -@XmlRootElement(name = "testcase") -public class Testcase { - - protected String skipped; - protected List error; - protected List failure; - @XmlElement(name = "system-out") - protected List systemOut; - @XmlElement(name = "system-err") - protected List systemErr; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "assertions") - protected String assertions; - @XmlAttribute(name = "time") - protected String time; - @XmlAttribute(name = "classname") - protected String classname; - @XmlAttribute(name = "status") - protected String status; - - /** - * Gets the value of the skipped property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the error property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the error property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getError().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Error } - * - * - */ - public List getError() { - if (error == null) { - error = new ArrayList(); - } - return this.error; - } - - /** - * Gets the value of the failure property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the failure property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getFailure().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Failure } - * - * - */ - public List getFailure() { - if (failure == null) { - failure = new ArrayList(); - } - return this.failure; - } - - /** - * Gets the value of the systemOut property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the systemOut property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getSystemOut().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link String } - * - * - */ - public List getSystemOut() { - if (systemOut == null) { - systemOut = new ArrayList(); - } - return this.systemOut; - } - - /** - * Gets the value of the systemErr property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the systemErr property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getSystemErr().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link String } - * - * - */ - public List getSystemErr() { - if (systemErr == null) { - systemErr = new ArrayList(); - } - return this.systemErr; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the assertions property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAssertions() { - return assertions; - } - - /** - * Sets the value of the assertions property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAssertions(String value) { - this.assertions = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the classname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getClassname() { - return classname; - } - - /** - * Sets the value of the classname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setClassname(String value) { - this.classname = value; - } - - /** - * Gets the value of the status property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuite.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuite.java deleted file mode 100644 index 29da667f77..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuite.java +++ /dev/null @@ -1,458 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}properties" minOccurs="0"/>
- *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" minOccurs="0"/>
- *         <element ref="{}system-err" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "properties", - "testcase", - "systemOut", - "systemErr" -}) -@XmlRootElement(name = "testsuite") -public class Testsuite { - - protected Properties properties; - protected List testcase; - @XmlElement(name = "system-out") - protected String systemOut; - @XmlElement(name = "system-err") - protected String systemErr; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "tests", required = true) - protected String tests; - @XmlAttribute(name = "failures") - protected String failures; - @XmlAttribute(name = "errors") - protected String errors; - @XmlAttribute(name = "time") - protected String time; - @XmlAttribute(name = "disabled") - protected String disabled; - @XmlAttribute(name = "skipped") - protected String skipped; - @XmlAttribute(name = "timestamp") - protected String timestamp; - @XmlAttribute(name = "hostname") - protected String hostname; - @XmlAttribute(name = "id") - protected String id; - @XmlAttribute(name = "package") - protected String _package; - - /** - * Gets the value of the properties property. - * - * @return - * possible object is - * {@link Properties } - * - */ - public Properties getProperties() { - return properties; - } - - /** - * Sets the value of the properties property. - * - * @param value - * allowed object is - * {@link Properties } - * - */ - public void setProperties(Properties value) { - this.properties = value; - } - - /** - * Gets the value of the testcase property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testcase property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestcase().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Testcase } - * - * - */ - public List getTestcase() { - if (testcase == null) { - testcase = new ArrayList(); - } - return this.testcase; - } - - /** - * Gets the value of the systemOut property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSystemOut() { - return systemOut; - } - - /** - * Sets the value of the systemOut property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSystemOut(String value) { - this.systemOut = value; - } - - /** - * Gets the value of the systemErr property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSystemErr() { - return systemErr; - } - - /** - * Sets the value of the systemErr property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSystemErr(String value) { - this.systemErr = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the tests property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTests() { - return tests; - } - - /** - * Sets the value of the tests property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTests(String value) { - this.tests = value; - } - - /** - * Gets the value of the failures property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFailures(String value) { - this.failures = value; - } - - /** - * Gets the value of the errors property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getErrors() { - return errors; - } - - /** - * Sets the value of the errors property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setErrors(String value) { - this.errors = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the disabled property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDisabled() { - return disabled; - } - - /** - * Sets the value of the disabled property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDisabled(String value) { - this.disabled = value; - } - - /** - * Gets the value of the skipped property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the timestamp property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimestamp() { - return timestamp; - } - - /** - * Sets the value of the timestamp property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimestamp(String value) { - this.timestamp = value; - } - - /** - * Gets the value of the hostname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getHostname() { - return hostname; - } - - /** - * Sets the value of the hostname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setHostname(String value) { - this.hostname = value; - } - - /** - * Gets the value of the id property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the package property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getPackage() { - return _package; - } - - /** - * Sets the value of the package property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setPackage(String value) { - this._package = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuites.java b/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuites.java deleted file mode 100644 index 170401c953..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/antjunit/Testsuites.java +++ /dev/null @@ -1,239 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.01.26 at 05:00:04 PM CST -// - - -package com.hp.application.automation.tools.results.parser.antjunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}testsuite" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="tests" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "testsuite" -}) -@XmlRootElement(name = "testsuites") -public class Testsuites { - - protected List testsuite; - @XmlAttribute(name = "name") - protected String name; - @XmlAttribute(name = "time") - protected String time; - @XmlAttribute(name = "tests") - protected String tests; - @XmlAttribute(name = "failures") - protected String failures; - @XmlAttribute(name = "disabled") - protected String disabled; - @XmlAttribute(name = "errors") - protected String errors; - - /** - * Gets the value of the testsuite property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testsuite property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestsuite().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Testsuite } - * - * - */ - public List getTestsuite() { - if (testsuite == null) { - testsuite = new ArrayList(); - } - return this.testsuite; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the tests property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTests() { - return tests; - } - - /** - * Sets the value of the tests property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTests(String value) { - this.tests = value; - } - - /** - * Gets the value of the failures property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFailures(String value) { - this.failures = value; - } - - /** - * Gets the value of the disabled property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDisabled() { - return disabled; - } - - /** - * Sets the value of the disabled property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDisabled(String value) { - this.disabled = value; - } - - /** - * Gets the value of the errors property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getErrors() { - return errors; - } - - /** - * Sets the value of the errors property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setErrors(String value) { - this.errors = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java b/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java deleted file mode 100644 index 2d9d86f190..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.hp.application.automation.tools.results.parser.jenkinsjunit; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import com.hp.application.automation.tools.results.parser.ReportParseException; -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.parser.util.ParserUtil; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; - -public class JenkinsJUnitReportParserImpl implements ReportParser { - - public List parseTestSets(InputStream reportInputStream, - String testingFramework, String testingTool) throws ReportParseException { - - try { - return parseTestSetsFromJenkinsPluginJUnitReport(reportInputStream, testingFramework, testingTool); - } catch (Exception e) { - - //e.printStackTrace(); - throw new ReportParseException(); - } - } - - private Result parseFromJenkinsPluginJUnitReport(InputStream reportInputStream) throws JAXBException { - JAXBContext jaxbContext = JAXBContext.newInstance(Result.class); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - return (Result)unmarshaller.unmarshal(reportInputStream); - } - - private AlmTest createExternalTestForJenkinsPluginJUnit(Result.Suites.Suite.Cases.Case c, String testingFramework, String testingTool) { - - return ParserUtil.createExternalTest(c.getClassName(), c.getTestName(), testingFramework, testingTool); - } - - private String getRunDetail(Result.Suites.Suite.Cases.Case c){ - String detail = ParserUtil.marshallerObject(Result.Suites.Suite.Cases.Case.class, c); - return Base64Encoder.encode(detail.getBytes()); - } - - private ArrayList parseTestSetsFromJenkinsPluginJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { - Result result = parseFromJenkinsPluginJUnitReport(reportInputStream); - ArrayList testSets = new ArrayList(); - - for (Result.Suites suites : result.getSuites()) { - for (Result.Suites.Suite suite : suites.getSuite()) { - AlmTestSet testSet = new AlmTestSetImpl(); - testSet.setFieldValue(AlmTestSet.TESTSET_NAME, ParserUtil.replaceInvalidCharsForTestSetName(suite.getName())); - testSet.setFieldValue(AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); - testSets.add(testSet); - - for (Result.Suites.Suite.Cases cases : suite.getCases()) { - for (Result.Suites.Suite.Cases.Case c : cases.getCase()){ - AlmTestInstance testInstance = new AlmTestInstanceImpl(); - testInstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); - testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); - - AlmTest test = createExternalTestForJenkinsPluginJUnit(c, testingFramework, testingTool); - testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); - - AlmRun run = ParserUtil.createRun(getRunStatus(c), - suite.getTimestamp(), - c.getDuration(), - getRunDetail (c)); - testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); - } - } - } - } - - return testSets; - } - - private String getRunStatus(Result.Suites.Suite.Cases.Case c) { - if (c.getSkipped() != null && c.getSkipped().equals("true")) { - return IAlmConsts.IStatuses.NO_RUN; - } - - if(c.getErrorStackTrace() != null && c.getErrorStackTrace().length() >0) { - return IAlmConsts.IStatuses.FAILED; - } - - if(c.getErrorDetails() != null && c.getErrorDetails().length() >0) { - return IAlmConsts.IStatuses.FAILED; - } - - if (c.getFailedSince() != null && c.getFailedSince().equals("0")) { - return IAlmConsts.IStatuses.PASSED; - } - - return IAlmConsts.IStatuses.FAILED; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java b/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java deleted file mode 100644 index 632ac3b2e5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.23 at 04:30:11 PM CST -// - - -package com.hp.application.automation.tools.results.parser.jenkinsjunit; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <choice maxOccurs="unbounded" minOccurs="0">
- *         <element ref="{}result"/>
- *       </choice>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "result" -}) -@XmlRootElement(name = "NewDataSet") -public class NewDataSet { - - protected List result; - - /** - * Gets the value of the result property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the result property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getResult().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Result } - * - * - */ - public List getResult() { - if (result == null) { - result = new ArrayList(); - } - return this.result; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java b/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java deleted file mode 100644 index 24b8b02b7c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.hp.application.automation.tools.results.parser.jenkinsjunit; -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.23 at 04:30:11 PM CST -// - - - - -import javax.xml.bind.annotation.XmlRegistry; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the com.hp.alm.qc.qualitymanagement.entities.reportparsing.jenkinsjunitreport package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.hp.alm.qc.qualitymanagement.entities.reportparsing.jenkinsjunitreport - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link Result } - * - */ - public Result createResult() { - return new Result(); - } - - /** - * Create an instance of {@link Result.Suites } - * - */ - public Result.Suites createResultSuites() { - return new Result.Suites(); - } - - /** - * Create an instance of {@link Result.Suites.Suite } - * - */ - public Result.Suites.Suite createResultSuitesSuite() { - return new Result.Suites.Suite(); - } - - /** - * Create an instance of {@link Result.Suites.Suite.Cases } - * - */ - public Result.Suites.Suite.Cases createResultSuitesSuiteCases() { - return new Result.Suites.Suite.Cases(); - } - - /** - * Create an instance of {@link NewDataSet } - * - */ - public NewDataSet createNewDataSet() { - return new NewDataSet(); - } - - /** - * Create an instance of {@link Result.Suites.Suite.Cases.Case } - * - */ - public Result.Suites.Suite.Cases.Case createResultSuitesSuiteCasesCase() { - return new Result.Suites.Suite.Cases.Case(); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Error.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Error.java deleted file mode 100644 index d1f9e56d43..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Error.java +++ /dev/null @@ -1,123 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "error") -public class Error { - - @XmlValue - protected String content; - @XmlAttribute(name = "type") - protected String type; - @XmlAttribute(name = "message") - protected String message; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Failure.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Failure.java deleted file mode 100644 index a9f9251f88..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Failure.java +++ /dev/null @@ -1,123 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "failure") -public class Failure { - - @XmlValue - protected String content; - @XmlAttribute(name = "type") - protected String type; - @XmlAttribute(name = "message") - protected String message; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java deleted file mode 100644 index 04ab1b2fa1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import com.hp.application.automation.tools.results.parser.ReportParseException; -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.parser.util.ParserUtil; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; - -public class MavenSureFireReportParserImpl implements ReportParser { - - public List parseTestSets(InputStream reportInputStream, - String testingFramework, String testingTool) throws ReportParseException { - - try { - return parseTestSetsFromMavenSurefirePluginJUnitReport(reportInputStream, testingFramework, testingTool); - } catch (Exception e) { - - throw new ReportParseException(); - } - } - - private Testsuite parseFromMavenSurefirePluginJUnitReport(InputStream reportInputStream) throws JAXBException { - JAXBContext jaxbContext = JAXBContext.newInstance(Testsuite.class); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - return (Testsuite)unmarshaller.unmarshal(reportInputStream); - } - - private AlmTest createExternalTestForMavenSurefirePluginJUnit(Testcase tc, String testingFramework, String testingTool) { - - return ParserUtil.createExternalTest(tc.getClassname(), tc.getName(), testingFramework, testingTool); - } - - private ArrayList parseTestSetsFromMavenSurefirePluginJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { - Testsuite testsuite = parseFromMavenSurefirePluginJUnitReport(reportInputStream); - ArrayList testSets = new ArrayList(); - - AlmTestSet testSet = new AlmTestSetImpl(); - testSet.setFieldValue( AlmTestSet.TESTSET_NAME, testsuite.getName()); - testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); - testSets.add(testSet); - - for (Testcase tc: testsuite.getTestcase()) { - AlmTestInstance testInstance = new AlmTestInstanceImpl(); - testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); - testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); - - AlmTest test = createExternalTestForMavenSurefirePluginJUnit(tc, testingFramework, testingTool); - testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); - - AlmRun run = ParserUtil.createRun(getRunStatus(tc), - testsuite.getTimestamp(), - tc.getTime(), - getRunDetail(tc)); - testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); - } - - return testSets; - } - - private String getRunStatus(Testcase testcase) { - if(testcase.getError().size()>0) { - return IAlmConsts.IStatuses.FAILED; - } - if(testcase.getFailure().size()>0) { - return IAlmConsts.IStatuses.FAILED; - } - if(testcase.getStatus() == null) { - return IAlmConsts.IStatuses.PASSED; - } - - String status = testcase.getStatus(); - if(status != null ){ - status = status.trim(); - if (status.length()>0){ - return status; - } else { - return IAlmConsts.IStatuses.PASSED; - } - } else { - return IAlmConsts.IStatuses.PASSED; - } - } - - private String getRunDetail(Testcase testcase){ - String detail = ParserUtil.marshallerObject(Testcase.class, testcase); - return Base64Encoder.encode(detail.getBytes()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java deleted file mode 100644 index 957977852c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java +++ /dev/null @@ -1,120 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the com.hp.alm.qc.qualitymanagement.entities.reportparsing.mavensurefirereport package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _SystemOut_QNAME = new QName("", "system-out"); - private final static QName _Skipped_QNAME = new QName("", "skipped"); - private final static QName _SystemErr_QNAME = new QName("", "system-err"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.hp.alm.qc.qualitymanagement.entities.reportparsing.mavensurefirereport - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link Failure } - * - */ - public Failure createFailure() { - return new Failure(); - } - - /** - * Create an instance of {@link Error } - * - */ - public Error createError() { - return new Error(); - } - - /** - * Create an instance of {@link Property } - * - */ - public Property createProperty() { - return new Property(); - } - - /** - * Create an instance of {@link Properties } - * - */ - public Properties createProperties() { - return new Properties(); - } - - /** - * Create an instance of {@link Testsuite } - * - */ - public Testsuite createTestsuite() { - return new Testsuite(); - } - - /** - * Create an instance of {@link Testcase } - * - */ - public Testcase createTestcase() { - return new Testcase(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "system-out") - public JAXBElement createSystemOut(String value) { - return new JAXBElement(_SystemOut_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "skipped") - public JAXBElement createSkipped(String value) { - return new JAXBElement(_Skipped_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "system-err") - public JAXBElement createSystemErr(String value) { - return new JAXBElement(_SystemErr_QNAME, String.class, null, value); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Properties.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Properties.java deleted file mode 100644 index 8d6dd178ff..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Properties.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}property" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "property" -}) -@XmlRootElement(name = "properties") -public class Properties { - - @XmlElement(required = true) - protected List property; - - /** - * Gets the value of the property property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the property property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getProperty().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Property } - * - * - */ - public List getProperty() { - if (property == null) { - property = new ArrayList(); - } - return this.property; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Property.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Property.java deleted file mode 100644 index dd535c7484..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Property.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "property") -public class Property { - - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "value", required = true) - protected String value; - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(String value) { - this.value = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testcase.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testcase.java deleted file mode 100644 index 864ff0f5b0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testcase.java +++ /dev/null @@ -1,339 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}skipped" minOccurs="0"/>
- *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ - -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "skipped", - "error", - "failure", - "systemOut", - "systemErr" -}) -@XmlRootElement(name = "testcase") -public class Testcase { - - protected String skipped; - protected List error; - protected List failure; - @XmlElement(name = "system-out") - protected List systemOut; - @XmlElement(name = "system-err") - protected List systemErr; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "assertions") - protected String assertions; - @XmlAttribute(name = "time") - protected String time; - @XmlAttribute(name = "classname") - protected String classname; - @XmlAttribute(name = "status") - protected String status; - - /** - * Gets the value of the skipped property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the error property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the error property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getError().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Error } - * - * - */ - public List getError() { - if (error == null) { - error = new ArrayList(); - } - return this.error; - } - - /** - * Gets the value of the failure property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the failure property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getFailure().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Failure } - * - * - */ - public List getFailure() { - if (failure == null) { - failure = new ArrayList(); - } - return this.failure; - } - - /** - * Gets the value of the systemOut property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the systemOut property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getSystemOut().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link String } - * - * - */ - public List getSystemOut() { - if (systemOut == null) { - systemOut = new ArrayList(); - } - return this.systemOut; - } - - /** - * Gets the value of the systemErr property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the systemErr property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getSystemErr().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link String } - * - * - */ - public List getSystemErr() { - if (systemErr == null) { - systemErr = new ArrayList(); - } - return this.systemErr; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the assertions property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAssertions() { - return assertions; - } - - /** - * Sets the value of the assertions property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAssertions(String value) { - this.assertions = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the classname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getClassname() { - return classname; - } - - /** - * Sets the value of the classname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setClassname(String value) { - this.classname = value; - } - - /** - * Gets the value of the status property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testsuite.java b/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testsuite.java deleted file mode 100644 index cc62944327..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/mavensurefire/Testsuite.java +++ /dev/null @@ -1,458 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.03.25 at 02:54:53 PM CST -// - - -package com.hp.application.automation.tools.results.parser.mavensurefire; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}properties" minOccurs="0"/>
- *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" minOccurs="0"/>
- *         <element ref="{}system-err" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "properties", - "testcase", - "systemOut", - "systemErr" -}) -@XmlRootElement(name = "testsuite") -public class Testsuite { - - protected Properties properties; - protected List testcase; - @XmlElement(name = "system-out") - protected String systemOut; - @XmlElement(name = "system-err") - protected String systemErr; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "tests", required = true) - protected String tests; - @XmlAttribute(name = "failures") - protected String failures; - @XmlAttribute(name = "errors") - protected String errors; - @XmlAttribute(name = "time") - protected String time; - @XmlAttribute(name = "disabled") - protected String disabled; - @XmlAttribute(name = "skipped") - protected String skipped; - @XmlAttribute(name = "timestamp") - protected String timestamp; - @XmlAttribute(name = "hostname") - protected String hostname; - @XmlAttribute(name = "id") - protected String id; - @XmlAttribute(name = "package") - protected String _package; - - /** - * Gets the value of the properties property. - * - * @return - * possible object is - * {@link Properties } - * - */ - public Properties getProperties() { - return properties; - } - - /** - * Sets the value of the properties property. - * - * @param value - * allowed object is - * {@link Properties } - * - */ - public void setProperties(Properties value) { - this.properties = value; - } - - /** - * Gets the value of the testcase property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testcase property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestcase().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Testcase } - * - * - */ - public List getTestcase() { - if (testcase == null) { - testcase = new ArrayList(); - } - return this.testcase; - } - - /** - * Gets the value of the systemOut property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSystemOut() { - return systemOut; - } - - /** - * Sets the value of the systemOut property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSystemOut(String value) { - this.systemOut = value; - } - - /** - * Gets the value of the systemErr property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSystemErr() { - return systemErr; - } - - /** - * Sets the value of the systemErr property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSystemErr(String value) { - this.systemErr = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the tests property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTests() { - return tests; - } - - /** - * Sets the value of the tests property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTests(String value) { - this.tests = value; - } - - /** - * Gets the value of the failures property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFailures(String value) { - this.failures = value; - } - - /** - * Gets the value of the errors property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getErrors() { - return errors; - } - - /** - * Sets the value of the errors property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setErrors(String value) { - this.errors = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the disabled property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDisabled() { - return disabled; - } - - /** - * Sets the value of the disabled property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDisabled(String value) { - this.disabled = value; - } - - /** - * Gets the value of the skipped property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the timestamp property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimestamp() { - return timestamp; - } - - /** - * Sets the value of the timestamp property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimestamp(String value) { - this.timestamp = value; - } - - /** - * Gets the value of the hostname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getHostname() { - return hostname; - } - - /** - * Sets the value of the hostname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setHostname(String value) { - this.hostname = value; - } - - /** - * Gets the value of the id property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the package property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getPackage() { - return _package; - } - - /** - * Sets the value of the package property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setPackage(String value) { - this._package = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoriesType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoriesType.java deleted file mode 100644 index d03b942921..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoriesType.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for categoriesType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="categoriesType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="category" type="{}categoryType" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "categoriesType", propOrder = { - "category" -}) -public class CategoriesType { - - @XmlElement(required = true) - protected List category; - - /** - * Gets the value of the category property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the category property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getCategory().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link CategoryType } - * - * - */ - public List getCategory() { - if (category == null) { - category = new ArrayList(); - } - return this.category; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoryType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoryType.java deleted file mode 100644 index d5edbfbc5f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/CategoryType.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for categoryType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="categoryType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "categoryType") -public class CategoryType { - - @XmlAttribute(name = "name", required = true) - protected String name; - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/FailureType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/FailureType.java deleted file mode 100644 index c34ba86b99..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/FailureType.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for failureType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="failureType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}message"/>
- *         <element ref="{}stack-trace"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "failureType", propOrder = { - "message", - "stackTrace" -}) -public class FailureType { - - @XmlElement(required = true) - protected String message; - @XmlElement(name = "stack-trace", required = true) - protected String stackTrace; - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - - /** - * Gets the value of the stackTrace property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStackTrace() { - return stackTrace; - } - - /** - * Sets the value of the stackTrace property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStackTrace(String value) { - this.stackTrace = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java deleted file mode 100644 index 92b5f95f0f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java +++ /dev/null @@ -1,269 +0,0 @@ -package com.hp.application.automation.tools.results.parser.nunit; - -import java.io.InputStream; -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import com.hp.application.automation.tools.results.parser.ReportParseException; -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.parser.util.ParserUtil; -import com.hp.application.automation.tools.results.parser.util.TimeUtil; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; - -public class NUnitReportParserImpl implements ReportParser { - - public List parseTestSets(InputStream reportInputStream, - String testingFramework, String testingTool) throws ReportParseException { - - try { - return parseTestSetFromNUnitReport(reportInputStream, testingFramework, testingTool); - } catch (Throwable e) { - throw new ReportParseException(); - } - } - - private ResultType parseFromNUnitReport(InputStream reportInputStream) throws JAXBException { - JAXBContext jaxbContext = JAXBContext.newInstance(ResultType.class); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - return (ResultType)unmarshaller.unmarshal(reportInputStream); - } - - private AlmTest createExternalTestForNUnitReport(TestCaseType testcase, String testingFramework, String testingTool) { - - String temp = testcase.getName(); - String methodName = ""; - String className = ""; - int indexMethod = temp.lastIndexOf("."); - if(indexMethod >= 0) { - methodName = temp.substring(indexMethod+1); - className = temp.substring(0, indexMethod); - } - return ParserUtil.createExternalTest(className, methodName, testingFramework, testingTool); - } - - private void createTestSetAndTest(TestSuiteType testSuite, - String uplevelSuiteName, - String execDate, - String execTime, - List testsets, - String testingFramework, - String testingTool) { - ResultsType resultsOfSuite = testSuite.getResults(); - List testcases = resultsOfSuite.getTestCase(); - List testSuites = resultsOfSuite.getTestSuite(); - - - String currentSuiteName = testSuite.getName(); - int index = currentSuiteName.lastIndexOf("\\"); - if(index >=0 ) { - currentSuiteName = currentSuiteName.substring(index+1); - } - - String testsetName = currentSuiteName; - - if(uplevelSuiteName!=null && uplevelSuiteName.length() >0) { - testsetName = uplevelSuiteName+"_"+currentSuiteName; - } - - if(testcases != null && testcases.size() >0) { - AlmTestSet testSet = new AlmTestSetImpl(); - testSet.setFieldValue( AlmTestSet.TESTSET_NAME,testsetName ); - testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); - testsets.add(testSet); - - for(TestCaseType testcase: testcases) { - AlmTestInstance testInstance = new AlmTestInstanceImpl(); - testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); - testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); - - AlmTest test = createExternalTestForNUnitReport( testcase, testingFramework, testingTool); - testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); - - String execDateTime = ""; - if(execDate != null && execTime != null){ - execDateTime = execDate +" " +execTime; - } - AlmRun run = ParserUtil.createRun(getRunStatus(testcase), - execDateTime, - String.valueOf(testcase.getTime()), - getRunDetail(testcase)); - testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); - } - } - - for(TestSuiteType s: testSuites){ - createTestSetAndTest(s, testsetName, execDate, execTime, testsets, testingFramework, testingTool); - } - } - - private Date getDate( int dateFormat, String dateStr) { - - DateFormat df = DateFormat.getDateInstance(dateFormat); - Date date = null; - try { - date = df.parse(dateStr); - return date; - } catch( Exception e) { - - } - return null; - } - - private Date getTime( int timeFormat, String dateStr) { - - DateFormat df = DateFormat.getTimeInstance(timeFormat); - Date date = null; - try { - date = df.parse(dateStr); - return date; - } catch( Exception e) { - - } - return null; - } - private static String supportedDateFormat [] = { - "yyyy-MM-dd", - "yyyy/MM/dd" - }; - private static String supportedTimeFormat [] = { - "HH:mm:ss", - "hh:mm:ss" - }; - private Date getDateBySupportedDateFormat(String dateStr) { - - for(String format : supportedDateFormat) { - try { - Date date = TimeUtil.getDateFormatter(format).parse(dateStr); - return date; - }catch (Exception e) { - - } - } - return null; - } - - private Date getTimeBySupportedTimeFormat(String timeStr) { - - for(String format : supportedTimeFormat) { - try { - Date date = TimeUtil.getDateFormatter(format).parse(timeStr); - return date; - }catch (Exception e) { - - } - } - return null; - } - - private String convertDateString(String dateStr) { - Date date = null; - date = getDate(DateFormat.LONG, dateStr); - if(date == null) { - date = getDate(DateFormat.MEDIUM, dateStr); - } - - if(date == null) { - date = getDate(DateFormat.SHORT, dateStr); - } - - if(date == null) { - date = getDate(DateFormat.FULL, dateStr); - } - - if(date == null) { - date = getDateBySupportedDateFormat(dateStr); - } - - if(date != null) { - return TimeUtil.getDateFormatter().format(date); - } else { - return null; - } - } - - private String convertTimeString(String timeStr) { - Date time = null; - time = getTime(DateFormat.LONG, timeStr); - - if(time == null) { - time = getTime(DateFormat.MEDIUM, timeStr); - } - - if(time == null) { - time = getTime(DateFormat.SHORT, timeStr); - } - - if(time == null) { - time = getTime(DateFormat.FULL, timeStr); - } - - if(time == null) { - time = getTimeBySupportedTimeFormat(timeStr); - } - - if(time != null) { - return TimeUtil.getTimeFormatter().format(time); - } else { - return null; - } - } - - - private ArrayList parseTestSetFromNUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { - - ResultType results = parseFromNUnitReport(reportInputStream); - - TestSuiteType testSuite = results.getTestSuite(); - String dateStr = results.getDate(); - String timeStr = results.getTime(); - String convertedDate = convertDateString(dateStr); - String convertedTime = convertTimeString(timeStr); - - if(convertedDate == null || convertedTime == null) { - Date executeDate = new Date(System.currentTimeMillis()); - convertedDate = TimeUtil.dateToString(executeDate); - convertedTime = TimeUtil.timeToString(executeDate); - } - - ArrayList testSets = new ArrayList(); - createTestSetAndTest(testSuite, "", convertedDate, convertedTime, testSets, testingFramework, testingTool); - return testSets; - } - - private String getRunStatus(TestCaseType testcase) { - String executed = testcase.getExecuted(); - if("True".equalsIgnoreCase(executed)) { - String success = testcase.getSuccess(); - - if("True".equalsIgnoreCase(success)) { - return IAlmConsts.IStatuses.PASSED; - } else { - return IAlmConsts.IStatuses.FAILED; - } - } else { - return IAlmConsts.IStatuses.NO_RUN; - } - } - - private String getRunDetail(TestCaseType testcase){ - String detail = ParserUtil.marshallerObject(TestCaseType.class, testcase); - return Base64Encoder.encode(detail.getBytes()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ObjectFactory.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ObjectFactory.java deleted file mode 100644 index f22e2b501e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ObjectFactory.java +++ /dev/null @@ -1,136 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the generated package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Message_QNAME = new QName("", "message"); - private final static QName _TestResults_QNAME = new QName("", "test-results"); - private final static QName _StackTrace_QNAME = new QName("", "stack-trace"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link ResultType } - * - */ - public ResultType createResultType() { - return new ResultType(); - } - - /** - * Create an instance of {@link FailureType } - * - */ - public FailureType createFailureType() { - return new FailureType(); - } - - /** - * Create an instance of {@link TestSuiteType } - * - */ - public TestSuiteType createTestSuiteType() { - return new TestSuiteType(); - } - - /** - * Create an instance of {@link ReasonType } - * - */ - public ReasonType createReasonType() { - return new ReasonType(); - } - - /** - * Create an instance of {@link TestCaseType } - * - */ - public TestCaseType createTestCaseType() { - return new TestCaseType(); - } - - /** - * Create an instance of {@link CategoriesType } - * - */ - public CategoriesType createCategoriesType() { - return new CategoriesType(); - } - - /** - * Create an instance of {@link CategoryType } - * - */ - public CategoryType createCategoryType() { - return new CategoryType(); - } - - /** - * Create an instance of {@link ResultsType } - * - */ - public ResultsType createResultsType() { - return new ResultsType(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "message") - public JAXBElement createMessage(String value) { - return new JAXBElement(_Message_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link ResultType }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "test-results") - public JAXBElement createTestResults(ResultType value) { - return new JAXBElement(_TestResults_QNAME, ResultType.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stack-trace") - public JAXBElement createStackTrace(String value) { - return new JAXBElement(_StackTrace_QNAME, String.class, null, value); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ReasonType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ReasonType.java deleted file mode 100644 index a38c63ac5f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ReasonType.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for reasonType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="reasonType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}message"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "reasonType", propOrder = { - "message" -}) -public class ReasonType { - - @XmlElement(required = true) - protected String message; - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultType.java deleted file mode 100644 index 160ea9a13e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultType.java +++ /dev/null @@ -1,235 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import java.math.BigDecimal; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for resultType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="resultType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="test-suite" type="{}test-suiteType"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="total" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
- *       <attribute name="failures" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
- *       <attribute name="not-run" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
- *       <attribute name="date" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlRootElement(name = "test-results") -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "resultType", propOrder = { - "testSuite" -}) -public class ResultType { - - @XmlElement(name = "test-suite", required = true) - protected TestSuiteType testSuite; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "total", required = true) - protected BigDecimal total; - @XmlAttribute(name = "failures", required = true) - protected BigDecimal failures; - @XmlAttribute(name = "not-run", required = true) - protected BigDecimal notRun; - @XmlAttribute(name = "date", required = true) - protected String date; - @XmlAttribute(name = "time", required = true) - protected String time; - - /** - * Gets the value of the testSuite property. - * - * @return - * possible object is - * {@link TestSuiteType } - * - */ - public TestSuiteType getTestSuite() { - return testSuite; - } - - /** - * Sets the value of the testSuite property. - * - * @param value - * allowed object is - * {@link TestSuiteType } - * - */ - public void setTestSuite(TestSuiteType value) { - this.testSuite = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the total property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getTotal() { - return total; - } - - /** - * Sets the value of the total property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setTotal(BigDecimal value) { - this.total = value; - } - - /** - * Gets the value of the failures property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setFailures(BigDecimal value) { - this.failures = value; - } - - /** - * Gets the value of the notRun property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getNotRun() { - return notRun; - } - - /** - * Sets the value of the notRun property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setNotRun(BigDecimal value) { - this.notRun = value; - } - - /** - * Gets the value of the date property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDate() { - return date; - } - - /** - * Sets the value of the date property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDate(String value) { - this.date = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultsType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultsType.java deleted file mode 100644 index 53db94e797..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/ResultsType.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for resultsType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="resultsType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <choice>
- *         <element name="test-suite" type="{}test-suiteType" maxOccurs="unbounded"/>
- *         <element name="test-case" type="{}test-caseType" maxOccurs="unbounded" minOccurs="0"/>
- *       </choice>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "resultsType", propOrder = { - "testSuite", - "testCase" -}) -public class ResultsType { - - @XmlElement(name = "test-suite") - protected List testSuite; - @XmlElement(name = "test-case") - protected List testCase; - - /** - * Gets the value of the testSuite property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testSuite property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestSuite().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link TestSuiteType } - * - * - */ - public List getTestSuite() { - if (testSuite == null) { - testSuite = new ArrayList(); - } - return this.testSuite; - } - - /** - * Gets the value of the testCase property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testCase property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestCase().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link TestCaseType } - * - * - */ - public List getTestCase() { - if (testCase == null) { - testCase = new ArrayList(); - } - return this.testCase; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestSuiteType.java b/src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestSuiteType.java deleted file mode 100644 index fe443b99d0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestSuiteType.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:45:43 AM CST -// - - -package com.hp.application.automation.tools.results.parser.nunit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for test-suiteType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="test-suiteType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="categories" type="{}categoriesType" minOccurs="0"/>
- *         <element name="results" type="{}resultsType"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="description" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="success" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="asserts" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "test-suiteType", propOrder = { - "categories", - "results" -}) -public class TestSuiteType { - - protected CategoriesType categories; - @XmlElement(required = true) - protected ResultsType results; - @XmlAttribute(name = "name", required = true) - protected String name; - @XmlAttribute(name = "description") - protected String description; - @XmlAttribute(name = "success", required = true) - protected String success; - @XmlAttribute(name = "time", required = true) - protected String time; - @XmlAttribute(name = "asserts") - protected String asserts; - - /** - * Gets the value of the categories property. - * - * @return - * possible object is - * {@link CategoriesType } - * - */ - public CategoriesType getCategories() { - return categories; - } - - /** - * Sets the value of the categories property. - * - * @param value - * allowed object is - * {@link CategoriesType } - * - */ - public void setCategories(CategoriesType value) { - this.categories = value; - } - - /** - * Gets the value of the results property. - * - * @return - * possible object is - * {@link ResultsType } - * - */ - public ResultsType getResults() { - return results; - } - - /** - * Sets the value of the results property. - * - * @param value - * allowed object is - * {@link ResultsType } - * - */ - public void setResults(ResultsType value) { - this.results = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the description property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDescription() { - return description; - } - - /** - * Sets the value of the description property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDescription(String value) { - this.description = value; - } - - /** - * Gets the value of the success property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSuccess() { - return success; - } - - /** - * Sets the value of the success property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSuccess(String value) { - this.success = value; - } - - /** - * Gets the value of the time property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the asserts property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAsserts() { - return asserts; - } - - /** - * Sets the value of the asserts property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAsserts(String value) { - this.asserts = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/NewDataSet.java b/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/NewDataSet.java deleted file mode 100644 index 031bc6a14e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/NewDataSet.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:25:36 AM CST -// - - -package com.hp.application.automation.tools.results.parser.testngxml; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <choice maxOccurs="unbounded" minOccurs="0">
- *         <element ref="{}testng-results"/>
- *       </choice>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "testngResults" -}) -@XmlRootElement(name = "NewDataSet") -public class NewDataSet { - - @XmlElement(name = "testng-results") - protected List testngResults; - - /** - * Gets the value of the testngResults property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the testngResults property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getTestngResults().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link TestngResults } - * - * - */ - public List getTestngResults() { - if (testngResults == null) { - testngResults = new ArrayList(); - } - return this.testngResults; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/ObjectFactory.java b/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/ObjectFactory.java deleted file mode 100644 index 1c0e7023c6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/ObjectFactory.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2015.05.13 at 09:25:36 AM CST -// - - -package com.hp.application.automation.tools.results.parser.testngxml; - -import javax.xml.bind.annotation.XmlRegistry; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the generated package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link TestngResults } - * - */ - public TestngResults createTestngResults() { - return new TestngResults(); - } - - /** - * Create an instance of {@link TestngResults.Suite } - * - */ - public TestngResults.Suite createTestngResultsSuite() { - return new TestngResults.Suite(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Test } - * - */ - public TestngResults.Suite.Test createTestngResultsSuiteTest() { - return new TestngResults.Suite.Test(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Test.Class } - * - */ - public TestngResults.Suite.Test.Class createTestngResultsSuiteTestClass() { - return new TestngResults.Suite.Test.Class(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Test.Class.TestMethod } - * - */ - public TestngResults.Suite.Test.Class.TestMethod createTestngResultsSuiteTestClassTestMethod() { - return new TestngResults.Suite.Test.Class.TestMethod(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Groups } - * - */ - public TestngResults.Suite.Groups createTestngResultsSuiteGroups() { - return new TestngResults.Suite.Groups(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Groups.Group } - * - */ - public TestngResults.Suite.Groups.Group createTestngResultsSuiteGroupsGroup() { - return new TestngResults.Suite.Groups.Group(); - } - - /** - * Create an instance of {@link NewDataSet } - * - */ - public NewDataSet createNewDataSet() { - return new NewDataSet(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Test.Class.TestMethod.Exception } - * - */ - public TestngResults.Suite.Test.Class.TestMethod.Exception createTestngResultsSuiteTestClassTestMethodException() { - return new TestngResults.Suite.Test.Class.TestMethod.Exception(); - } - - /** - * Create an instance of {@link TestngResults.Suite.Groups.Group.Method } - * - */ - public TestngResults.Suite.Groups.Group.Method createTestngResultsSuiteGroupsGroupMethod() { - return new TestngResults.Suite.Groups.Group.Method(); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java b/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java deleted file mode 100644 index ee5d1d13e3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.hp.application.automation.tools.results.parser.testngxml; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import com.hp.application.automation.tools.results.parser.ReportParseException; -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.parser.testngxml.TestngResults.Suite; -import com.hp.application.automation.tools.results.parser.testngxml.TestngResults.Suite.Test; -import com.hp.application.automation.tools.results.parser.testngxml.TestngResults.Suite.Test.Class.TestMethod; -import com.hp.application.automation.tools.results.parser.util.ParserUtil; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Base64Encoder; - -public class TestNGXmlReportParserImpl implements ReportParser { - - public List parseTestSets(InputStream reportInputStream, - String testingFramework, String testingTool) throws ReportParseException { - - try { - return parseTestSetFromTestNGXmlReport(reportInputStream, testingFramework, testingTool); - } catch (Throwable e) { - - throw new ReportParseException(); - } - } - - private TestngResults parseFromTestNGXmlReport(InputStream reportInputStream) throws JAXBException { - JAXBContext jaxbContext = JAXBContext.newInstance(TestngResults.class); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - return (TestngResults)unmarshaller.unmarshal(reportInputStream); - } - - private AlmTest createExternalTestForTestNGXmlReport(String className, String methodName, String testingFramework, String testingTool) { - - return ParserUtil.createExternalTest(className, methodName, testingFramework, testingTool); - } - - private ArrayList parseTestSetFromTestNGXmlReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { - - TestngResults testngresults = parseFromTestNGXmlReport(reportInputStream); - - ArrayList testSets = new ArrayList(); - for( Suite suite : testngresults.suite) { - AlmTestSet testSet = new AlmTestSetImpl(); - testSet.setFieldValue( AlmTestSet.TESTSET_NAME, suite.getName()); - testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); - testSets.add(testSet); - - - for (Test t: suite.getTest()) { - - for(TestngResults.Suite.Test.Class c: t.getClazz() ) { - - for(TestMethod tm : c.getTestMethod()) { - AlmTestInstance testInstance = new AlmTestInstanceImpl(); - testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); - testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); - - AlmTest test = createExternalTestForTestNGXmlReport( c.getName(), tm.getName(), testingFramework, testingTool); - testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); - - AlmRun run = ParserUtil.createRun(getRunStatus(tm), tm.getStartedAt(), String.valueOf(tm.getDurationMs()), getRunDetail(tm)); - testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); - } - } - } - } - return testSets; - } - - private String getRunStatus(TestMethod tm) { - String status = tm.getStatus(); - if(status != null && status.length()>0){ - status = status.trim(); - - if("PASS".equalsIgnoreCase(status)) { - return IAlmConsts.IStatuses.PASSED; - } else if ("FAIL".equalsIgnoreCase(status)) { - return IAlmConsts.IStatuses.FAILED; - } else { - return IAlmConsts.IStatuses.NO_RUN; - } - } else { - return IAlmConsts.IStatuses.NO_RUN; - } - } - - private String getRunDetail(TestMethod tm){ - String detail = ParserUtil.marshallerObject(TestMethod.class, tm); - return Base64Encoder.encode(detail.getBytes()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/util/ParserUtil.java b/src/main/java/com/hp/application/automation/tools/results/parser/util/ParserUtil.java deleted file mode 100644 index 00e5ef4279..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/util/ParserUtil.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.hp.application.automation.tools.results.parser.util; - -import java.io.StringWriter; -import java.util.Date; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; - -import com.hp.application.automation.tools.results.parser.ReportParser; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmRunImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestImpl; - -public class ParserUtil { - public static char nameConnector = '_'; - public static char[] testNameInvalidChars = new char[] { '\\', '/', ':', '"', '?', '\'', '<', '>', '|', '*', '%' }; - public static char[] testSetNameInvalidChars = new char[] { '\\', '^', ',', '"', '*' }; - - public static String repaceInvalidChars(char[] invalidChars, char newChar, String source) - { - StringBuffer temp = new StringBuffer(source); - - for (int i=0; i= 0) { - packageName = temp.substring(0, indexDot); - className = temp.substring(indexDot+1); - } - - String testName = className + "_" + methodName; - test.setFieldValue( AlmTest.TS_UT_PACKAGE_NAME, packageName); - test.setFieldValue( AlmTest.TEST_NAME, testName ); - test.setFieldValue( AlmTest.TEST_TYPE, ReportParser.EXTERNAL_TEST_TYPE); - test.setFieldValue( AlmTest.TS_TESTING_FRAMEWORK, testingFramework); - test.setFieldValue( AlmTest.TS_TESTING_TOOL, testingTool); - test.setFieldValue( AlmTest.TS_UT_CLASS_NAME, className); - test.setFieldValue( AlmTest.TS_UT_METHOD_NAME, methodName); - return test; - } - - public static String marshallerObject(Class c, Object o){ - String s = ""; - try { - JAXBContext jaxbContext = JAXBContext.newInstance(c); - Marshaller marshaller = jaxbContext.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_ENCODING,"utf-8"); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); - - StringWriter baos = new StringWriter(); - marshaller.marshal(o, baos); - s += baos.toString(); - }catch (Exception e) { - } - return s; - } - - public static AlmRun createRun(String runStatus, String execDateTime, String duration, String detail) { - AlmRun run = new AlmRunImpl(); - run.setFieldValue( AlmRun.RUN_SUBTYPE_ID, ReportParser.EXTERNAL_RUN_TYPE_ID); - run.setFieldValue( AlmRun.RUN_STATUS, runStatus); - run.setFieldValue( AlmRun.RUN_DETAIL, detail); - Date executeDate; - if(execDateTime != null && execDateTime.length() >0 ) { - execDateTime = execDateTime.replaceAll("T", " "); - executeDate = TimeUtil.stringToDate(execDateTime); - } else { - executeDate = new Date(System.currentTimeMillis()); - } - - run.setFieldValue( AlmRun.RUN_EXECUTION_DATE, - TimeUtil.dateToString(executeDate)); - run.setFieldValue( AlmRun.RUN_EXECUTION_TIME, - TimeUtil.timeToString(executeDate)); - - if(duration != null && duration.length() >0 ) { - Float durationTime = 0.0f; - try { - durationTime = Float.valueOf(duration); - } catch (NumberFormatException e) { - //the exception may be ignored. - } - run.setFieldValue( AlmRun.RUN_DURATION, String.valueOf(durationTime.intValue())); - } else { - run.setFieldValue( AlmRun.RUN_DURATION, String.valueOf(0) ); - } - - return run; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/util/TimeUtil.java b/src/main/java/com/hp/application/automation/tools/results/parser/util/TimeUtil.java deleted file mode 100644 index 4ba5cad04f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/parser/util/TimeUtil.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.hp.application.automation.tools.results.parser.util; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -public class TimeUtil { - public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; - public static final String DATE_FORMAT = "yyyy-MM-dd"; // "MM/dd/yyyy"); - public static final String TIME_FORMAT = "HH:mm:ss"; - - public static SimpleDateFormat getDateFormatter() { - return new SimpleDateFormat(DATE_FORMAT); - } - - public static SimpleDateFormat getDateFormatter(String format) { - return new SimpleDateFormat(format); - } - - public static String dateToString(java.util.Date date) { - try { - return ((date == null) ? "" : getDateFormatter().format(date)); - } catch (Exception e) { - return ""; - } - } - - public static java.util.Date stringToDate(String source) { - TimeZone localTimeZone = getDateFormatter().getTimeZone(); - return stringToDate(source, localTimeZone); - } - - public static DateFormat getFullTimestampFormatter(Locale locale) { - DateFormat dateFormat = - DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale); - - String localeString = locale.toString(); - if (localeString.equals("zh_SG")) { - return new SimpleDateFormat("dd/MM/yyyy a hh:mm"); - } else if (localeString.equals("ko")) { - return changeDateFormatPattern(dateFormat, "y+\\. *M+\\. *d+", "yyyy-MM-dd"); - } - - // change year format to long format (e.g. 2012) - return changeDateFormatPattern(dateFormat, "y+", "yyyy"); - } - - private static DateFormat changeDateFormatPattern( - final DateFormat dateFormat, - String regex, - String replacement) { - if (dateFormat instanceof SimpleDateFormat) { - SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat; - - String pattern = simpleDateFormat.toPattern().replaceAll(regex, replacement); - simpleDateFormat.applyPattern(pattern); - - return simpleDateFormat; - } - return dateFormat; - } - - public static SimpleDateFormat getFullTimestampFormatter() { - return new SimpleDateFormat(DATE_TIME_FORMAT); // m_fullTimestampFormatter; - } - - - public static SimpleDateFormat getTimeFormatter() { - return new SimpleDateFormat(TIME_FORMAT); // m_timeFormatter; - } - - public static java.util.Date stringToDate(String source, TimeZone timeZone) { - // check input - if (source == null) { - throw new IllegalArgumentException("null argument not allowed"); - } - - java.util.Date result; - try { - boolean hasColon = (source.indexOf(':') != -1); - boolean hasMinusSign = (source.indexOf('-') != -1); - int length = source.length(); - - // datetime format - if ((length == DATE_TIME_FORMAT.length()) - || (hasColon && hasMinusSign)) { - SimpleDateFormat fullTimestampFormatter = - getFullTimestampFormatter(); - fullTimestampFormatter.setTimeZone(timeZone); - result = fullTimestampFormatter.parse(source); - // date format - } else if ((source.length() == DATE_FORMAT.length()) - || (hasMinusSign)) { - SimpleDateFormat dateFormatter = getDateFormatter(); - dateFormatter.setTimeZone(timeZone); - result = dateFormatter.parse(source); - // time format - } else if ((source.length() == TIME_FORMAT.length()) || (hasColon)) { - SimpleDateFormat timeFormatter = getTimeFormatter(); - timeFormatter.setTimeZone(timeZone); - result = timeFormatter.parse(source); - } else { - throw new IllegalArgumentException("unsupported date format: \"" + source + "\""); - } - } catch (java.text.ParseException e) { - return new Date(); - } - - return result; - } - - public static String timeToString(java.util.Date date) { - try { - return ((date == null) ? "" : getTimeFormatter().format(date)); - } catch (Exception e) { - return ""; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/package-info.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/package-info.java deleted file mode 100644 index a3102ee80e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Created by kazaky on 07/07/2016. - */ -package com.hp.application.automation.tools.results.projectparser; \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java deleted file mode 100644 index 66f891b139..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * Created by kazaky on 07/07/2016. - */ -public class AvgTransactionResponseTime extends TimeRangeResult { - - public AvgTransactionResponseTime() { - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - protected String name = ""; -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/GoalResult.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/GoalResult.java deleted file mode 100644 index 83c3282c68..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/GoalResult.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * Created by kazaky on 07/07/2016. - */ - - -public abstract class GoalResult implements LrTest{ - - public SLA_STATUS getStatus() { - return _status; - } - - public void setStatus(SLA_STATUS _status) { - this._status = _status; - } - - public SLA_GOAL getSlaGoal() { - return _slaGoal; - } - - public void setSlaGoal(SLA_GOAL _slaGoal) { - this._slaGoal = _slaGoal; - } - - public double getDuration() { - return _duration; -} - - public void setDuration(double _duration) { - this._duration = _duration; - } - - private SLA_GOAL _slaGoal; - private SLA_STATUS _status; - - public String getFullName() { - return _fullName; - } - - public void setFullName(String _fullName) { - this._fullName = _fullName; - } - - private String _fullName; - private double _duration; - - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java deleted file mode 100644 index 3ff82e9de1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results.projectparser.performance; - -import java.util.ArrayList; -import java.util.Map; -import java.util.TreeMap; - - -/** - * Holds information on the SLA's of one scenario (per job / run / build) - */ -public class JobLrScenarioResult extends LrScenario { - public static final int DEFAULT_CONNECTION_MAX = -1; - public static final int DEFAULT_SCENARIO_DURATION = -1; - public ArrayList scenarioSlaResults; - public Map vUserSum; - public TreeMap transactionSum; - public TreeMap> transactionData; - private int connectionMax; - private long scenarioDuration; - - public JobLrScenarioResult(String scenarioName) { - super.setScenrioName(scenarioName); - connectionMax = DEFAULT_CONNECTION_MAX; - scenarioDuration = DEFAULT_SCENARIO_DURATION; - vUserSum = new TreeMap(); - transactionSum = new TreeMap(); - transactionData = new TreeMap<>(); - scenarioSlaResults = new ArrayList(0); - } - - public long getScenarioDuration() { - return scenarioDuration; - } - - public void setScenarioDuration(long scenarioDuration) { - this.scenarioDuration = scenarioDuration; - } - - public int getConnectionMax() { - return connectionMax; - } - - public void setConnectionMax(int connectionMax) { - this.connectionMax = connectionMax; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrJobResults.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrJobResults.java deleted file mode 100644 index 649c3acbf3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrJobResults.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results.projectparser.performance; - -import java.util.HashMap; -import java.util.Map; - - -public class LrJobResults extends LrRunResults implements LrTest { - - private Map _scenarioResults; - - public LrJobResults() { - _scenarioResults = new HashMap(); - } - - public Map getLrScenarioResults() { - return _scenarioResults; - } - - public JobLrScenarioResult addScenario(JobLrScenarioResult scenario) { - JobLrScenarioResult jobLrScenarioResult = _scenarioResults.put(scenario.getScenarioName(), scenario); - if (jobLrScenarioResult != null) { - _totalErrors += scenario.getTotalErrors(); - _totalFailures += scenario.getTotalFailures(); - _time += getTime(); - } - return jobLrScenarioResult; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrRunResults.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrRunResults.java deleted file mode 100644 index 23aadd6585..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrRunResults.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results.projectparser.performance; - -public class LrRunResults { - protected int _totalFailures; - protected int _totalErrors; - protected double _time; - private int TotalNoData; - private int TotalPassed; - private int TestCount; - - public LrRunResults() { - _totalFailures = 0; - _totalErrors = 0; - _time = 0; - TotalNoData = 0; - TotalPassed = 0; - TestCount = 0; - } - - public int getTotalFailures() { - return _totalFailures; - } - - public void setTotalFailures(int totalFailures) { - this._totalFailures = totalFailures; - } - - public void incTotalErrors() { - _totalErrors++; - } - - public void incTotalNoData() { - TotalNoData++; - } - - public int getTotalErrors() { - return _totalErrors; - } - - public void setTotalErrors(int totalErrors) { - this._totalErrors = totalErrors; - } - - public void updateStatus(LrTest.SLA_STATUS slaStatus) { - switch (slaStatus) { - case Failed: - incTotalFailures(); - incTotalTests(); - break; - case Passed: - incTotalPassed(); - incTotalTests(); - break; - default: - break; - } - } - - public void incTotalFailures() { - _totalFailures++; - } - - public void incTotalPassed() { - TotalPassed++; - } - - public void incTotalTests() { - TestCount++; - } - - public int getTotalNoData() { - return TotalNoData; - } - - public int getTestCount() { - return TestCount; - } - - public double getTime() { - return _time; - } - - public void setTime(double time) { - this._time = time; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrScenario.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrScenario.java deleted file mode 100644 index 211cb342fb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrScenario.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * The type Lr scenario. - */ -public abstract class LrScenario extends LrJobResults { - private String _scenrioName; - - /** - * Instantiates a new Lr scenario. - */ - public LrScenario() { - this(""); - } - - /** - * Instantiates a new Lr scenario. - * - * @param _scenrioName the scenrio name - */ - public LrScenario(String _scenrioName) { - this._scenrioName = _scenrioName; - } - - /** - * Gets scenario name. - * - * @return the scenario name - */ - public String getScenarioName() { - return _scenrioName; - } - - /** - * Sets scenrio name. - * - * @param scenrioName the scenrio name - */ - void setScenrioName(String scenrioName) { - _scenrioName = scenrioName; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrTest.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrTest.java deleted file mode 100644 index 8309ced208..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * Created by kazaky on 08/07/2016. - */ -public interface LrTest { - public enum SLA_STATUS { - Failed, Passed, NoData, bad; - - public static SLA_STATUS checkStatus(String status) { - if ((status.compareTo(Failed.toString()) == 0)) { - return Failed; - } else if ((status.compareTo(Passed.toString()) == 0)) { - return Passed; - } else if ((status.compareTo(NoData.toString()) == 0)) { - return NoData; - } - return bad; - } - } - - enum SLA_GOAL { - AverageThroughput, TotalThroughput, AverageHitsPerSecond, TotalHits, - ErrorsPerSecond, PercentileTRT, AverageTRT, Bad; - - public static SLA_GOAL checkGoal(String status) { - if ((status.compareTo(AverageThroughput.toString()) == 0)) { - return AverageThroughput; - } else if ((status.compareTo(TotalThroughput.toString()) == 0)) { - return TotalThroughput; - } else if ((status.compareTo(AverageHitsPerSecond.toString()) == 0)) { - return AverageHitsPerSecond; - } else if ((status.compareTo(TotalHits.toString()) == 0)) { - return TotalHits; - } else if ((status.compareTo(ErrorsPerSecond.toString()) == 0)) { - return ErrorsPerSecond; - } else if ((status.compareTo(AverageTRT.toString()) == 0)) { - return AverageTRT; - } else if ((status.compareTo(PercentileTRT.toString()) == 0)) { - return PercentileTRT; - } - return Bad; - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java deleted file mode 100644 index b4afd65ce5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * Created by kazaky on 10/07/2016. - */ -public class PercentileTransactionWholeRun extends WholeRunResult { - - private String name; - private double _precentage; - - public PercentileTransactionWholeRun() { - _precentage = 0.0; - name = ""; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public double getPrecentage() { - return _precentage; - } - - public void setPrecentage(double precentage) { - this._precentage = precentage; - } - - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/ProjectLrResults.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/ProjectLrResults.java deleted file mode 100644 index 807a44073e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/ProjectLrResults.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.results.projectparser.performance; - -import java.util.HashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - - -public class ProjectLrResults extends LrRunResults { - private SortedMap _scenarioResults; - - public ProjectLrResults() { - _scenarioResults = new TreeMap(); - } - - public SortedMap getScenarioResults() { - return _scenarioResults; - } - - public LrProjectScenarioResults addScenario(LrProjectScenarioResults scenario) { - LrProjectScenarioResults jobLrScenarioResult = _scenarioResults.put(scenario.getScenarioName(), scenario); - if (jobLrScenarioResult != null) { - _totalErrors += scenario.getTotalErrors(); - _totalFailures += scenario.getTotalFailures(); - _time += getTime(); - } - return jobLrScenarioResult; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRange.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRange.java deleted file mode 100644 index 6e23c9b57c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRange.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * The type Time range. - */ -public class TimeRange { - - private LrTest.SLA_STATUS slaStatus = LrTest.SLA_STATUS.bad; - private double _actualValue; - private double _goalValue; - private int loadAmount; - private double startTime; - private double endTime; - - /** - * Instantiates a new Time range. - * - * @param _actualValue the actual value - * @param _goalValue the goal value - * @param slaStatus the sla status - * @param loadAmount the load amount - * @param startTime the start time - * @param endTime the end time - */ - public TimeRange(double _actualValue, double _goalValue, LrTest.SLA_STATUS slaStatus, int loadAmount, - double startTime, double endTime) { - this._actualValue = _actualValue; - this._goalValue = _goalValue; - this.slaStatus = slaStatus; - this.loadAmount = 0; - this.loadAmount = loadAmount; - this.startTime = 0; - this.startTime = startTime; - this.endTime = 0; - this.endTime = endTime; - } - - /** - * Gets sla status. - * - * @return the sla status - */ - public LrTest.SLA_STATUS getSlaStatus() { - return slaStatus; - } - - /** - * Sets sla status. - * - * @param slaStatus the sla status - */ - public void setSlaStatus(LrTest.SLA_STATUS slaStatus) { - this.slaStatus = slaStatus; - } - - /** - * Gets actual value. - * - * @return the actual value - */ - public double getActualValue() { - return _actualValue; - } - - /** - * Sets actual value. - * - * @param actualValue the actual value - */ - public void setActualValue(double actualValue) { - this._actualValue = actualValue; - } - - /** - * Gets goal value. - * - * @return the goal value - */ - public double getGoalValue() { - return _goalValue; - } - - /** - * Sets goal value. - * - * @param goalValue the goal value - */ - public void setGoalValue(double goalValue) { - this._goalValue = goalValue; - } - - /** - * Gets load amount. - * - * @return the load amount - */ - public int getLoadAmount() { - return loadAmount; - } - - /** - * Sets load amount. - * - * @param loadAmount the load amount - */ - public void setLoadAmount(int loadAmount) { - this.loadAmount = loadAmount; - } - - /** - * Gets start time. - * - * @return the start time - */ - public double getStartTime() { - return startTime; - } - - /** - * Sets start time. - * - * @param startTime the start time - */ - public void setStartTime(double startTime) { - this.startTime = startTime; - } - - /** - * Gets end time. - * - * @return the end time - */ - public double getEndTime() { - return endTime; - } - - /** - * Sets end time. - * - * @param endTime the end time - */ - public void setEndTime(double endTime) { - this.endTime = endTime; - } - - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRangeResult.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRangeResult.java deleted file mode 100644 index ca6b4fdbd0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/TimeRangeResult.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by kazaky on 07/07/2016. - */ -public class TimeRangeResult extends GoalResult implements LrTest { - - - /** - * The Time ranges. - */ - private ArrayList timeRanges; - private double _avgActualValue; - private double _actualValueSum; - private double _goalValue; - private String LoadThrashold; - /** - * Instantiates a new Time range result. - */ - public TimeRangeResult() { - _actualValueSum = 0; - _goalValue = 0; - _avgActualValue = 0; - timeRanges = new ArrayList(0); - } - - public List getTimeRanges() { - return timeRanges; - } - - /** - * Gets actual value avg. - * - * @return the actual value avg - */ - public double getActualValueAvg() { - _avgActualValue = _actualValueSum / timeRanges.size(); - return _avgActualValue; - } - - /** - * Gets goal value. - * - * @return the goal value - */ - public double getGoalValue() { - return _goalValue; - } - - /** - * Sets goal value. - * - * @param goalValue the goal value - */ - public void setGoalValue(double goalValue) { - this._goalValue = goalValue; - } - - /** - * Inc actual value. - * - * @param actualValue the actual value - */ - public void incActualValue(double actualValue) { - this._actualValueSum += actualValue; - } - - /** - * Gets load thrashold. - * - * @return the load thrashold - */ - public String getLoadThrashold() { - return LoadThrashold; - } - - /** - * Sets load thrashold. - * - * @param loadThrashold the load thrashold - * @return the load thrashold - */ - public TimeRangeResult setLoadThrashold(String loadThrashold) { - LoadThrashold = loadThrashold; - return this; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/WholeRunResult.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/WholeRunResult.java deleted file mode 100644 index a4b60c0cf1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/WholeRunResult.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -/** - * Created by kazaky on 07/07/2016. - */ -public class WholeRunResult extends GoalResult { - - private double _actualValue; - private double _goalValue; - - /** - * Instantiates a new Whole run result. - * - * @param _actualValue the actual value - * @param _goalValue the goal value - */ - public WholeRunResult(double _actualValue, double _goalValue) { - this._actualValue = _actualValue; - this._goalValue = _goalValue; - } - - /** - * Instantiates an empty new Whole run result. - */ - public WholeRunResult() { - this(0,0); - } - - /** - * Gets actual value. - * - * @return the actual value - */ - public double getActualValue() { - return _actualValue; - } - - /** - * Sets actual value. - * - * @param actualValue the actual value - */ - public void setActualValue(double actualValue) { - this._actualValue = actualValue; - } - - /** - * Gets goal value. - * - * @return the goal value - */ - public double getGoalValue() { - return _goalValue; - } - - /** - * Sets goal value. - * - * @param goalValue the goal value - */ - public void setGoalValue(double goalValue) { - this._goalValue = goalValue; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/XmlParserUtil.java b/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/XmlParserUtil.java deleted file mode 100644 index 1415cbf128..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/XmlParserUtil.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.hp.application.automation.tools.results.projectparser.performance; - -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import javax.annotation.Nullable; - -/** - * Created by kazaky on 17/10/2016. - */ -public class XmlParserUtil { - - @Nullable - public static Node getNode(String tagName, NodeList nodes) { - for (int x = 0; x < nodes.getLength(); x++) { - Node node = nodes.item(x); - if (node.getNodeName().equalsIgnoreCase(tagName)) { - return node; - } - } - return null; - } - - public static String getNodeValue(Node node) { - NodeList childNodes = node.getChildNodes(); - for (int x = 0; x < childNodes.getLength(); x++) { - Node data = childNodes.item(x); - if (data.getNodeType() == Node.TEXT_NODE) - return data.getNodeValue(); - } - return ""; - } - - public static String getNodeValue(String tagName, NodeList nodes) { - for (int x = 0; x < nodes.getLength(); x++) { - Node node = nodes.item(x); - if (node.getNodeName().equalsIgnoreCase(tagName)) { - NodeList childNodes = node.getChildNodes(); - for (int y = 0; y < childNodes.getLength(); y++) { - Node data = childNodes.item(y); - if (data.getNodeType() == Node.TEXT_NODE) - return data.getNodeValue(); - } - } - } - return ""; - } - - public static String getNodeAttr(String attrName, Node node) { - NamedNodeMap attrs = node.getAttributes(); - for (int y = 0; y < attrs.getLength(); y++) { - Node attr = attrs.item(y); - if (attr.getNodeName().equalsIgnoreCase(attrName)) { - return attr.getNodeValue(); - } - } - return ""; - } - - public static String getNodeAttr(String tagName, String attrName, NodeList nodes) { - for (int x = 0; x < nodes.getLength(); x++) { - Node node = nodes.item(x); - if (node.getNodeName().equalsIgnoreCase(tagName)) { - NodeList childNodes = node.getChildNodes(); - for (int y = 0; y < childNodes.getLength(); y++) { - Node data = childNodes.item(y); - if ((data.getNodeType() == Node.ATTRIBUTE_NODE) && data.getNodeName().equalsIgnoreCase(attrName)) { - return data.getNodeValue(); - } - } - } - } - return ""; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestException.java b/src/main/java/com/hp/application/automation/tools/results/service/AlmRestException.java deleted file mode 100644 index 8ce5104e01..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -public class AlmRestException extends Exception{ - - private static final long serialVersionUID = -5386355008323770238L; - - public AlmRestException(Throwable cause) { - - super(cause); - } - - public AlmRestException(String message) { - - super(message); - } - - public AlmRestException(String message, Throwable cause) { - - super(message, cause); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestInfo.java b/src/main/java/com/hp/application/automation/tools/results/service/AlmRestInfo.java deleted file mode 100644 index 8e32e9759b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestInfo.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -public class AlmRestInfo { - - private String serverUrl; - private String userName; - private String password; - private String domain; - private String project; - private String timeout; - - public AlmRestInfo(String serverUrl, String domain, String project, String userName, String password, String timeout) { - this.serverUrl = serverUrl; - this.userName = userName; - this.password = password; - this.domain = domain; - this.project = project; - this.timeout = timeout; - - } - - public String getServerUrl(){ - return serverUrl; - } - - public void setServerUrl(String serverUrl) { - this.serverUrl = serverUrl; - } - - public String getUserName(){ - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword(){ - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getDomain(){ - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public String getProject(){ - return project; - } - - public void setProject(String project){ - this.project = project; - } - - public String getTimeout() { - return timeout; - } - - public void setTimeout(String timeout){ - this.timeout = timeout; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestTool.java b/src/main/java/com/hp/application/automation/tools/results/service/AlmRestTool.java deleted file mode 100644 index 8226320fe1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/AlmRestTool.java +++ /dev/null @@ -1,227 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.hp.application.automation.tools.common.Pair; -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.results.service.almentities.AlmEntity; -import com.hp.application.automation.tools.results.service.rest.CreateAlmEntityRequest; -import com.hp.application.automation.tools.results.service.rest.GetAlmEntityRequest; -import com.hp.application.automation.tools.results.service.rest.UpdateAlmEntityRequest; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.RestAuthenticator; - -public class AlmRestTool { - - private Logger _logger ; - - private RestClient restClient; - private AlmRestInfo almLoginInfo; - - - public AlmRestTool (AlmRestInfo almLoginInfo, Logger logger) { - this.restClient = new RestClient( - almLoginInfo.getServerUrl(), - almLoginInfo.getDomain(), - almLoginInfo.getProject(), - almLoginInfo.getUserName());; - this.almLoginInfo = almLoginInfo; - this._logger = logger; - } - - public RestClient getRestClient() { - return this.restClient; - } - - - private void appendQCSessionCookies(RestClient client) { - - // issue a post request so that cookies relevant to the QC Session will be added to the RestClient - Response response = - client.httpPost( - client.build("rest/site-session"), - null, - null, - ResourceAccessLevel.PUBLIC); - if (!response.isOk()) { - _logger.log("Failed to add QC Session Cookies."); - } - } - - - - public boolean login() throws Exception { - - boolean ret = true; - try { - ret = - new RestAuthenticator().login( - restClient, - almLoginInfo.getUserName(), - almLoginInfo.getPassword(), - _logger); - appendQCSessionCookies(restClient); - } catch (Throwable cause) { - ret = false; - _logger.log(String.format( - "Failed login to ALM Server URL: %s. Exception: %s", - almLoginInfo.getServerUrl(), - cause.getMessage())); - throw new AlmRestException (cause); - } - return ret; - } - - public List> getPairListForAlmEntityFields(AlmEntity almEntity, List fieldNames){ - List> pairs = new ArrayList>(); - for(String fieldName : fieldNames) { - pairs.add(new Pair(fieldName, String.valueOf(almEntity.getFieldValue(fieldName)))); - } - return pairs; - } - - public List> getPairListForAlmEntityFields(AlmEntity almEntity, String[] fieldNames){ - List> pairs = new ArrayList>(); - for(String fieldName : fieldNames) { - pairs.add(new Pair(fieldName, String.valueOf(almEntity.getFieldValue(fieldName)))); - } - return pairs; - } - - public List> getMapListForAlmEntityFields(AlmEntity almEntity, String[] fieldNames){ - List> fieldsMapList = new ArrayList>(); - - Map fieldsMap = new HashMap (); - - for(String fieldName : fieldNames) { - fieldsMap.put(fieldName, String.valueOf(almEntity.getFieldValue(fieldName))); - } - fieldsMapList.add(fieldsMap); - return fieldsMapList; - } - - public void populateAlmEntityFieldValue(Map mapFieldValue, AlmEntity almEntity) { - for(Map.Entry entry : mapFieldValue.entrySet()){ - almEntity.setFieldValue(entry.getKey(), entry.getValue()); - } - } - - public List getAlmEntityList(List> entities, Class c) { - - List entityList = new ArrayList (); - for(Map fieldValueMap: entities) { - try { - E entity = c.newInstance(); - populateAlmEntityFieldValue(fieldValueMap, entity); - entityList.add(entity); - } catch (Exception e) { - - } - } - - return entityList; - - } - - public static String getEncodedString(String s) { - String quotedStr = "\"" + s +"\""; - try { - quotedStr = URLEncoder.encode(quotedStr, "UTF-8"); - } catch (Exception e) { - - } - return quotedStr; - } - - public E getEntityUnderParentFolder( Class entityClass, int parentId, String entityName ){ - - String getEntityUnderParentFolderQuery = String.format("fields=id,name&query={parent-id[%s];name[%s]}", String.valueOf(parentId), getEncodedString(entityName)); - try { - AlmEntity entity = entityClass.newInstance(); - GetAlmEntityRequest getRequest = new GetAlmEntityRequest(entity, getRestClient(), getEntityUnderParentFolderQuery); - Response response = getRequest.perform(); - if(response.isOk() ) { - List> entities2 = XPathUtils.toEntities(response.toString()); - List entities = getAlmEntityList(entities2, entityClass); - - if(entities.size()>0){ - return entities.get(0); - } else { - return null; - } - } else { - _logger.log("Failed to get Entity:" +getEntityUnderParentFolderQuery ); - return null; - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - - } - - public List getAlmEntity( E entity, String queryString){ - - List ret = new ArrayList(); - - try { - GetAlmEntityRequest getRequest = new GetAlmEntityRequest(entity, getRestClient(), queryString); - Response response = getRequest.perform(); - if(response.isOk() && !response.toString().equals("")) { - List> entities2 = XPathUtils.toEntities(response.toString()); - List entities = getAlmEntityList(entities2, entity.getClass()); - return entities; - } else { - return ret; - } - - } catch (Exception e) { - e.printStackTrace(); - _logger.log("Failed to get Entity:" + entity.toString() +" with query string:" +queryString); - return ret; - } - - } - - public E createAlmEntity (E entity, String[] fieldsForCreation) throws ExternalEntityUploadException { - - CreateAlmEntityRequest createRequest = new CreateAlmEntityRequest(getRestClient(), entity, getPairListForAlmEntityFields(entity, fieldsForCreation) ); - Response response = createRequest.perform(); - if(response.isOk() && !response.toString().equals("")){ - List> entities2 = XPathUtils.toEntities(response.toString()); - List entities = getAlmEntityList(entities2, entity.getClass()); - - if(entities.size()>0){ - - return (E)entities.get(0); - } else { - _logger.log("Failed to create Entity:" + entity.toString()); - throw new ExternalEntityUploadException("Failed to create Entity:" + entity.toString()); - } - } else { - _logger.log("Failed to create Entity:" + entity.toString()); - throw new ExternalEntityUploadException("Failed to create Entity:" + entity.toString()); - } - - } - - public void updateAlmEntity (E entity, String[] fieldsForUpdate) { - - UpdateAlmEntityRequest updateRequest = new UpdateAlmEntityRequest(getRestClient(), entity, getMapListForAlmEntityFields(entity, fieldsForUpdate)) ; - Response response = updateRequest.execute(); - - if(!response.isOk()) { - _logger.log("Failed to update entity:" + entity.toString()); - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java deleted file mode 100644 index f170d00aee..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java +++ /dev/null @@ -1,437 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -import com.hp.application.automation.tools.results.parser.ReportParserManager; -import com.hp.application.automation.tools.results.service.almentities.AlmCommonProperties; -import com.hp.application.automation.tools.results.service.almentities.AlmEntity; -import com.hp.application.automation.tools.results.service.almentities.AlmRun; -import com.hp.application.automation.tools.results.service.almentities.AlmTest; -import com.hp.application.automation.tools.results.service.almentities.AlmTestConfig; -import com.hp.application.automation.tools.results.service.almentities.AlmTestConfigImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestFolder; -import com.hp.application.automation.tools.results.service.almentities.AlmTestFolderImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstance; -import com.hp.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetFolder; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetFolderImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSetImpl; -import com.hp.application.automation.tools.results.service.almentities.EntityRelation; -import com.hp.application.automation.tools.results.service.almentities.IAlmConsts; -import com.hp.application.automation.tools.sse.sdk.Logger; - -public class DefaultExternalEntityUploadServiceImpl implements - IExternalEntityUploadService { - - Logger logger; - - - private AlmRestTool restTool; - - public DefaultExternalEntityUploadServiceImpl(AlmRestTool restTool, Logger logger) { - this.restTool = restTool; - this.logger = logger; - } - - - private String [] getTestCreationFields() { - - return new String [] { AlmTest.TEST_NAME, - AlmTest.TEST_TYPE, - AlmTest.TS_TESTING_FRAMEWORK, - AlmTest.TS_TESTING_TOOL, - AlmTest.TS_UT_PACKAGE_NAME, - AlmTest.TS_UT_CLASS_NAME, - AlmTest.TS_UT_METHOD_NAME, - AlmCommonProperties.PARENT_ID, - AlmTest.TEST_RESPONSIBLE - }; - } - - private AlmTest importTest(AlmTest test , int testFolderId, String testingTool, String testdesigner) throws ExternalEntityUploadException{ - - String className = (String) test.getFieldValue(AlmTest.TS_UT_CLASS_NAME); - String methodName = (String) test.getFieldValue(AlmTest.TS_UT_METHOD_NAME); - String packageName = (String) test.getFieldValue(AlmTest.TS_UT_PACKAGE_NAME); - String testingFramework = (String) test.getFieldValue(AlmTest.TS_TESTING_FRAMEWORK); - - String queryString = String.format("query={parent-id[%s];subtype-id[EXTERNAL-TEST];ut-class-name[%s];ut-method-name[%s]}&fields=id,name,ut-package-name,ut-class-name,ut-method-name,testing-framework&page-size=2000", - String.valueOf(testFolderId), - AlmRestTool.getEncodedString(className), - AlmRestTool.getEncodedString(methodName)); - List existingTests = restTool.getAlmEntity(new AlmTestImpl(), queryString); - - AlmTestImpl importedTest = null;//restTool.getEntityUnderParentFolder(AlmTestImpl.class, testFolderId, test.getName()); - - if(existingTests != null && existingTests.size() >0) { - boolean exists = false; - Map existingTestMap = new HashMap (); - - for(AlmTestImpl existingTest : existingTests) { - if(existingTest.getKey().endsWith(test.getKey())) { - exists = true; - importedTest = existingTest; - break; - } - existingTestMap.put(existingTest.getName(), existingTest); - } - - if(!exists) { - String tempName = className + "_" + methodName; - if(!existingTestMap.containsKey(tempName)) { - test.setFieldValue(AlmTest.TEST_NAME, tempName); - } else { - tempName = packageName + "_" +tempName; - if(!existingTestMap.containsKey(tempName)) { - test.setFieldValue(AlmTest.TEST_NAME, tempName); - } else { - tempName = tempName +"_" +testingFramework; - if(!existingTestMap.containsKey(tempName)) { - test.setFieldValue(AlmTest.TEST_NAME, tempName); - } - } - } - - } - } - - if(importedTest == null) { - test.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(testFolderId)); - test.setFieldValue(AlmTest.TS_TESTING_TOOL, testingTool); - test.setFieldValue(AlmTest.TEST_RESPONSIBLE, testdesigner); - return restTool.createAlmEntity(test, getTestCreationFields()); - } - - - return importedTest; - } - - private String [] getTestSetCreationFields() { - return new String [] { AlmCommonProperties.PARENT_ID, - AlmTestSet.TESTSET_NAME, - AlmTestSet.TESTSET_SUB_TYPE_ID}; - } - - private AlmTestSet importTestSet(AlmTestSet testset, int testsetFolderId) throws ExternalEntityUploadException{ - - - AlmTestSetImpl importedTestset = restTool.getEntityUnderParentFolder(AlmTestSetImpl.class, testsetFolderId, testset.getName()); - - if(importedTestset == null) { - - testset.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(testsetFolderId)); - return restTool.createAlmEntity(testset, getTestSetCreationFields()); - - } - - - return importedTestset; - } - - private AlmTestConfig getMainTestConfig(AlmTest test){ - - AlmTestConfigImpl testConfigImpl = new AlmTestConfigImpl(); - String queryString = String.format("query={parent-id[%s]}&fields=id,name", String.valueOf(test.getId()) ); - List testconfigs = restTool.getAlmEntity(testConfigImpl, queryString); - if(testconfigs != null && testconfigs.size() >0) { - return testconfigs.get(0); - } else { - return null; - } - - } - - private String [] getTestInstanceCreationFields (){ - return new String [] { AlmTestInstance.TEST_INSTANCE_TESTSET_ID, - AlmTestInstance.TEST_INSTANCE_CONFIG_ID, - AlmTestInstance.TEST_INSTANCE_TEST_ID, - AlmTestInstance.TEST_INSTANCE_TESTER_NAME, - AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID - }; - - } - - private AlmTestInstance importTestInstance(AlmTestInstance testinstance, String testsetId, String testId, String testconfigId, String tester) throws ExternalEntityUploadException{ - - String queryString = String.format("query={cycle-id[%s];test-config-id[%s];test-id[%s]}&fields=id,name", - String.valueOf(testsetId), String.valueOf(testconfigId), String.valueOf(testId) ); - - List testInstances = restTool.getAlmEntity(new AlmTestInstanceImpl(), queryString); - - if(testInstances!=null && testInstances.size() > 0){ - return testInstances.get(0); - } else { - - testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TESTSET_ID, String.valueOf(testsetId)); - testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_CONFIG_ID, String.valueOf(testconfigId)); - testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TEST_ID, String.valueOf(testId)); - testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TESTER_NAME, tester); - - return restTool.createAlmEntity(testinstance, getTestInstanceCreationFields()); - } - } - - private String generateImportRunName() { - Calendar cal = new GregorianCalendar(); - cal.setTime(new java.sql.Date(System.currentTimeMillis())); - return String.format( - IAlmConsts.IMPORT_RUN_NAME_TEMPLATE, - cal.get(Calendar.MONTH) + 1, // java.util.Calendar represents months from 0 to 11 instead of from 1 to 12. That's why it should be incremented. - cal.get(Calendar.DAY_OF_MONTH), - cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), - cal.get(Calendar.SECOND)); - } - - - private String[] getRunCreationFields() { - return new String[]{ - AlmRun.RUN_CONFIG_ID, - AlmRun.RUN_CYCLE_ID, - AlmRun.RUN_TEST_ID, - AlmRun.RUN_TESTCYCL_UNIQUE_ID, - AlmRun.RUN_BUILD_REVISION, - AlmCommonProperties.NAME, - AlmCommonProperties.OWNER, - AlmRun.RUN_STATUS, - AlmRun.RUN_SUBTYPE_ID, - AlmRun.RUN_DETAIL, - AlmRun.RUN_DURATION, - AlmRun.RUN_JENKINS_JOB_NAME, - AlmRun.RUN_JENKINS_URL, - AlmRun.RUN_EXECUTION_DATE, - AlmRun.RUN_EXECUTION_TIME, - AlmRun.RUN_STATUS - }; - } - - private AlmRun generateRun(String tester, - AlmRun run, - String testsetId, - String testId, - String testInstanceId, - String testconfigId, - String subversion, - String jobName, - String buildUrl) throws ExternalEntityUploadException{ - - run.setFieldValue(AlmRun.RUN_CONFIG_ID, String.valueOf(testconfigId)); - run.setFieldValue(AlmRun.RUN_CYCLE_ID, String.valueOf(testsetId)); - run.setFieldValue(AlmRun.RUN_TEST_ID, String.valueOf(testId)); - run.setFieldValue(AlmRun.RUN_TESTCYCL_UNIQUE_ID, String.valueOf(testInstanceId)); - run.setFieldValue(AlmRun.RUN_JENKINS_JOB_NAME, jobName); - run.setFieldValue(AlmRun.RUN_JENKINS_URL, buildUrl); - - - if(subversion != null && subversion.length() >0 ) { - run.setFieldValue(AlmRun.RUN_BUILD_REVISION, subversion); - } else { - run.setFieldValue(AlmRun.RUN_BUILD_REVISION, ""); - } - - run.setFieldValue(AlmCommonProperties.NAME, generateImportRunName()); - run.setFieldValue(AlmCommonProperties.OWNER, tester); - - return restTool.createAlmEntity(run, getRunCreationFields()); - - - } - - private String[] getCreationFieldsForTestFolder() { - return new String[] {AlmCommonProperties.NAME, AlmCommonProperties.PARENT_ID}; - } - - private AlmTestFolder createTestFolder(int parentId, String folderName) throws ExternalEntityUploadException { - - AlmTestFolderImpl testFolder = restTool.getEntityUnderParentFolder(AlmTestFolderImpl.class, parentId, folderName); - String encodedFolderName = folderName; - - if(testFolder == null) { - testFolder = new AlmTestFolderImpl(); - testFolder.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(parentId)); - testFolder.setFieldValue(AlmCommonProperties.NAME, encodedFolderName); - return restTool.createAlmEntity(testFolder, getCreationFieldsForTestFolder()); - } else { - return testFolder; - } - } - String FOLDER_SEPERATOR = "\\"; - - - private AlmTestFolder createTestFolderPath(int parentId, String path) throws ExternalEntityUploadException { - List folders = new ArrayList(); - - StringTokenizer tokenizer = new StringTokenizer(path, FOLDER_SEPERATOR); - - while (tokenizer.hasMoreTokens()) { - String itemString = tokenizer.nextToken(); - AlmTestFolder testFolder = createTestFolder(parentId, itemString); - if(testFolder != null) { - folders.add(testFolder); - parentId = Integer.valueOf(testFolder.getId()); - } - } - - if(folders.size() >0 ){ - return folders.get(folders.size()-1); - } else { - return null; - } - } - - private String[] getCreationFieldsForTestSetFolder() { - return new String[] {AlmCommonProperties.NAME, AlmCommonProperties.PARENT_ID}; - } - - private AlmTestSetFolder createTestSetFolder(int parentId, String folderName) throws ExternalEntityUploadException { - - AlmTestSetFolderImpl testsetFolder = restTool.getEntityUnderParentFolder(AlmTestSetFolderImpl.class, parentId, folderName); - - String encodedFolderName = folderName; - - if(testsetFolder == null) { - testsetFolder = new AlmTestSetFolderImpl(); - testsetFolder.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(parentId)); - testsetFolder.setFieldValue(AlmCommonProperties.NAME, encodedFolderName); - return restTool.createAlmEntity(testsetFolder, getCreationFieldsForTestSetFolder()); - } else { - return testsetFolder; - } - } - - private AlmTestSetFolder createTestSetFolderPath(int parentId, String path) throws ExternalEntityUploadException { - - List folders = new ArrayList(); - - StringTokenizer tokenizer = new StringTokenizer(path, FOLDER_SEPERATOR); - - while (tokenizer.hasMoreTokens()) { - String itemString = tokenizer.nextToken(); - AlmTestSetFolder testsetFolder = createTestSetFolder(parentId, itemString); - if(testsetFolder != null) { - folders.add(testsetFolder); - parentId = Integer.valueOf(testsetFolder.getId()); - } - } - if(folders.size() >0 ){ - return folders.get(folders.size()-1); - } else { - return null; - } - } - - @Override - public void UploadExternalTestSet(AlmRestInfo loginInfo, - String reportFilePath, - String testsetFolderPath, - String testFolderPath, - String testingFramework, - String testingTool, - String subversion, - String jobName, - String buildUrl) throws ExternalEntityUploadException{ - - logger.log("INFO: Start to parse file: " +reportFilePath); - - List testsets = ReportParserManager.getInstance().parseTestSets( reportFilePath, testingFramework, testingTool); - - if(testsets == null) { - logger.log("Failed to parse file: " + reportFilePath); - throw new ExternalEntityUploadException("Failed to parse file: " + reportFilePath); - } else { - logger.log("INFO: parse resut file succeed."); - } - - if(testsets != null && testsets.size() >0 ) { - logger.log("INFO: Start to login to ALM Server."); - try { - if( restTool.login() ) { - - logger.log("INFO: Checking test folder..."); - AlmTestFolder testFolder = createTestFolderPath(2, testFolderPath); - logger.log("INFO: Checking testset folder..."); - AlmTestSetFolder testsetFolder = createTestSetFolderPath (0, testsetFolderPath); - if(testFolder != null && testsetFolder != null){ - logger.log("INFO: Uploading ALM Entities..."); - importExternalTestSet( - testsets, - loginInfo.getUserName(), - Integer.valueOf(testsetFolder.getId()), - Integer.valueOf(testFolder.getId()), - testingTool, - subversion, - jobName, - buildUrl); - } - } else { - throw new ExternalEntityUploadException("Failed to login to ALM Server."); - } - } catch (Exception e) { - throw new ExternalEntityUploadException(e); - } - } - } - - - private void importExternalTestSet(List testsets, String tester, int testsetFolderId, int testFolderId, String testingTool, String subversion, String jobName, String buildUrl ) throws ExternalEntityUploadException{ - - - for (AlmTestSet testset : testsets){ - AlmTestSet importedTestSet = importTestSet(testset, testsetFolderId); - if(importedTestSet == null ) { - continue; - } - List testinstances = testset.getRelatedEntities().get(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION); - if(testinstances == null || testinstances.size() <=0) { - continue; - } - - for(AlmEntity testinstanceEntity: testinstances){ - AlmTestInstance testInstance = (AlmTestInstance) testinstanceEntity; - List tests = testInstance.getRelatedEntities().get(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION); - if(tests == null || tests.size() <= 0) { - continue; - } - - AlmTest test = (AlmTest) tests.get(0); - AlmTest importedTest = importTest(test, testFolderId, testingTool, tester); - if(importedTest == null) { - continue; - } - - AlmTestConfig mainTestConfig = getMainTestConfig(importedTest); - if(mainTestConfig == null) { - continue; - } - - AlmTestInstance importedTestInstance = importTestInstance(testInstance, importedTestSet.getId(), importedTest.getId(), mainTestConfig.getId(), tester); - List runs = testInstance.getRelatedEntities().get(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION); - if(runs == null || runs.size() <= 0) { - continue; - } - - AlmRun run = (AlmRun) runs.get(0); - generateRun(tester, - run, - importedTestSet.getId(), - importedTest.getId(), - importedTestInstance.getId(), - mainTestConfig.getId(), - subversion, - jobName, - buildUrl - ); - } - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadException.java b/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadException.java deleted file mode 100644 index e61c962831..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -public class ExternalEntityUploadException extends Exception{ - - private static final long serialVersionUID = -5386355008323770238L; - - public ExternalEntityUploadException(Throwable cause) { - - super(cause); - } - - public ExternalEntityUploadException(String message) { - - super(message); - } - - public ExternalEntityUploadException(String message, Throwable cause) { - - super(message, cause); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadLogger.java b/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadLogger.java deleted file mode 100644 index 8506ad2d1f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/ExternalEntityUploadLogger.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -import java.io.PrintStream; - -import com.hp.application.automation.tools.sse.sdk.Logger; - -public class ExternalEntityUploadLogger implements Logger { - - private PrintStream printStream; - - public ExternalEntityUploadLogger(PrintStream printStream) { - this.printStream = printStream; - } - @Override - public void log(String message) { - if(printStream != null) { - printStream.println(message); - } - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/IExternalEntityUploadService.java b/src/main/java/com/hp/application/automation/tools/results/service/IExternalEntityUploadService.java deleted file mode 100644 index 15557975a2..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/IExternalEntityUploadService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -public interface IExternalEntityUploadService { - - public void UploadExternalTestSet(AlmRestInfo loginInfo, String reportFilePath, String testsetFolderPath, String testFolderPath, String testingFramework, String testingTool, String subversion, String jobName, String buildUrl) throws ExternalEntityUploadException; - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/SystemOutLogger.java b/src/main/java/com/hp/application/automation/tools/results/service/SystemOutLogger.java deleted file mode 100644 index 11375cc081..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/SystemOutLogger.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hp.application.automation.tools.results.service; - -import com.hp.application.automation.tools.sse.sdk.Logger; - -public class SystemOutLogger implements Logger { - - @Override - public void log(String message) { - System.out.println(message); - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmCommonProperties.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmCommonProperties.java deleted file mode 100644 index 841978afe6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmCommonProperties.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmCommonProperties { - - public final String PARENT_ID = "parent-id"; - public final String NAME = "name"; - public final String ID = "id"; - public final String OWNER = "owner"; -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntity.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntity.java deleted file mode 100644 index 9f320ce8c7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -import java.util.List; -import java.util.Map; - -public interface AlmEntity { - - public void setFieldValue(String fieldName, String fieldValue); - public Object getFieldValue(String fieldName); - public void addRelatedEntity(String relationName, AlmEntity entity); - public Map> getRelatedEntities() ; - - public String getName(); - - public String getId(); - - public void setId(String id); - - public String getRestPrefix(); - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntityImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntityImpl.java deleted file mode 100644 index 79224416ff..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmEntityImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class AlmEntityImpl implements AlmEntity { - - private final Map fields = new HashMap(); - private final Map> relatedEntities = - new HashMap>(); - - - public String getName() { - return (String) getFieldValue(AlmCommonProperties.NAME); - } - - public String getId() { - return getFieldValue(AlmCommonProperties.ID); - - } - - public void setId(String id) { - setFieldValue(AlmCommonProperties.ID, id); - } - - @Override - public void setFieldValue(String fieldName, String fieldValue) { - fields.put(fieldName, fieldValue); - - } - - @Override - public String getFieldValue(String fieldName) { - return fields.get(fieldName); - } - - @Override - public void addRelatedEntity(String relationName, AlmEntity entity) { - List entities = relatedEntities.get(relationName); - if (entities == null){ - relatedEntities.put(relationName, new ArrayList()); - entities = relatedEntities.get(relationName); - } - - entities.add(entity); - } - - @Override - public Map> getRelatedEntities() { - return relatedEntities; - } - - public String toString(){ - String s = this.getRestPrefix() +":"; - - for(Map.Entry field : fields.entrySet()) { - s += field.getKey(); - s += "="; - s += field.getValue(); - } - return s; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRun.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRun.java deleted file mode 100644 index e7884d77b6..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRun.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmRun extends AlmEntity{ - public final String RUN_SUBTYPE_ID = "subtype-id"; - public final String RUN_STATUS = "status"; - public final String RUN_DETAIL = "detail"; - public final String RUN_EXECUTION_DATE = "execution-date"; - public final String RUN_EXECUTION_TIME = "execution-time"; - public final String RUN_DURATION = "duration"; - public final String RUN_CONFIG_ID ="test-config-id"; - public final String RUN_CYCLE_ID = "cycle-id"; - public final String RUN_TEST_ID = "test-id"; - public final String RUN_TESTCYCL_UNIQUE_ID = "testcycl-id"; - public final String RUN_BUILD_REVISION= "build-revision"; - public final String RUN_JENKINS_JOB_NAME="jenkins-job-name"; - public final String RUN_JENKINS_URL="jenkins-url"; - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRunImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRunImpl.java deleted file mode 100644 index 796a18b343..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmRunImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmRunImpl extends AlmEntityImpl implements AlmRun { - - private static String restPrefix = "runs"; - public String getRestPrefix() { - return restPrefix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTest.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTest.java deleted file mode 100644 index 8f732d6c27..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTest extends AlmEntity{ - public final String TEST_NAME = "name"; - public final String TEST_TYPE = "subtype-id"; - public final String TS_TESTING_FRAMEWORK = "testing-framework"; - public final String TS_TESTING_TOOL = "testing-tool"; - public final String TS_UT_CLASS_NAME = "ut-class-name"; - public final String TS_UT_METHOD_NAME = "ut-method-name"; - public final String TEST_RESPONSIBLE = "owner"; - public final String TS_UT_PACKAGE_NAME = "ut-package-name"; - - public String getKey(); -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfig.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfig.java deleted file mode 100644 index b5c7d40f9f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfig.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTestConfig extends AlmEntity { - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java deleted file mode 100644 index 014eddd4bb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestConfigImpl extends AlmEntityImpl implements AlmTestConfig { - - private static String restPrefix = "test-configs"; - public String getRestPrefix() { - return restPrefix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolder.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolder.java deleted file mode 100644 index 6c181b11a8..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolder.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTestFolder extends AlmEntity { - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java deleted file mode 100644 index d26db39036..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestFolderImpl extends AlmEntityImpl implements AlmTestFolder { - - private static String restPrefix = "test-folders"; - public String getRestPrefix() { - return restPrefix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestImpl.java deleted file mode 100644 index bf62eb0247..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestImpl extends AlmEntityImpl implements AlmTest { - private static String restPrefix = "tests"; - public String getRestPrefix() { - return restPrefix; - } - - public String getKey(){ - String className = (String)getFieldValue(AlmTest.TS_UT_CLASS_NAME); - - String methodName = (String)getFieldValue(AlmTest.TS_UT_METHOD_NAME); - String packageName = (String)getFieldValue(AlmTest.TS_UT_PACKAGE_NAME); - if(packageName == null) { - packageName = ""; - } - String testingFramework = (String) getFieldValue(AlmTest.TS_TESTING_FRAMEWORK); - String key = packageName +"_" +className +"_"+ methodName+"_"+testingFramework; - return key; - } - - public boolean equals(Object o){ - - if( !(o instanceof AlmTestImpl)){ - return false; - } - - if(this == o) { - return true; - } - - AlmTestImpl oT = (AlmTestImpl) o; - - String className = (String)getFieldValue(AlmTest.TS_UT_CLASS_NAME); - - String methodName = (String)getFieldValue(AlmTest.TS_UT_METHOD_NAME); - String packageName = (String)getFieldValue(AlmTest.TS_UT_PACKAGE_NAME); - if(packageName == null) { - packageName = ""; - } - - String testingFramework = (String) getFieldValue(AlmTest.TS_TESTING_FRAMEWORK); - - return className.equals((String)oT.getFieldValue(AlmTest.TS_UT_CLASS_NAME)) - && packageName.equals((String)oT.getFieldValue(AlmTest.TS_UT_PACKAGE_NAME)) - && methodName.equals((String)oT.getFieldValue(AlmTest.TS_UT_METHOD_NAME)) - && testingFramework.equals((String)oT.getFieldValue(AlmTest.TS_TESTING_FRAMEWORK)); - - } - - public int hashCode(){ - - return getKey().hashCode(); - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstance.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstance.java deleted file mode 100644 index c9288e8d35..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstance.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTestInstance extends AlmEntity{ - - public final String TEST_INSTANCE_SUBTYPE_ID = "subtype-id"; - public final String TEST_INSTANCE_EXEC_DATE = "exec-date"; - public final String TEST_INSTANCE_EXEC_TIME = "exec-time"; - public final String TEST_INSTANCE_TESTSET_ID = "cycle-id"; - public final String TEST_INSTANCE_CONFIG_ID= "test-config-id"; - public final String TEST_INSTANCE_TEST_ID = "test-id"; - public final String TEST_INSTANCE_TESTER_NAME = "owner"; - - public String getKey(); -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java deleted file mode 100644 index 6699fe941c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestInstanceImpl extends AlmEntityImpl implements - AlmTestInstance { - private static String restPrefix = "test-instances"; - public String getRestPrefix() { - return restPrefix; - } - - public String getKey() { - - return getFieldValue(AlmTestInstance.TEST_INSTANCE_TESTSET_ID) + "_" - + getFieldValue(AlmTestInstance.TEST_INSTANCE_CONFIG_ID) + "_" - + getFieldValue(AlmTestInstance.TEST_INSTANCE_TEST_ID); - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSet.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSet.java deleted file mode 100644 index 6d23722998..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSet.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTestSet extends AlmEntity{ - - public final String TESTSET_NAME = "name"; - public final String TESTSET_SUB_TYPE_ID = "subtype-id"; - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolder.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolder.java deleted file mode 100644 index 8d35f73623..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolder.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface AlmTestSetFolder extends AlmEntity { - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java deleted file mode 100644 index e1af63a76f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestSetFolderImpl extends AlmEntityImpl implements - AlmTestSetFolder { - private static String restPrefix = "test-set-folders"; - public String getRestPrefix() { - return restPrefix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetImpl.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetImpl.java deleted file mode 100644 index ffde3d4db2..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/AlmTestSetImpl.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public class AlmTestSetImpl extends AlmEntityImpl implements AlmTestSet { - private static String restPrefix = "test-sets"; - public String getRestPrefix() { - return restPrefix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/EntityRelation.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/EntityRelation.java deleted file mode 100644 index 0f9d789e30..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/EntityRelation.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface EntityRelation { - public final String TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION = "TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION"; - public final String TEST_TO_TESTINSTANCE_REALIZATION_RELATION = "TEST_TO_TESTINSTANCE_REALIZATION_RELATION"; - public final String TESTINSTANCE_TO_RUN_REALIZATION_RELATION = "TESTINSTANCE_TO_RUN_REALIZATION_RELATION"; - -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/almentities/IAlmConsts.java b/src/main/java/com/hp/application/automation/tools/results/service/almentities/IAlmConsts.java deleted file mode 100644 index 7f4bf160a7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/almentities/IAlmConsts.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.hp.application.automation.tools.results.service.almentities; - -public interface IAlmConsts { - - public interface IStatuses { - public final String NO_RUN = "No Run"; - public final String PASSED = "Passed"; - public final String FAILED = "Failed"; - - } - public final String IMPORT_RUN_NAME_TEMPLATE = "Import_Run_%d-%d_%d-%d-%d"; -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java b/src/main/java/com/hp/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java deleted file mode 100644 index 01f715d107..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.hp.application.automation.tools.results.service.rest; - -import com.hp.application.automation.tools.common.Pair; -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.results.service.almentities.AlmEntity; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.PostRequest; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class CreateAlmEntityRequest extends PostRequest { - - List> attrForCreation; - AlmEntity almEntity; - private static final String IGNORE_REQUIRED_FIELDS_VALIDATION = "X-QC-Ignore-Customizable-Required-Fields-Validation"; - public CreateAlmEntityRequest( Client client, AlmEntity almEntity, List> attrForCreation){ - super(client, ""); - this.attrForCreation = attrForCreation; - this.almEntity = almEntity; - } - - @Override - protected Map getHeaders() { - - Map ret = new HashMap(); - ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); - ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); - ret.put(IGNORE_REQUIRED_FIELDS_VALIDATION, "Y"); - return ret; - } - - @Override - protected String getSuffix() { - // TODO Auto-generated method stub - return almEntity.getRestPrefix(); - } - - protected List> getDataFields() { - - return attrForCreation; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/rest/GetAlmEntityRequest.java b/src/main/java/com/hp/application/automation/tools/results/service/rest/GetAlmEntityRequest.java deleted file mode 100644 index 50c4628254..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/rest/GetAlmEntityRequest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.hp.application.automation.tools.results.service.rest; - -import com.hp.application.automation.tools.results.service.almentities.AlmEntity; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GetRequest; - -public class GetAlmEntityRequest extends GetRequest { - - private AlmEntity almEntity; - private String queryString ; - - public GetAlmEntityRequest(AlmEntity almEntity, Client client) { - super(client, ""); - this.almEntity = almEntity; - - } - - public GetAlmEntityRequest(AlmEntity almEntity, Client client, String queryString) { - super(client, ""); - this.almEntity = almEntity; - this.queryString = queryString; - - } - - protected String getQueryString() { - - return queryString; - } - - protected String getSuffix() { - if(queryString != null && queryString.length() >0 ) { - return almEntity.getRestPrefix(); - - } else { - return String.format("%s/%s", almEntity.getRestPrefix(), almEntity.getId()); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java b/src/main/java/com/hp/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java deleted file mode 100644 index 8aead91cf5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hp.application.automation.tools.results.service.rest; - -import java.util.List; -import java.util.Map; - -import com.hp.application.automation.tools.results.service.almentities.AlmEntity; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralPutBulkRequest; - -public class UpdateAlmEntityRequest extends GeneralPutBulkRequest { - - List> attrForUpdate; - AlmEntity almEntity; - - public UpdateAlmEntityRequest( Client client, AlmEntity almEntity, List> attrForUpdate){ - super(client); - this.attrForUpdate = attrForUpdate; - this.almEntity = almEntity; - } - - @Override - protected String getSuffix() { - // TODO Auto-generated method stub - return String.format("%s/%s", almEntity.getRestPrefix(), almEntity.getId()); - } - - protected List> getFields() { - - return attrForUpdate; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunBuilder.java b/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunBuilder.java deleted file mode 100644 index a28623701f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunBuilder.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.hp.application.automation.tools.model.AbstractSvRunModel; -import com.hp.application.automation.tools.model.SvServerSettingsModel; -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.sv.jsvconfigurator.build.ProjectBuilder; -import com.hp.sv.jsvconfigurator.core.IProject; -import com.hp.sv.jsvconfigurator.core.IService; -import com.hp.sv.jsvconfigurator.core.impl.exception.CommandExecutorException; -import com.hp.sv.jsvconfigurator.core.impl.exception.CommunicatorException; -import com.hp.sv.jsvconfigurator.core.impl.exception.ProjectBuilderException; -import com.hp.sv.jsvconfigurator.core.impl.jaxb.atom.ServiceListAtom; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import com.hp.sv.jsvconfigurator.serverclient.impl.CommandExecutorFactory; -import hudson.AbortException; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.tasks.Builder; -import jenkins.tasks.SimpleBuildStep; -import org.apache.commons.lang.StringUtils; - -class ServiceInfo { - private final String id; - private final String name; - - public ServiceInfo(String id, String name) { - this.id = id; - this.name = name; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } -} - -class ConfigurationException extends Exception { - public ConfigurationException(String message) { - super(message); - } -} - -public abstract class AbstractSvRunBuilder extends Builder implements SimpleBuildStep { - private static final Logger LOG = Logger.getLogger(AbstractSvRunBuilder.class.getName()); - - protected final T model; - - protected AbstractSvRunBuilder(T model) { - this.model = model; - } - - protected static void verifyNotNull(Object value, String errorMessage) throws ConfigurationException { - if (value == null) { - throw new ConfigurationException(errorMessage); - } - } - - public T getModel() { - return model; - } - - public SvServiceSelectionModel getServiceSelection() { - return model.getServiceSelection(); - } - - protected SvServerSettingsModel getSelectedServerSettings() throws ConfigurationException { - SvServerSettingsModel[] servers = ((AbstractSvRunDescriptor) getDescriptor()).getServers(); - if (servers != null) { - for (SvServerSettingsModel serverSettings : servers) { - if (model.getServerName() != null && model.getServerName().equals(serverSettings.getName())) { - return serverSettings; - } - } - } - throw new ConfigurationException("Selected server configuration '" + model.getServerName() + "' does not exist."); - } - - protected abstract void performImpl(@Nonnull Run run, @Nonnull FilePath workspace, Launcher launcher, TaskListener listener) throws Exception; - - protected ICommandExecutor createCommandExecutor() throws Exception { - SvServerSettingsModel serverModel = getSelectedServerSettings(); - return new CommandExecutorFactory().createCommandExecutor(serverModel.getUrlObject(), serverModel.getCredentials()); - } - - @Override - public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { - PrintStream logger = listener.getLogger(); - Date startDate = new Date(); - try { - SvServerSettingsModel serverModel = getSelectedServerSettings(); - - logger.printf("%nStarting %s for SV Server '%s' (%s as %s) on %s%n", getDescriptor().getDisplayName(), - serverModel.getName(), serverModel.getUrlObject(), serverModel.getUsername(), startDate); - logConfig(logger, " "); - validateServiceSelection(); - performImpl(run, workspace, launcher, listener); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Build failed: " + e.getMessage(), e); - throw new AbortException(e.getMessage()); - } finally { - double duration = (new Date().getTime() - startDate.getTime()) / 1000.; - logger.printf("Finished: %s in %.3f seconds%n%n", getDescriptor().getDisplayName(), duration); - } - } - - protected void logConfig(PrintStream logger, String prefix) { - SvServiceSelectionModel ss = model.getServiceSelection(); - switch (ss.getSelectionType()) { - case SERVICE: - logger.println(prefix + "Service name or id: " + ss.getService()); - break; - case PROJECT: - logger.println(prefix + "Project path: " + ss.getProjectPath()); - logger.println(prefix + "Project password: " + ((StringUtils.isNotBlank(ss.getProjectPassword())) ? "*****" : null)); - break; - case ALL_DEPLOYED: - logger.println(prefix + "All deployed services"); - break; - case DEPLOY: - logger.println(prefix + "Project path: " + ss.getProjectPath()); - logger.println(prefix + "Project password: " + ((StringUtils.isNotBlank(ss.getProjectPassword())) ? "*****" : null)); - logger.println(prefix + "Service name or id: " + ss.getService()); - break; - } - logger.println(prefix + "Force: " + model.isForce()); - } - - protected List getServiceList(boolean ignoreMissingServices, PrintStream logger, FilePath workspace) throws Exception { - SvServiceSelectionModel s = getServiceSelection(); - ICommandExecutor exec = createCommandExecutor(); - - ArrayList res = new ArrayList<>(); - - switch (s.getSelectionType()) { - case SERVICE: - addServiceIfDeployed(s.getService(), res, ignoreMissingServices, exec, logger); - break; - case PROJECT: - IProject project = loadProject(workspace); - for (IService svc : project.getServices()) { - addServiceIfDeployed(svc.getId(), res, ignoreMissingServices, exec, logger); - } - break; - case ALL_DEPLOYED: - for (ServiceListAtom.ServiceEntry entry : exec.getServiceList(null).getEntries()) { - res.add(new ServiceInfo(entry.getId(), entry.getTitle())); - } - break; - case DEPLOY: - break; - } - return res; - } - - private void addServiceIfDeployed(String service, ArrayList results, boolean ignoreMissingServices, - ICommandExecutor exec, PrintStream logger) throws CommunicatorException, CommandExecutorException { - try { - IService svc = exec.findService(service, null); - results.add(new ServiceInfo(svc.getId(), svc.getName())); - } catch (CommandExecutorException e) { - if (!ignoreMissingServices) { - throw e; - } - logger.printf("Service '%s' is not deployed, ignoring%n", service); - } - } - - protected IProject loadProject(FilePath workspace) throws ProjectBuilderException { - SvServiceSelectionModel s = getServiceSelection(); - FilePath projectPath = workspace.child(s.getProjectPath()); - return new ProjectBuilder().buildProject(new File(projectPath.getRemote()), s.getProjectPassword()); - } - - protected void validateServiceSelection() throws ConfigurationException { - SvServiceSelectionModel s = getServiceSelection(); - switch (s.getSelectionType()) { - case SERVICE: - verifyNotNull(s.getService(), "Service name or id must not be empty if service selection by name or id set"); - break; - case PROJECT: - verifyNotNull(s.getProjectPath(), "Project path must not be empty if service selection by project is set"); - break; - case ALL_DEPLOYED: - break; - case DEPLOY: - verifyNotNull(s.getProjectPath(), "Project path must not be empty for deployment"); - break; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunDescriptor.java b/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunDescriptor.java deleted file mode 100644 index def430c4ca..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/AbstractSvRunDescriptor.java +++ /dev/null @@ -1,57 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; - -import com.hp.application.automation.tools.model.SvServerSettingsModel; -import com.hp.application.automation.tools.settings.SvServerSettingsBuilder; -import hudson.model.AbstractProject; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.ListBoxModel; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; - -public abstract class AbstractSvRunDescriptor extends BuildStepDescriptor { - private final String displayName; - - protected AbstractSvRunDescriptor(String displayName) { - this.displayName = displayName; - load(); - } - - @Override - public boolean isApplicable(@SuppressWarnings("rawtypes") Class jobType) { - return true; - } - - @Nonnull - @Override - public String getDisplayName() { - return displayName; - } - - public SvServerSettingsModel[] getServers() { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins == null) { - throw new IllegalStateException("Cannot get Jenkins instance, probably not running inside Jenkins"); - } - return jenkins.getDescriptorByType(SvServerSettingsBuilder.DescriptorImpl.class).getServers(); - } - - @SuppressWarnings("unused") - public ListBoxModel doFillServerNameItems() { - ListBoxModel items = new ListBoxModel(); - for (SvServerSettingsModel server : getServers()) { - if (StringUtils.isNotBlank(server.getName())) { - items.add(server.getName(), server.getName()); - } - } - - return items; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/AlmRunTypes.java b/src/main/java/com/hp/application/automation/tools/run/AlmRunTypes.java deleted file mode 100644 index 75b4f4a7c4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/AlmRunTypes.java +++ /dev/null @@ -1,13 +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. - -package com.hp.application.automation.tools.run; -public class AlmRunTypes { - - public enum RunType { - Alm, FileSystem, LoadRunner - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/run/AutEnvironmentBuilder.java b/src/main/java/com/hp/application/automation/tools/run/AutEnvironmentBuilder.java deleted file mode 100644 index c64dad8186..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/AutEnvironmentBuilder.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.hp.application.automation.tools.run; - -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.kohsuke.stapler.DataBoundConstructor; - -import com.hp.application.automation.tools.model.AUTEnvironmentModelResolver; -import com.hp.application.automation.tools.model.AUTEnvironmentResolvedModel; -import com.hp.application.automation.tools.model.AlmServerSettingsModel; -import com.hp.application.automation.tools.model.AutEnvironmentModel; -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; -import com.hp.application.automation.tools.sse.autenvironment.AUTEnvironmentBuilderPerformer; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.sdk.Logger; - -import hudson.EnvVars; -import hudson.Extension; -import hudson.Launcher; -import hudson.model.*; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.VariableResolver; - -/** - * Created by barush on 21/10/2014. - */ -public class AutEnvironmentBuilder extends Builder { - - private final AutEnvironmentModel autEnvironmentModel; - - @DataBoundConstructor - public AutEnvironmentBuilder(AutEnvironmentModel autEnvironmentModel) { - - this.autEnvironmentModel = autEnvironmentModel; - - } - - public AutEnvironmentModel getAutEnvironmentModel() { - return autEnvironmentModel; - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) - throws InterruptedException, IOException { - - autEnvironmentModel.setAlmServerUrl(getServerUrl(autEnvironmentModel.getAlmServerName())); - PrintStream logger = listener.getLogger(); - EnvVars envVars = build.getEnvironment(listener); - execute(build, envVars, autEnvironmentModel, logger); - - return true; - } - - public String getServerUrl(String almServerName) { - - String ret = ""; - AlmServerSettingsModel[] almServers = getDescriptor().getAlmServers(); - if (almServers != null && almServers.length > 0) { - for (AlmServerSettingsModel almServer : almServers) { - if (almServerName.equals(almServer.getAlmServerName())) { - ret = almServer.getAlmServerUrl(); - break; - } - } - } - - return ret; - } - - private void execute( - AbstractBuild build, - EnvVars envVars, - AutEnvironmentModel autEnvironmentModel, - final PrintStream printStreamLogger) throws InterruptedException { - - AUTEnvironmentBuilderPerformer performer; - try { - Logger logger = new Logger() { - - public void log(String message) { - printStreamLogger.println(message); - } - }; - VariableResolver.ByMap variableResolver = - new VariableResolver.ByMap(envVars); - - AUTEnvironmentResolvedModel autEnvModel = - AUTEnvironmentModelResolver.resolveModel(autEnvironmentModel, variableResolver); - performer = new AUTEnvironmentBuilderPerformer(autEnvModel, variableResolver, logger); - performer.start(); - assignOutputValue(build, performer, autEnvModel.getOutputParameter(), logger); - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - throw e; - } catch (Throwable cause) { - build.setResult(Result.FAILURE); - } - - } - - private void assignOutputValue( - AbstractBuild build, - AUTEnvironmentBuilderPerformer performer, - String outputParameterName, - Logger logger) { - - if (StringUtils.isNullOrEmpty(outputParameterName)) { - logger.log("No environment variable was specified for getting the AUT Environment Configuration ID"); - return; - } - - ParametersAction oldParametersAction = build.getAction(ParametersAction.class); - if (oldParametersAction != null - && oldParametersAction.getParameter(outputParameterName) != null) { - - List parametersList = - new ArrayList(oldParametersAction.getParameters()); - Iterator iterator = parametersList.iterator(); - while (iterator.hasNext()) { - ParameterValue nextValue = iterator.next(); - if (nextValue.getName().equals(outputParameterName)) { - if (!(nextValue instanceof StringParameterValue)) { - logger.log(String.format( - "Can't assign value to %s because it's type is not 'String Parameter'", - outputParameterName)); - return; - } - parametersList.remove(nextValue); - parametersList.add(new StringParameterValue( - nextValue.getName(), - performer.getAutEnvironmentConfigurationIdToReturn(), - nextValue.getDescription())); - break; - } - } - - build.getActions().remove(oldParametersAction); - build.addAction(new ParametersAction(parametersList)); - - } else { - logger.log(String.format( - "Can't assign created AUT Environment Configuration ID to: [%s] because there's no such parameter for this build", - outputParameterName)); - } - - } - - @Extension - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - - load(); - } - - @Override - public boolean isApplicable(Class aClass) { - return true; - } - - @Override - public String getDisplayName() { - - return "Execute AUT Environment preparation using HP ALM Lab Management"; - } - - public AlmServerSettingsModel[] getAlmServers() { - - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/PcBuilder.java b/src/main/java/com/hp/application/automation/tools/run/PcBuilder.java deleted file mode 100644 index 21f2c37899..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/PcBuilder.java +++ /dev/null @@ -1,732 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 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. - */ - -package com.hp.application.automation.tools.run; - -import com.hp.application.automation.tools.common.PcException; -import com.hp.application.automation.tools.model.PcModel; -import com.hp.application.automation.tools.model.PostRunAction; -import com.hp.application.automation.tools.model.SecretContainer; -import com.hp.application.automation.tools.model.TimeslotDuration; -import com.hp.application.automation.tools.pc.*; -import com.hp.application.automation.tools.sse.result.model.junit.Error; -import com.hp.application.automation.tools.sse.result.model.junit.Failure; -import com.hp.application.automation.tools.sse.result.model.junit.*; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.console.HyperlinkNote; -import hudson.model.*; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.util.FormValidation; -import jenkins.tasks.SimpleBuildStep; -import org.apache.commons.lang.StringUtils; -import org.apache.http.client.ClientProtocolException; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import javax.annotation.Nonnull; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import java.io.IOException; -import java.io.PrintStream; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; - -import static com.hp.application.automation.tools.pc.RunState.FINISHED; -import static com.hp.application.automation.tools.pc.RunState.RUN_FAILURE; - -public class PcBuilder extends Builder implements SimpleBuildStep{ - - private static final String artifactsDirectoryName = "archive"; - public static final String artifactsResourceName = "artifact"; - public static final String runReportStructure = "%s/%s/performanceTestsReports/pcRun%s"; - public static final String trendReportStructure = "%s/%s/performanceTestsReports/TrendReports"; - public static final String pcReportArchiveName = "Reports.zip"; - public static final String pcReportFileName = "Report.html"; - private static final String RUNID_BUILD_VARIABLE = "HP_RUN_ID"; - - public static final String TRENDED = "Trended"; - public static final String PENDING = "Pending"; - public static final String PUBLISHING = "Publishing"; - public static final String ERROR = "Error"; - - private final PcModel pcModel; - - - private final String almPassword; - private final String timeslotDurationHours; - private final String timeslotDurationMinutes; - private final boolean statusBySLA; - private int runId; - private FilePath pcReportFile; - private String junitResultsFileName; - private PrintStream logger; - // private boolean trendReportReady; - - @DataBoundConstructor - public PcBuilder( - String pcServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String testId, - String testInstanceId, - String timeslotDurationHours, - String timeslotDurationMinutes, - PostRunAction postRunAction, - boolean vudsMode, - boolean statusBySLA, - String description, - boolean addRunToTrendReport, - String trendReportId) { - this.almUserName = almUserName; - this.almPassword = almPassword; - this.timeslotDurationHours = timeslotDurationHours; - this.timeslotDurationMinutes = timeslotDurationMinutes; - this.statusBySLA = statusBySLA; - - pcModel = - new PcModel( - pcServerName.trim(), - almUserName.trim(), - almPassword, - almDomain.trim(), - almProject.trim(), - testId.trim(), - testInstanceId.trim(), - timeslotDurationHours.trim(), - timeslotDurationMinutes.trim(), - postRunAction, - vudsMode, - description, - addRunToTrendReport, - trendReportId); - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) - throws InterruptedException, IOException { - perform(build, build.getWorkspace(), launcher, listener); - - return true; - } - - public PcModel getPcModel() { - - return pcModel; - } - - public String getRunResultsFileName() { - - return junitResultsFileName; - } - - public static String getArtifactsDirectoryName() { - - return artifactsDirectoryName; - } - - public static String getArtifactsResourceName() { - - return artifactsResourceName; - } - - public static String getRunReportStructure() { - - return runReportStructure; - } - - public static String getPcReportArchiveName() { - - return pcReportArchiveName; - } - - public static String getPcreportFileName() { - - return pcReportFileName; - } - - private Testsuites execute(PcClient pcClient, Run build) - throws InterruptedException,NullPointerException { - try { - if (!StringUtils.isBlank(pcModel.getDescription())) - logger.println("- - -\nTest description: " + pcModel.getDescription()); - if (!beforeRun(pcClient)) - return null; - - return run(pcClient, build); - - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - pcClient.stopRun(runId); - throw e; - } catch (NullPointerException e) { - logger.println("Error: Run could not start!"); - } catch (Exception e) { - logger.println(e); - } finally { - pcClient.logout(); - } - return null; - } - - - private Testsuites run(PcClient pcClient, Run build) - throws InterruptedException, ClientProtocolException, - IOException, PcException { - - PcRunResponse response = null; - String errorMessage = ""; - String eventLogString = ""; - boolean trendReportReady = false; - try { - runId = pcClient.startRun(); - - // This allows a user to access the runId from within Jenkins using a build variable. - build.addAction(new ParametersAction(new StringParameterValue(RUNID_BUILD_VARIABLE, "" + runId))); - logger.print("Set " + RUNID_BUILD_VARIABLE + " Env Variable to " + runId + "\n"); - - response = pcClient.waitForRunCompletion(runId); - - - if (response != null && RunState.get(response.getRunState()) == FINISHED) { - pcReportFile = pcClient.publishRunReport(runId, getReportDirectory(build)); - - // Adding the trend report section - if(pcModel.isAddRunToTrendReport() && pcModel.getTrendReportId() != null && RunState.get(response.getRunState()) != RUN_FAILURE){ - pcClient.addRunToTrendReport(this.runId, pcModel.getTrendReportId()); - pcClient.waitForRunToPublishOnTrendReport(this.runId, pcModel.getTrendReportId()); - pcClient.downloadTrendReportAsPdf(pcModel.getTrendReportId(), getTrendReportsDirectory(build)); - trendReportReady = true; - } - - } else if (response != null && RunState.get(response.getRunState()).ordinal() > FINISHED.ordinal()) { - PcRunEventLog eventLog = pcClient.getRunEventLog(runId); - eventLogString = buildEventLogString(eventLog); - } - - - } catch (PcException e) { - errorMessage = e.getMessage(); - logger.println("Error: " + errorMessage); - } - - Testsuites ret = new Testsuites(); - parsePcRunResponse(ret,response, build, errorMessage, eventLogString); - parsePcTrendResponse(ret,pcClient,trendReportReady,pcModel.getTrendReportId(),runId); - return ret; - } - - private String buildEventLogString(PcRunEventLog eventLog) { - - String logFormat = "%-5s | %-7s | %-19s | %s\n"; - StringBuilder eventLogStr = new StringBuilder("Event Log:\n\n" + String.format(logFormat, "ID", "TYPE", "TIME","DESCRIPTION")); - for (PcRunEventLogRecord record : eventLog.getRecordsList()) { - eventLogStr.append(String.format(logFormat, record.getID(), record.getType(), record.getTime(), record.getDescription())); - } - return eventLogStr.toString(); - } - - private boolean beforeRun(PcClient pcClient) { - return validatePcForm() && pcClient.login(); - } - - private String getReportDirectory(Run build) { - return String.format( - runReportStructure, - build.getRootDir().getPath(), - artifactsDirectoryName, - runId); - } - - private String getTrendReportsDirectory(Run build) { - return String.format( - trendReportStructure, - build.getRootDir().getPath(), - artifactsDirectoryName); - } - - - @Override - @Deprecated - public boolean perform(Build build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - return super.perform(build, launcher, listener); - } - - private boolean validatePcForm() { - - logger.println("Validating parameters before run"); - String prefix = "doCheck"; - boolean ret = true; - Method[] methods = getDescriptor().getClass().getMethods(); - Method[] modelMethods = pcModel.getClass().getMethods(); - for (Method method : methods) { - String name = method.getName(); - if (name.startsWith(prefix)) { - name = name.replace(prefix, "").toLowerCase(); - for (Method modelMethod : modelMethods) { - String modelMethodName = modelMethod.getName(); - if (modelMethodName.toLowerCase().equals("get" + name)) { - try { - Object obj = - method.invoke(getDescriptor(), modelMethod.invoke(getPcModel())); - if (!obj.equals(FormValidation.ok())) { - logger.println(obj); - ret = false; - } - break; - } catch (Exception e) { - logger.println(e); - } - } - } - } - } - - boolean isTrendReportIdValid = validateTrendReportIdIsNumeric(getPcModel().getTrendReportId(), - getPcModel().isAddRunToTrendReport()); - - ret &= isTrendReportIdValid; - return ret; - - } - - private boolean validateTrendReportIdIsNumeric(String trendReportId, boolean addRunToTrendReport){ - - FormValidation res = FormValidation.ok(); - if(addRunToTrendReport){ - if(trendReportId.isEmpty()){ - res = FormValidation.error("Parameter Is Missing: trend report ID is missing"); - } - else{ - - try{ - - Integer.parseInt(trendReportId); - } - catch(NumberFormatException e) { - - res = FormValidation.error("Illegal Parameter: trend report ID is is not a number"); - } - - } - } - - logger.println(res.toString().replace(":

","")); - - return res.equals(FormValidation.ok()); - } - - private Testsuites parsePcRunResponse(Testsuites ret, - PcRunResponse runResponse, - Run build, - String errorMessage, String eventLogString) throws IOException, InterruptedException { - - RunState runState = RunState.get(runResponse.getRunState()); - - - List testSuites = ret.getTestsuite(); - Testsuite testSuite = new Testsuite(); - Testcase testCase = new Testcase(); - testCase.setClassname("Performance Tests.Test ID: " + runResponse.getTestID()); - testCase.setName("Run ID: " + runResponse.getID()); - testCase.setTime(String.valueOf(runResponse.getDuration() * 60)); - if (pcReportFile != null && pcReportFile.exists() && runState == FINISHED) - testCase.getSystemOut().add(getOutputForReportLinks(build)); - updateTestStatus(testCase, runResponse, errorMessage, eventLogString); - testSuite.getTestcase().add(testCase); - testSuites.add(testSuite); - return ret; - } - - private Testsuites parsePcTrendResponse(Testsuites ret,PcClient pcClient,boolean trendReportReady,String TrendReportID, int runID) throws IOException, InterruptedException { - - - // Create Trend Report - if(trendReportReady){ - List testSuites = ret.getTestsuite(); - Testsuite testSuite = new Testsuite(); - Testcase testCase = new Testcase(); - - String reportUrlTemp = trendReportStructure.replaceFirst("%s/", "") + "/trendReport%s.pdf"; - String reportUrl = String.format(reportUrlTemp, artifactsResourceName, pcModel.getTrendReportId()); - - testCase.setClassname("Trend report publishing .Trend Report ID: " + TrendReportID); - testCase.setName("Run ID: " + runID); - pcClient.publishTrendReport(reportUrl, pcModel.getTrendReportId()); - //testCase.setTime(String.valueOf(runResponse.getDuration() * 60)); - testCase.setStatus(JUnitTestCaseStatus.PASS); - testSuite.getTestcase().add(testCase); - testSuites.add(testSuite); - } - // End Create Trend Report - - return ret; - } - - private void updateTestStatus(Testcase testCase, PcRunResponse response, String errorMessage, String eventLog) { - RunState runState = RunState.get(response.getRunState()); - if (runState == RUN_FAILURE) { - setError(testCase, String.format("%s. %s", runState, errorMessage), eventLog); - } else if (statusBySLA && runState == FINISHED && !(response.getRunSLAStatus().equalsIgnoreCase("passed"))) { - setFailure(testCase, "Run measurements did not reach SLA criteria. Run SLA Status: " - + response.getRunSLAStatus(), eventLog); - } else if (runState.hasFailure()) { - setFailure(testCase, String.format("%s. %s", runState, errorMessage), eventLog); - } else if(errorMessage != null && !errorMessage.isEmpty()){ - setFailure(testCase, String.format("%s. %s", runState, errorMessage), eventLog); - } - else{ - testCase.setStatus(JUnitTestCaseStatus.PASS); - } - } - - private void setError(Testcase testCase, String message, String eventLog) { - Error error = new Error(); - error.setMessage(message); - if (!(eventLog == null || eventLog.isEmpty())) - testCase.getSystemErr().add(eventLog); - testCase.getError().add(error); - testCase.setStatus(JUnitTestCaseStatus.ERROR); - logger.println(String.format("%s %s", message ,eventLog)); - } - - private void setFailure(Testcase testCase, String message, String eventLog) { - Failure failure = new Failure(); - failure.setMessage(message); - if (!(eventLog == null || eventLog.isEmpty())) - testCase.getSystemErr().add(eventLog); - testCase.getFailure().add(failure); - testCase.setStatus(JUnitTestCaseStatus.FAILURE); - logger.println(String.format("Failure: %s %s", message ,eventLog)); - } - - private String getOutputForReportLinks(Run build) { - String urlPattern = getArtifactsUrlPattern(build); - String viewUrl = String.format(urlPattern, pcReportFileName); - String downloadUrl = String.format(urlPattern, "*zip*/pcRun" + runId); - logger.println(HyperlinkNote.encodeTo(viewUrl, "View analysis report of run " + runId)); - return String.format("View analysis report:\n%s\n\n\nDownload Report:\n%s", viewUrl, downloadUrl); - - } - - private String getArtifactsUrlPattern(Run build) { - - String runReportUrlTemp = runReportStructure.replaceFirst("%s/", ""); - return String.format( - runReportUrlTemp, - artifactsResourceName, - runId + "/%s"); - } - - private void provideStepResultStatus(Result resultStatus, Run build) { - String runIdStr = - (runId > 0) ? String.format(" (PC RunID: %s)", String.valueOf(runId)) : ""; - logger.println(String.format( - "Result Status%s: %s\n- - -", - runIdStr, - resultStatus.toString())); - build.setResult(resultStatus); - - } - - private Result createRunResults(FilePath filePath, Testsuites testsuites) { - Result ret = Result.SUCCESS; - try { - if (testsuites != null) { - StringWriter writer = new StringWriter(); - JAXBContext context = JAXBContext.newInstance(Testsuites.class); - Marshaller marshaller = context.createMarshaller(); - marshaller.marshal(testsuites, writer); - filePath.write(writer.toString(), null); - if (containsErrorsOrFailures(testsuites.getTestsuite())) { - ret = Result.UNSTABLE; - } - } else { - logger.println("Empty Results"); - ret = Result.UNSTABLE; - } - - } catch (Exception cause) { - logger.print(String.format( - "Failed to create run results, Exception: %s", - cause.getMessage())); - ret = Result.UNSTABLE; - } - return ret; - } - - private boolean containsErrorsOrFailures(List testsuites) { - boolean ret = false; - for (Testsuite testsuite : testsuites) { - for (Testcase testcase : testsuite.getTestcase()) { - String status = testcase.getStatus(); - if (status.equals(JUnitTestCaseStatus.ERROR) - || status.equals(JUnitTestCaseStatus.FAILURE)) { - ret = true; - break; - } - } - } - return ret; - } - - private String getJunitResultsFileName() { - Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); - String time = formatter.format(new Date()); - junitResultsFileName = String.format("Results%s.xml", time); - return junitResultsFileName; - } - - @Override - public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, - @Nonnull TaskListener listener) throws InterruptedException, IOException { - Result resultStatus = Result.FAILURE; - //trendReportReady = false; - logger = listener.getLogger(); - PcClient pcClient = new PcClient(pcModel, logger); - Testsuites testsuites = execute(pcClient, build); - -// // Create Trend Report -// if(trendReportReady){ -// String reportUrlTemp = trendReportStructure.replaceFirst("%s/", "") + "/trendReport%s.pdf"; -// String reportUrl = String.format(reportUrlTemp, artifactsResourceName, pcModel.getTrendReportId()); -// pcClient.publishTrendReport(reportUrl, pcModel.getTrendReportId()); -// } -// // End Create Trend Report - - FilePath resultsFilePath = workspace.child(getJunitResultsFileName()); - resultStatus = createRunResults(resultsFilePath, testsuites); - provideStepResultStatus(resultStatus, build); - - if (!Result.SUCCESS.equals(resultStatus) && !Result.FAILURE.equals(resultStatus)) { - return; - } - //Only do this if build worked (Not unstable or aborted - which might mean there is no report - JUnitResultArchiver jUnitResultArchiver = new JUnitResultArchiver(this.getRunResultsFileName()); - jUnitResultArchiver.setKeepLongStdio(true); - jUnitResultArchiver.perform(build, workspace, launcher, listener); - - } - - public String getPcServerName() - { - return getPcModel().getPcServerName(); - } - - public String getAlmProject() - { - return getPcModel().getAlmProject(); - } - public String getTestId() - { - return getPcModel().getTestId(); - } - public String getAlmDomain() - { - return getPcModel().getAlmDomain(); - } - public String getTimeslotDurationHours() - { - return timeslotDurationHours; - } - public String getTimeslotDurationMinutes() - { - return timeslotDurationMinutes; - } - public PostRunAction getPostRunAction() - { - return getPcModel().getPostRunAction(); - } - - public String getTrendReportId() - { - return getPcModel().getTrendReportId(); - } - - public String getTestInstanceId() - { - return getPcModel().getTestInstanceId(); - } - - - public boolean isAddRunToTrendReport() - { - return getPcModel().isAddRunToTrendReport(); - } - - public boolean isVudsMode() - { - return getPcModel().isVudsMode(); - } - - public String getDescription() - { - return getPcModel().getDescription(); - } - public String getAlmUserName() { - return almUserName; - } - - private final String almUserName; - - public String getAlmPassword() { - return almPassword; - } - - public boolean isStatusBySLA() { - return statusBySLA; - } - - // This indicates to Jenkins that this is an implementation of an extension - // point - @Extension - @Symbol("pcBuild") - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - - load(); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - - return true; - } - - @Override - public String getDisplayName() { - - return "Execute HP tests using HP Performance Center"; - } - - public FormValidation doCheckPcServerName(@QueryParameter String value) { - - return validateString(value, "PC Server"); - } - - public FormValidation doCheckAlmUserName(@QueryParameter String value) { - - return validateString(value, "User name"); - } - - public FormValidation doCheckAlmDomain(@QueryParameter String value) { - - return validateString(value, "Domain"); - } - - public FormValidation doCheckAlmProject(@QueryParameter String value) { - - return validateString(value, "Project"); - } - - public FormValidation doCheckTestId(@QueryParameter String value) { - - return validateHigherThanInt(value, "Test ID", 0, true); - } - - public FormValidation doCheckTestInstanceId(@QueryParameter String value) { - - return validateHigherThanInt(value, "Test Instance ID", 0, true); - } - - public FormValidation doCheckTimeslotDuration(@QueryParameter TimeslotDuration value) { - - return validateHigherThanInt( - String.valueOf(value.toMinutes()), - "Timeslot Duration (in minutes)", - 30, - false); - } - - public FormValidation doCheckTimeslotId(@QueryParameter String value) { - - return validateHigherThanInt(value, "Timeslot ID", 0, true); - } - - - /** - * @param limitIncluded - * if true, value must be higher than limit. if false, value must be equal to or - * higher than limit. - */ - private FormValidation validateHigherThanInt( - String value, - String field, - int limit, - boolean limitIncluded) { - FormValidation ret = FormValidation.ok(); - value = value.trim(); - String messagePrefix = field + " must be "; - if (StringUtils.isBlank(value)) { - ret = FormValidation.error(messagePrefix + "set"); - } else { - try { - if (limitIncluded && Integer.parseInt(value) <= limit) - ret = FormValidation.error(messagePrefix + "higher than " + limit); - else if (Integer.parseInt(value) < limit) - ret = FormValidation.error(messagePrefix + "at least " + limit); - } catch (Exception e) { - ret = FormValidation.error(messagePrefix + "a whole number"); - } - } - - return ret; - - } - - private FormValidation validateString(String value, String field) { - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value.trim())) { - ret = FormValidation.error(field + " must be set"); - } - - return ret; - } - - - - public List getPostRunActions() { - - return PcModel.getPostRunActions(); - } - - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/run/RunFromAlmBuilder.java b/src/main/java/com/hp/application/automation/tools/run/RunFromAlmBuilder.java deleted file mode 100644 index 13eb0e1dca..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/RunFromAlmBuilder.java +++ /dev/null @@ -1,389 +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. - -package com.hp.application.automation.tools.run; - -import hudson.EnvVars; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.Util; - -import hudson.model.Result; -import hudson.model.AbstractProject; -import hudson.model.Hudson; -import hudson.model.Run; -import hudson.model.TaskListener; - -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import hudson.util.IOUtils; -import hudson.util.VariableResolver; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.net.URL; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.Properties; - -import jenkins.tasks.SimpleBuildStep; -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -import com.hp.application.automation.tools.AlmToolsUtils; -import com.hp.application.automation.tools.EncryptionUtils; -import com.hp.application.automation.tools.model.AlmServerSettingsModel; -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.RunFromAlmModel; -import com.hp.application.automation.tools.run.AlmRunTypes.RunType; -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; - -public class RunFromAlmBuilder extends Builder implements SimpleBuildStep { - - private final RunFromAlmModel runFromAlmModel; - private final static String HpToolsLauncher_SCRIPT_NAME = "HpToolsLauncher.exe"; - private String ResultFilename = "ApiResults.xml"; - private String ParamFileName = "ApiRun.txt"; - //private String KillFileName = ""; - - @DataBoundConstructor - public RunFromAlmBuilder( - String almServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String almTestSets, - String almRunResultsMode, - String almTimeout, - String almRunMode, - String almRunHost) { - - runFromAlmModel = - new RunFromAlmModel( - almServerName, - almUserName, - almPassword, - almDomain, - almProject, - almTestSets, - almRunResultsMode, - almTimeout, - almRunMode, - almRunHost); - } - - public String getAlmServerName(){ - return runFromAlmModel.getAlmServerName(); - } - - public String getAlmUserName(){ - return runFromAlmModel.getAlmUserName(); - } - - public String getAlmPassword(){ - return runFromAlmModel.getAlmPassword(); - } - - public String getAlmDomain(){ - return runFromAlmModel.getAlmDomain(); - } - - public String getAlmProject(){ - return runFromAlmModel.getAlmProject(); - } - - public String getAlmTestSets(){ - return runFromAlmModel.getAlmTestSets(); - } - - public String getAlmRunResultsMode(){ - return runFromAlmModel.getAlmRunResultsMode(); - } - - public String getAlmTimeout(){ - return runFromAlmModel.getAlmTimeout(); - } - - public String getAlmRunMode(){ - return runFromAlmModel.getAlmRunMode(); - } - - public String getAlmRunHost(){ - return runFromAlmModel.getAlmRunHost(); - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public void perform(Run build, FilePath workspace, Launcher launcher, - TaskListener listener) throws InterruptedException, IOException { - - // get the alm server settings - AlmServerSettingsModel almServerSettingsModel = getAlmServerSettingsModel(); - - if (almServerSettingsModel == null) { - listener.fatalError("An ALM server is not defined. Go to Manage Jenkins->Configure System and define your ALM server under Application Lifecycle Management"); - return; - } - - EnvVars env = null; - try { - env = build.getEnvironment(listener); - } catch (IOException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } - VariableResolver varResolver = new VariableResolver.ByMap(build.getEnvironment(listener)); - - // now merge them into one list - Properties mergedProperties = new Properties(); - - mergedProperties.putAll(almServerSettingsModel.getProperties()); - mergedProperties.putAll(runFromAlmModel.getProperties(env, varResolver)); - - String encAlmPass = ""; - try { - - encAlmPass = - EncryptionUtils.Encrypt( - runFromAlmModel.getAlmPassword(), - EncryptionUtils.getSecretKey()); - - mergedProperties.remove(RunFromAlmModel.ALM_PASSWORD_KEY); - mergedProperties.put(RunFromAlmModel.ALM_PASSWORD_KEY, encAlmPass); - - } catch (Exception e) { - build.setResult(Result.FAILURE); - listener.fatalError("problem in qcPassword encription"); - } - - Date now = new Date(); - Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); - String time = formatter.format(now); - - // get a unique filename for the params file - ParamFileName = "props" + time + ".txt"; - ResultFilename = "Results" + time + ".xml"; - //KillFileName = "stop" + time + ".txt"; - - mergedProperties.put("runType", RunType.Alm.toString()); - mergedProperties.put("resultsFilename", ResultFilename); - - // get properties serialized into a stream - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - mergedProperties.store(stream, ""); - } catch (IOException e) { - build.setResult(Result.FAILURE); - // TODO Auto-generated catch block - e.printStackTrace(); - } - String propsSerialization = stream.toString(); - InputStream propsStream = IOUtils.toInputStream(propsSerialization); - - // get the remote workspace filesys - FilePath projectWS = workspace; - - // Get the URL to the Script used to run the test, which is bundled - // in the plugin - URL cmdExeUrl = - Hudson.getInstance().pluginManager.uberClassLoader.getResource(HpToolsLauncher_SCRIPT_NAME); - if (cmdExeUrl == null) { - listener.fatalError(HpToolsLauncher_SCRIPT_NAME + " not found in resources"); - return; - } - - FilePath propsFileName = projectWS.child(ParamFileName); - FilePath CmdLineExe = projectWS.child(HpToolsLauncher_SCRIPT_NAME); - - try { - // create a file for the properties file, and save the properties - propsFileName.copyFrom(propsStream); - - // Copy the script to the project workspace - CmdLineExe.copyFrom(cmdExeUrl); - } catch (IOException e1) { - build.setResult(Result.FAILURE); - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - try { - // Run the HpToolsLauncher.exe - AlmToolsUtils.runOnBuildEnv(build, launcher, listener, CmdLineExe, ParamFileName); - } catch (IOException ioe) { - Util.displayIOException(ioe, listener); - build.setResult(Result.FAILURE); - return; - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - PrintStream out = listener.getLogger(); - // kill processes - //FilePath killFile = projectWS.child(KillFileName); - /* try { - out.println("Sending abort command"); - killFile.write("\n", "UTF-8"); - while (!killFile.exists()) - Thread.sleep(1000); - Thread.sleep(1500); - - } catch (IOException e1) { - //build.setResult(Result.FAILURE); - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (InterruptedException e1) { - //build.setResult(Result.FAILURE); - // TODO Auto-generated catch block - e1.printStackTrace(); - }*/ - - try { - AlmToolsUtils.runHpToolsAborterOnBuildEnv(build, launcher, listener, ParamFileName, workspace); - } catch (IOException e1) { - Util.displayIOException(e1, listener); - build.setResult(Result.FAILURE); - return; - } catch (InterruptedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - out.println("Operation was aborted by user."); - //build.setResult(Result.FAILURE); - } - return; - - } - - public AlmServerSettingsModel getAlmServerSettingsModel() { - for (AlmServerSettingsModel almServer : getDescriptor().getAlmServers()) { - if (this.runFromAlmModel != null - && runFromAlmModel.getAlmServerName().equals(almServer.getAlmServerName())) { - return almServer; - } - } - return null; - } - - public RunFromAlmModel getRunFromAlmModel() { - return runFromAlmModel; - } - - // This indicates to Jenkins that this is an implementation of an extension - // point. - @Extension - // To expose this builder in the Snippet Generator. - @Symbol("runFromAlmBuilder") - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - load(); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - return true; - } - - @Override - public String getDisplayName() { - return "Execute HP functional tests from HP ALM"; - } - - public boolean hasAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).hasAlmServers(); - } - - public AlmServerSettingsModel[] getAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - } - - public FormValidation doCheckAlmUserName(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("User name must be set"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmTimeout(@QueryParameter String value) { - - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - String val1 = value.trim(); - - if (val1.length() > 0 && val1.charAt(0) == '-') - val1 = val1.substring(1); - - if (!StringUtils.isNumeric(val1) && val1 != "") { - return FormValidation.error("Timeout name must be a number"); - } - return FormValidation.ok(); - } - - public FormValidation doCheckAlmPassword(@QueryParameter String value) { - // if (StringUtils.isBlank(value)) { - // return FormValidation.error("Password must be set"); - // } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmDomain(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Domain must be set"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmProject(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Project must be set"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmTestSets(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Testsets are missing"); - } - - String[] testSetsArr = value.replaceAll("\r", "").split("\n"); - - for (int i=0; i < testSetsArr.length; i++) { - if (StringUtils.isBlank(testSetsArr[i])) { - return FormValidation.error("Testsets should not contains empty lines"); - } - } - return FormValidation.ok(); - } - - public List getAlmRunModes() { - return RunFromAlmModel.runModes; - } - } - - public String getRunResultsFileName() { - return ResultFilename; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/RunFromFileBuilder.java b/src/main/java/com/hp/application/automation/tools/run/RunFromFileBuilder.java deleted file mode 100644 index 1564ea7109..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/RunFromFileBuilder.java +++ /dev/null @@ -1,695 +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. - -package com.hp.application.automation.tools.run; - -import com.hp.application.automation.tools.AlmToolsUtils; -import com.hp.application.automation.tools.EncryptionUtils; -import com.hp.application.automation.tools.mc.JobConfigurationProxy; -import com.hp.application.automation.tools.model.MCServerSettingsModel; -import com.hp.application.automation.tools.model.ProxySettings; -import com.hp.application.automation.tools.model.RunFromFileSystemModel; -import com.hp.application.automation.tools.run.AlmRunTypes.RunType; -import com.hp.application.automation.tools.settings.MCServerSettingsBuilder; -import hudson.EnvVars; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.Util; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.Result; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import hudson.util.VariableResolver; -import jenkins.model.Jenkins; -import jenkins.tasks.SimpleBuildStep; -import net.minidev.json.JSONObject; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.bind.JavaScriptMethod; - -import javax.annotation.Nonnull; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.net.URL; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Iterator; -import java.util.Objects; -import java.util.Properties; - -/** - * Describs a regular jenkins build step from UFT or LR - */ -public class RunFromFileBuilder extends Builder implements SimpleBuildStep { - - - private String ResultFilename = "ApiResults.xml"; - private String ParamFileName = "ApiRun.txt"; - private final RunFromFileSystemModel runFromFileModel; - private static final String HP_TOOLS_LAUNCHER_EXE = "HpToolsLauncher.exe"; - private static final String LRANALYSIS_LAUNCHER_EXE = "LRAnalysisLauncher.exe"; - - - /** - * Instantiates a new Run from file builder. - * - * @param fsTests the fs tests - */ - @DataBoundConstructor - public RunFromFileBuilder(String fsTests) { - - runFromFileModel = new RunFromFileSystemModel(fsTests); - } - - /** - * Instantiates a new Run from file builder. - * - * @param runFromFileModel the run from file model - */ - public RunFromFileBuilder(RunFromFileSystemModel runFromFileModel) { - - this.runFromFileModel = runFromFileModel; - } - - /** - * @deprecated - * Instantiates a new Run from file builder. - * - * @param fsTests the fs tests - * @param fsTimeout the fs timeout - * @param controllerPollingInterval the controller polling interval - * @param perScenarioTimeOut the per scenario time out - * @param ignoreErrorStrings the ignore error strings - * @param mcServerName the mc server name - * @param fsUserName the fs user name - * @param fsPassword the fs password - * @param fsDeviceId the fs device id - * @param fsTargetLab the fs target lab - * @param fsManufacturerAndModel the fs manufacturer and model - * @param fsOs the fs os - * @param fsAutActions the fs aut actions - * @param fsLaunchAppName the fs launch app name - * @param fsDevicesMetrics the fs devices metrics - * @param fsInstrumented the fs instrumented - * @param fsExtraApps the fs extra apps - * @param fsJobId the fs job id - * @param proxySettings the proxy settings - * @param useSSL the use ssl - */ - @SuppressWarnings("squid:S00107") - @Deprecated - public RunFromFileBuilder(String fsTests, String fsTimeout, String controllerPollingInterval, - String perScenarioTimeOut, String ignoreErrorStrings, String mcServerName, String fsUserName, String fsPassword, String fsDeviceId, String fsTargetLab, - String fsManufacturerAndModel, String fsOs, String fsAutActions, String fsLaunchAppName, String fsDevicesMetrics, String fsInstrumented, String fsExtraApps, String fsJobId, - ProxySettings proxySettings, boolean useSSL) { - - runFromFileModel = new RunFromFileSystemModel(fsTests, fsTimeout, controllerPollingInterval, - perScenarioTimeOut, ignoreErrorStrings, mcServerName, fsUserName, fsPassword, fsDeviceId, fsTargetLab, fsManufacturerAndModel, fsOs, fsAutActions, fsLaunchAppName, - fsDevicesMetrics, fsInstrumented, fsExtraApps, fsJobId, proxySettings, useSSL); - } - - /** - * Gets param file name. - * - * @return the param file name - */ - public String getParamFileName() { - return ParamFileName; - } - - /** - * Sets controller polling interval. - * - * @param controllerPollingInterval the controller polling interval - */ - @DataBoundSetter - public void setControllerPollingInterval(String controllerPollingInterval) { - runFromFileModel.setControllerPollingInterval(controllerPollingInterval); - } - - /** - * Sets per scenario time out. - * - * @param perScenarioTimeOut the per scenario time out - */ - @DataBoundSetter - public void setPerScenarioTimeOut(String perScenarioTimeOut) { - runFromFileModel.setPerScenarioTimeOut(perScenarioTimeOut); - } - - /** - * Sets ignore error strings. - * - * @param ignoreErrorStrings the ignore error strings - */ - @DataBoundSetter - public void setIgnoreErrorStrings(String ignoreErrorStrings) { - runFromFileModel.setIgnoreErrorStrings(ignoreErrorStrings); - } - - /** - * Sets fs timeout. - * - * @param fsTimeout the fs timeout - */ - @DataBoundSetter - public void setFsTimeout(String fsTimeout) { - runFromFileModel.setFsTimeout(fsTimeout); - } - - /** - * Sets mc server name. - * - * @param mcServerName the mc server name - */ - @DataBoundSetter - public void setMcServerName(String mcServerName) { - runFromFileModel.setMcServerName(mcServerName); - } - - /** - * Sets fs user name. - * - * @param fsUserName the fs user name - */ - @DataBoundSetter - public void setFsUserName(String fsUserName) { - runFromFileModel.setFsUserName(fsUserName); - } - - /** - * Sets fs password. - * - * @param fsPassword the fs password - */ - @DataBoundSetter - public void setFsPassword(String fsPassword) { - runFromFileModel.setFsPassword(fsPassword); - } - - /** - * Sets fs device id. - * - * @param fsDeviceId the fs device id - */ - @DataBoundSetter - public void setFsDeviceId(String fsDeviceId) { - runFromFileModel.setFsDeviceId(fsDeviceId); - } - - /** - * Sets fs os. - * - * @param fsOs the fs os - */ - @DataBoundSetter - public void setFsOs(String fsOs) { - runFromFileModel.setFsOs(fsOs); - } - - /** - * Sets fs manufacturer and model. - * - * @param fsManufacturerAndModel the fs manufacturer and model - */ - @DataBoundSetter - public void setFsManufacturerAndModel(String fsManufacturerAndModel) { - runFromFileModel.setFsManufacturerAndModel(fsManufacturerAndModel); - } - - /** - * Sets fs target lab. - * - * @param fsTargetLab the fs target lab - */ - @DataBoundSetter - public void setFsTargetLab(String fsTargetLab) { - runFromFileModel.setFsTargetLab(fsTargetLab); - } - - /** - * Sets fs aut actions. - * - * @param fsAutActions the fs aut actions - */ - @DataBoundSetter - public void setFsAutActions(String fsAutActions) { - runFromFileModel.setFsAutActions(fsAutActions); - } - - /** - * Sets fs launch app name. - * - * @param fsLaunchAppName the fs launch app name - */ - @DataBoundSetter - public void setFsLaunchAppName(String fsLaunchAppName) { - runFromFileModel.setFsLaunchAppName(fsLaunchAppName); - } - - /** - * Sets fs instrumented. - * - * @param fsInstrumented the fs instrumented - */ - @DataBoundSetter - public void setFsInstrumented(String fsInstrumented) { - runFromFileModel.setFsInstrumented(fsInstrumented); - } - - /** - * Sets fs devices metrics. - * - * @param fsDevicesMetrics the fs devices metrics - */ - @DataBoundSetter - public void setFsDevicesMetrics(String fsDevicesMetrics) { - runFromFileModel.setFsDevicesMetrics(fsDevicesMetrics); - } - - /** - * Sets fs extra apps. - * - * @param fsExtraApps the fs extra apps - */ - @DataBoundSetter - public void setFsExtraApps(String fsExtraApps) { - runFromFileModel.setFsExtraApps(fsExtraApps); - } - - /** - * Sets fs job id. - * - * @param fsJobId the fs job id - */ - @DataBoundSetter - public void setFsJobId(String fsJobId) { - runFromFileModel.setFsJobId(fsJobId); - } - - /** - * Sets proxy settings. - * - * @param proxySettings the proxy settings - */ - @DataBoundSetter - public void setProxySettings(ProxySettings proxySettings) { - runFromFileModel.setProxySettings(proxySettings); - } - - @Override - public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) - - throws InterruptedException, IOException { - - // get the mc server settings - MCServerSettingsModel mcServerSettingsModel = getMCServerSettingsModel(); - - EnvVars env = null; - try { - env = build.getEnvironment(listener); - - } catch (IOException | InterruptedException e) { - listener.error("Failed loading build environment " + e); - } - - - - // this is an unproper replacment to the build.getVariableResolver since workflow run won't support the - // getBuildEnviroment() as written here: - // https://github.com/jenkinsci/pipeline-plugin/blob/893e3484a25289c59567c6724f7ce19e3d23c6ee/DEVGUIDE.md#variable-substitutions - - JSONObject jobDetails = null; - String mcServerUrl = ""; - // now merge them into one list - Properties mergedProperties = new Properties(); - if (mcServerSettingsModel != null) { - mcServerUrl = mcServerSettingsModel.getProperties().getProperty("MobileHostAddress"); - if (runFromFileModel.getProxySettings() == null) { - jobDetails = runFromFileModel.getJobDetails(mcServerUrl, null, null, null); - } else { - jobDetails = runFromFileModel.getJobDetails(mcServerUrl, runFromFileModel.getProxySettings().getFsProxyAddress(), runFromFileModel.getProxySettings().getFsProxyUserName(), - runFromFileModel.getProxySettings().getFsProxyPassword()); - } - mergedProperties.setProperty("mobileinfo", jobDetails != null ? jobDetails.toJSONString() : ""); - mergedProperties.setProperty("MobileHostAddress", mcServerUrl); - } - - if (runFromFileModel != null && StringUtils.isNotBlank(runFromFileModel.getFsPassword())) { - String encPassword = ""; - try { - encPassword = EncryptionUtils.Encrypt(runFromFileModel.getFsPassword(), EncryptionUtils.getSecretKey()); - mergedProperties.put("MobilePassword", encPassword); - } catch (Exception e) { - build.setResult(Result.FAILURE); - listener.fatalError("problem in mobile center password encryption" + e); - } - } - - if(env == null) - { - listener.fatalError("Enviroment not set"); - throw new IOException("Env Null - something went wrong with fetching jenkins build environment"); - } - if(build instanceof AbstractBuild) - { - VariableResolver varResolver = ((AbstractBuild) build).getBuildVariableResolver(); - mergedProperties.putAll(runFromFileModel.getProperties(env, varResolver)); - } - else - { - mergedProperties.putAll(runFromFileModel.getProperties(env)); - } - - - int idx = 0; - for (Iterator iterator = env.keySet().iterator(); iterator.hasNext(); ) { - String key = iterator.next(); - idx++; - mergedProperties.put("JenkinsEnv" + idx, key + ";" + env.get(key)); - } - - Date now = new Date(); - Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); - String time = formatter.format(now); - - // get a unique filename for the params file - ParamFileName = "props" + time + ".txt"; - ResultFilename = "Results" + time + ".xml"; - - mergedProperties.put("runType", RunType.FileSystem.toString()); - mergedProperties.put("resultsFilename", ResultFilename); - - // get properties serialized into a stream - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - mergedProperties.store(stream, ""); - } catch (IOException e) { - listener.error("Storing run variable failed: " + e); - build.setResult(Result.FAILURE); - } - String propsSerialization = stream.toString(); - FilePath CmdLineExe; - try (InputStream propsStream = IOUtils.toInputStream(propsSerialization)) { - - // Get the URL to the Script used to run the test, which is bundled - // in the plugin - @SuppressWarnings("squid:S2259") - URL cmdExeUrl = Jenkins.getInstance().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE); - if (cmdExeUrl == null) { - listener.fatalError(HP_TOOLS_LAUNCHER_EXE + " not found in resources"); - return; - } - - @SuppressWarnings("squid:S2259") - URL cmdExe2Url = Jenkins.getInstance().pluginManager.uberClassLoader.getResource(LRANALYSIS_LAUNCHER_EXE); - if (cmdExe2Url == null) { - listener.fatalError(LRANALYSIS_LAUNCHER_EXE + "not found in resources"); - return; - } - - FilePath propsFileName = workspace.child(ParamFileName); - CmdLineExe = workspace.child(HP_TOOLS_LAUNCHER_EXE); - FilePath CmdLineExe2 = workspace.child(LRANALYSIS_LAUNCHER_EXE); - - try { - // create a file for the properties file, and save the properties - propsFileName.copyFrom(propsStream); - - // Copy the script to the project workspace - CmdLineExe.copyFrom(cmdExeUrl); - - CmdLineExe2.copyFrom(cmdExe2Url); - - } catch (IOException | InterruptedException e) { - build.setResult(Result.FAILURE); - listener.error("Copying executable files to executing node " + e); - } - } - - try { - // Run the HpToolsLauncher.exe - AlmToolsUtils.runOnBuildEnv(build, launcher, listener, CmdLineExe, ParamFileName); - // Has the report been successfully generated? - } catch (IOException ioe) { - Util.displayIOException(ioe, listener); - build.setResult(Result.FAILURE); - listener.error("Failed running HpToolsLauncher " + ioe); - return; - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - PrintStream out = listener.getLogger(); - listener.error("Failed running HpToolsLauncher - build aborted " + e); - - try { - AlmToolsUtils.runHpToolsAborterOnBuildEnv(build, launcher, listener, ParamFileName, workspace); - } catch (IOException e1) { - Util.displayIOException(e1, listener); - build.setResult(Result.FAILURE); - return; - } catch (InterruptedException e1) { - listener.error("Failed running HpToolsAborter " + e1); - } - out.println("Operation Was aborted by user."); - } - } - - /** - * Gets mc server settings model. - * - * @return the mc server settings model - */ - public MCServerSettingsModel getMCServerSettingsModel() { - for (MCServerSettingsModel mcServer : getDescriptor().getMcServers()) { - if (this.runFromFileModel != null - && runFromFileModel.getMcServerName() != null - && mcServer.getMcServerName() != null - && runFromFileModel.getMcServerName().equals(mcServer.getMcServerName())) { - return mcServer; - } - } - return null; - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - /** - * Gets run from file model. - * - * @return the run from file model - */ - public RunFromFileSystemModel getRunFromFileModel() { - return runFromFileModel; - } - - /** - * Gets run results file name. - * - * @return the run results file name - */ - public String getRunResultsFileName() { - return ResultFilename; - } - - /** - * The type Descriptor. - */ - @Extension - public static final class DescriptorImpl extends BuildStepDescriptor { - /** - * The Instance. - */ - JobConfigurationProxy instance = JobConfigurationProxy.getInstance(); - - /** - * Instantiates a new Descriptor. - */ - public DescriptorImpl() { - load(); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - return true; - } - - /** - * Gets job id. - * - * @param mcUrl the mc url - * @param mcUserName the mc user name - * @param mcPassword the mc password - * @param proxyAddress the proxy address - * @param proxyUserName the proxy user name - * @param proxyPassword the proxy password - * @return the job id - */ - @JavaScriptMethod - public String getJobId(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUserName, String proxyPassword) { - return instance.createTempJob(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUserName, proxyPassword); - } - - /** - * Populate app and device json object. - * - * @param mcUrl the mc url - * @param mcUserName the mc user name - * @param mcPassword the mc password - * @param proxyAddress the proxy address - * @param proxyUserName the proxy user name - * @param proxyPassword the proxy password - * @param jobId the job id - * @return the json object - */ - @JavaScriptMethod - public JSONObject populateAppAndDevice(String mcUrl, String mcUserName, String mcPassword, String proxyAddress, String proxyUserName, String proxyPassword, String jobId) { - return instance.getJobJSONData(mcUrl, mcUserName, mcPassword, proxyAddress, proxyUserName, proxyPassword, jobId); - } - - /** - * Gets mc server url. - * - * @param serverName the server name - * @return the mc server url - */ - @SuppressWarnings("squid:S2259") - @JavaScriptMethod - public String getMcServerUrl(String serverName) { - String serverUrl = ""; - MCServerSettingsModel[] servers = Jenkins.getInstance().getDescriptorByType( - MCServerSettingsBuilder.MCDescriptorImpl.class).getInstallations(); - for (MCServerSettingsModel mcServer : servers) { - if (mcServer.getMcServerName().equals(serverName)) { - serverUrl = mcServer.getMcServerUrl(); - } - } - return serverUrl; - } - - @Override - public String getDisplayName() { - return "Execute HP tests from file system"; - } - - /** - * Do check fs tests form validation. - * - * @param value the value - * @return the form validation - */ - @SuppressWarnings("squid:S1172") - public FormValidation doCheckFsTests(@QueryParameter String value) { - return FormValidation.ok(); - } - - /** - * Do check ignore error strings form validation. - * - * @param value the value - * @return the form validation - */ - @SuppressWarnings("squid:S1172") - public FormValidation doCheckIgnoreErrorStrings(@QueryParameter String value) { - - return FormValidation.ok(); - } - - /** - * Do check fs timeout form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckFsTimeout(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - String val1 = value.trim(); - if (val1.length() > 0 && val1.charAt(0) == '-') - val1 = val1.substring(1); - - if (!StringUtils.isNumeric(val1) && !Objects.equals(val1, "")) { - return FormValidation.error("Timeout name must be a number"); - } - return FormValidation.ok(); - } - - /** - * Has mc servers boolean. - * - * @return the boolean - */ - @SuppressWarnings("squid:S2259") - public boolean hasMCServers() { - return Jenkins.getInstance().getDescriptorByType( - MCServerSettingsBuilder.MCDescriptorImpl.class).hasMCServers(); - } - - /** - * Get mc servers mc server settings model [ ]. - * - * @return the mc server settings model [ ] - */ - @SuppressWarnings("squid:S2259") - - public MCServerSettingsModel[] getMcServers() { - return Jenkins.getInstance().getDescriptorByType( - MCServerSettingsBuilder.MCDescriptorImpl.class).getInstallations(); - } - - /** - * Do check controller polling interval form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckControllerPollingInterval(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - if (!StringUtils.isNumeric(value)) { - return FormValidation.error("Controller Polling Interval must be a number"); - } - - return FormValidation.ok(); - } - - /** - * Do check per scenario time out form validation. - * - * @param value the value - * @return the form validation - */ - public FormValidation doCheckPerScenarioTimeOut(@QueryParameter String value) { - if (StringUtils.isEmpty(value)) { - return FormValidation.ok(); - } - - if (!StringUtils.isNumeric(value)) { - return FormValidation.error("Per Scenario Timeout must be a number"); - } - - return FormValidation.ok(); - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/SseBuilder.java b/src/main/java/com/hp/application/automation/tools/run/SseBuilder.java deleted file mode 100644 index 510904e6e1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/SseBuilder.java +++ /dev/null @@ -1,538 +0,0 @@ -package com.hp.application.automation.tools.run; - -import java.io.IOException; -import java.io.PrintStream; -import java.io.StringWriter; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; - -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.AncestorInPath; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.QueryParameter; - -import com.cloudbees.plugins.credentials.CredentialsProvider; -import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; -import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; -import com.cloudbees.plugins.credentials.matchers.IdMatcher; -import com.hp.application.automation.tools.model.AlmServerSettingsModel; -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.model.EnumDescription; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.model.SseProxySettings; -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; -import com.hp.application.automation.tools.sse.SSEBuilderPerformer; -import com.hp.application.automation.tools.sse.result.model.junit.Testcase; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuite; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; -import com.hp.application.automation.tools.sse.sdk.Logger; - -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.Util; -import hudson.model.*; -import hudson.model.queue.Tasks; -import hudson.security.ACL; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import hudson.util.ListBoxModel; -import hudson.util.VariableResolver; -import jenkins.tasks.SimpleBuildStep; - -/*** - * This Jenkins plugin contains an unofficial implementation of some of the elements of the HP ALM - * Lab Management SDK. Users are free to use this plugin as they wish, but HP does not take - * responsibility for supporting or providing backwards compatibility for the functionality herein. - * - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class SseBuilder extends Builder implements SimpleBuildStep { - - private SseModel _sseModel; - private String _fileName; - - private String almServerName; - private String credentialsId; - private String almDomain; - private String almProject; - private String description; - private String runType; - private String almEntityId; - private String timeslotDuration; - private String postRunAction; - private String environmentConfigurationId; - private CdaDetails cdaDetails; - private SseProxySettings proxySettings; - - //Databound setters and getters. - public String getAlmServerName() { return almServerName; } - public String getCredentialsId() { return credentialsId; } - public String getAlmDomain() { return almDomain; } - public String getAlmProject() { return almProject; } - public String getDescription() { return description; } - public String getRunType() { return runType; } - public String getAlmEntityId() { return almEntityId; } - public String getTimeslotDuration() { return timeslotDuration; } - public String getPostRunAction() { return postRunAction; } - public String getEnvironmentConfigurationId() { return environmentConfigurationId; } - public CdaDetails getCdaDetails() { return cdaDetails; } - public SseProxySettings getProxySettings() { return proxySettings; } - - public boolean isUseProxy() { - return proxySettings != null; - } - public boolean isCdaDetailsChecked() { - return cdaDetails != null; - } - - @DataBoundSetter - public void setDescription(String description) { this.description = description; } - - @DataBoundSetter - public void setPostRunAction(String postRunAction) { this.postRunAction = postRunAction; } - - @DataBoundSetter - public void setEnvironmentConfigurationId(String environmentConfigurationId) { - this.environmentConfigurationId = environmentConfigurationId; - } - - @DataBoundSetter - public void setCdaDetails(CdaDetails cdaDetails) { this.cdaDetails = cdaDetails; } - - @DataBoundSetter - public void setProxySettings(SseProxySettings proxySettings) { this.proxySettings = proxySettings; } - - /** - * Should only contains mandatory properties. - */ - @DataBoundConstructor - public SseBuilder(String almServerName, - String almProject, - String credentialsId, - String almDomain, - String runType, - String almEntityId, - String timeslotDuration) { - - this.almServerName = almServerName; - this.credentialsId = credentialsId; - this.almProject = almProject; - this.almDomain = almDomain; - this.timeslotDuration = timeslotDuration; - this.runType = runType; - this.almEntityId = almEntityId; - } - - @Override - public void perform(Run build, FilePath workspace, Launcher launcher, - TaskListener listener) throws InterruptedException, IOException { - - PrintStream logger = listener.getLogger(); - - UsernamePasswordCredentials credentials = getCredentialsById(credentialsId, build, logger); - setProxyCredentials(build); - - _sseModel = new SseModel( - almServerName, - credentials.getUsername(), - credentials.getPassword().getPlainText(), - almDomain, - almProject, - runType, - almEntityId, - timeslotDuration, - description, - postRunAction, - environmentConfigurationId, - cdaDetails, - proxySettings); - - _sseModel.setAlmServerUrl(getServerUrl(_sseModel.getAlmServerName())); - - VariableResolver varResolver = new VariableResolver.ByMap(build.getEnvironment(listener)); - Testsuites testsuites = execute(build, logger, varResolver); - - FilePath resultsFilePath = workspace.child(getFileName()); - Result resultStatus = createRunResults(resultsFilePath, testsuites, logger); - provideStepResultStatus(resultStatus, build, logger); - } - - /** - * Get credentials by the credentials id. Then set the user name and password into the SsePoxySetting. - */ - private void setProxyCredentials(Run run) { - if (proxySettings != null && proxySettings.getFsProxyCredentialsId() != null) { - UsernamePasswordCredentials up = CredentialsProvider.findCredentialById( - proxySettings.getFsProxyCredentialsId(), - StandardUsernamePasswordCredentials.class, - run, - URIRequirementBuilder.create().build()); - - if (up != null) { - proxySettings.setFsProxyUserName(up.getUsername()); - proxySettings.setFsProxyPassword(up.getPassword()); - } - } - } - - /** - * Get user name password credentials by id. - */ - private UsernamePasswordCredentials getCredentialsById(String credentialsId, Run run, PrintStream logger) { - if (StringUtils.isBlank(credentialsId)) { - throw new NullPointerException("credentials is not configured."); - } - - UsernamePasswordCredentials credentials = CredentialsProvider.findCredentialById(credentialsId, - StandardUsernamePasswordCredentials.class, - run, - URIRequirementBuilder.create().build()); - - if (credentials == null) { - logger.println("Can not find credentials with the credentialsId:" + credentialsId); - } - return credentials; - } - - public AlmServerSettingsModel getAlmServerSettingsModel() { - - AlmServerSettingsModel ret = null; - for (AlmServerSettingsModel almServer : getDescriptor().getAlmServers()) { - if (_sseModel != null - && _sseModel.getAlmServerName().equals(almServer.getAlmServerName())) { - ret = almServer; - break; - } - } - - return ret; - } - - private void provideStepResultStatus( - Result resultStatus, - Run build, - PrintStream logger) { - - logger.println(String.format("Result Status: %s", resultStatus.toString())); - build.setResult(resultStatus); - - } - - private Testsuites execute( - Run build, - PrintStream logger, - VariableResolver buildVariableResolver) throws InterruptedException { - - Testsuites ret = null; - SSEBuilderPerformer performer = null; - try { - performer = new SSEBuilderPerformer(); - ret = execute(performer, logger, buildVariableResolver); - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - stop(performer, logger); - throw e; - } catch (Exception cause) { - build.setResult(Result.FAILURE); - logger.print(String.format("Failed to execute test, Exception: %s", cause.getMessage())); - } - - return ret; - } - - private Result createRunResults(FilePath filePath, Testsuites testsuites, PrintStream logger) { - - Result ret = Result.SUCCESS; - try { - if (testsuites != null) { - StringWriter writer = new StringWriter(); - JAXBContext context = JAXBContext.newInstance(Testsuites.class); - Marshaller marshaller = context.createMarshaller(); - marshaller.marshal(testsuites, writer); - filePath.write(writer.toString(), null); - if (containsErrors(testsuites.getTestsuite())) { - ret = Result.UNSTABLE; - } - } else { - logger.println("Empty Results"); - ret = Result.UNSTABLE; - } - - } catch (Exception cause) { - logger.print(String.format( - "Failed to create run results, Exception: %s", - cause.getMessage())); - ret = Result.UNSTABLE; - } - - return ret; - } - - private boolean containsErrors(List testsuites) { - - boolean ret = false; - for (Testsuite testsuite : testsuites) { - for (Testcase testcase : testsuite.getTestcase()) { - if ("error".equals(testcase.getStatus())) { - ret = true; - break; - } - } - } - - return ret; - } - - private String getFileName() { - - Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); - String time = formatter.format(new Date()); - _fileName = String.format("Results%s.xml", time); - return _fileName; - } - - private void stop(SSEBuilderPerformer performer, PrintStream logger) { - - try { - if (performer != null) { - performer.stop(); - } - } catch (Exception cause) { - logger.println(String.format("Failed to stop BVS. Exception: %s", cause.getMessage())); - } - } - - private Testsuites execute( - SSEBuilderPerformer performer, - final PrintStream logger, - VariableResolver buildVariableResolver) throws InterruptedException, - IOException { - - return performer.start(_sseModel, new Logger() { - - @Override - public void log(String message) { - - logger.println(message); - } - }, buildVariableResolver); - } - - public String getServerUrl(String almServerName) { - - String ret = ""; - AlmServerSettingsModel[] almServers = getDescriptor().getAlmServers(); - if (almServers != null && almServers.length > 0) { - for (AlmServerSettingsModel almServer : almServers) { - if (almServerName.equals(almServer.getAlmServerName())) { - ret = almServer.getAlmServerUrl(); - break; - } - } - } - - return ret; - } - - public SseModel getSseModel() { - - return _sseModel; - } - - public String getRunResultsFileName() { - - return _fileName; - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - // This indicates to Jenkins that this is an implementation of an extension point - @Extension - // To expose this builder in the Snippet Generator. - @Symbol("sseBuild") - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - - load(); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - - return true; - } - - @Override - public String getDisplayName() { - - return "Execute HP tests using HP ALM Lab Management"; - } - - public boolean hasAlmServers() { - - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).hasAlmServers(); - } - - public AlmServerSettingsModel[] getAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); - } - - public FormValidation doCheckTimeslotDuration(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Timeslot duration must be set"); - } - - String val1 = value.trim(); - - if (!StringUtils.isNumeric(val1)) { - return FormValidation.error("Timeslot duration must be a number"); - } - - if (Integer.valueOf(val1) < 30) { - return FormValidation.error("Timeslot duration must be higher than 30"); - } - - return FormValidation.ok(); - } - - public FormValidation doCheckAlmDomain(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("Domain must be set"); - } - - return ret; - } - - public FormValidation doCheckAlmProject(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("Project must be set"); - } - - return ret; - } - - public FormValidation doCheckAlmEntityId(@QueryParameter String value) { - - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("Entity ID must be set."); - } - - return ret; - } - - public List getRunTypes() { - - return SseModel.getRunTypes(); - } - - public List getPostRunActions() { - - return SseModel.getPostRunActions(); - } - - public List getDeploymentActions() { - - return CdaDetails.getDeploymentActions(); - } - - public static List getDeprovisioningActions() { - - return CdaDetails.getDeprovisioningActions(); - } - - /** - * To fill in the credentials drop down list which's field is 'credentialsId'. - * This method's name works with tag . - */ - public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, - @QueryParameter String credentialsId) { - - if (project == null || !project.hasPermission(Item.CONFIGURE)) { - return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); - } - return new StandardUsernameListBoxModel() - .includeEmptyValue() - .includeAs( - project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, - project, - StandardUsernamePasswordCredentials.class, - URIRequirementBuilder.create().build()) - .includeCurrentValue(credentialsId); - } - - /** - * To fill in the credentials drop down list which's field is 'FsProxyCredentialsId'. - */ - public ListBoxModel doFillFsProxyCredentialsIdItems(@AncestorInPath Item project, - @QueryParameter String credentialsId) { - return doFillCredentialsIdItems(project, credentialsId); - } - - public FormValidation doCheckCredentialsId(@AncestorInPath Item project, - @QueryParameter String url, - @QueryParameter String value) { - if (project == null || !project.hasPermission(Item.EXTENDED_READ)) { - return FormValidation.ok(); - } - - value = Util.fixEmptyAndTrim(value); - if (value == null) { - return FormValidation.ok(); - } - - url = Util.fixEmptyAndTrim(url); - if (url == null) - // not set, can't check - { - return FormValidation.ok(); - } - - if (url.indexOf('$') >= 0) - // set by variable, can't check - { - return FormValidation.ok(); - } - - for (ListBoxModel.Option o : CredentialsProvider.listCredentials( - StandardUsernamePasswordCredentials.class, - project, - project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, - URIRequirementBuilder.create().build(), - new IdMatcher(value))) { - - if (StringUtils.equals(value, o.value)) { - return FormValidation.ok(); - } - } - // no credentials available, can't check - return FormValidation.warning("Cannot find any credentials with id " + value); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/SvChangeModeBuilder.java b/src/main/java/com/hp/application/automation/tools/run/SvChangeModeBuilder.java deleted file mode 100644 index cdf925ae3b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/SvChangeModeBuilder.java +++ /dev/null @@ -1,184 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; -import java.io.PrintStream; -import java.util.Collection; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.hp.application.automation.tools.model.SvChangeModeModel; -import com.hp.application.automation.tools.model.SvDataModelSelection; -import com.hp.application.automation.tools.model.SvPerformanceModelSelection; -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.sv.jsvconfigurator.core.IProjectElement; -import com.hp.sv.jsvconfigurator.core.IService; -import com.hp.sv.jsvconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; -import com.hp.sv.jsvconfigurator.processor.ChmodeProcessor; -import com.hp.sv.jsvconfigurator.processor.ChmodeProcessorInput; -import com.hp.sv.jsvconfigurator.processor.IChmodeProcessor; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.util.FormValidation; -import hudson.util.ListBoxModel; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -/** - * Performs change mode of virtual service - */ -public class SvChangeModeBuilder extends AbstractSvRunBuilder { - private static final Logger LOG = Logger.getLogger(SvChangeModeBuilder.class.getName()); - - @DataBoundConstructor - public SvChangeModeBuilder(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, - SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { - super(new SvChangeModeModel(serverName, force, mode, dataModel, performanceModel, serviceSelection)); - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @SuppressWarnings("unused") - public SvDataModelSelection getDataModel() { - return model.getDataModel(); - } - - @SuppressWarnings("unused") - public SvPerformanceModelSelection getPerformanceModel() { - return model.getPerformanceModel(); - } - - @Override - protected void performImpl(@Nonnull Run run, @Nonnull FilePath workspace, Launcher launcher, TaskListener listener) throws Exception { - PrintStream logger = listener.getLogger(); - - ICommandExecutor exec = createCommandExecutor(); - for (ServiceInfo service : getServiceList(false, logger, workspace)) { - changeServiceMode(service, logger, exec); - } - } - - private void changeServiceMode(ServiceInfo serviceInfo, PrintStream logger, ICommandExecutor commandExecutor) throws Exception { - - String dataModel = model.getDataModel().getSelectedModelName(); - String performanceModel = model.getPerformanceModel().getSelectedModelName(); - boolean useDefaultDataModel = model.getDataModel().isDefaultSelected(); - boolean useDefaultPerformanceModel = model.getPerformanceModel().isDefaultSelected(); - ServiceRuntimeConfiguration.RuntimeMode targetMode = getTargetMode(); - - ChmodeProcessorInput chmodeInput = new ChmodeProcessorInput(model.isForce(), null, serviceInfo.getId(), - dataModel, performanceModel, targetMode, useDefaultDataModel, useDefaultPerformanceModel); - - logger.printf(" Changing mode of service '%s' [%s] to %s mode%n", serviceInfo.getName(), serviceInfo.getId(), model.getMode()); - - IChmodeProcessor processor = new ChmodeProcessor(null); - - try { - processor.process(chmodeInput, commandExecutor); - } finally { - printServiceStatus(logger, serviceInfo, commandExecutor); - } - } - - private ServiceRuntimeConfiguration.RuntimeMode getTargetMode() { - // Set STAND_BY with PM in case of simulation without data model to be in accord with designer & SVM - if (model.getMode() == ServiceRuntimeConfiguration.RuntimeMode.SIMULATING - && !model.getPerformanceModel().isNoneSelected() - && model.getDataModel().isNoneSelected()) { - return ServiceRuntimeConfiguration.RuntimeMode.STAND_BY; - } - - return model.getMode(); - } - - private void printServiceStatus(PrintStream logger, ServiceInfo serviceInfo, ICommandExecutor commandExecutor) { - try { - IService service = commandExecutor.findService(serviceInfo.getId(), null); - ServiceRuntimeConfiguration info = commandExecutor.getServiceRuntimeInfo(service); - ServiceRuntimeConfiguration.RuntimeMode mode = getDisplayRuntimeMode(info); - - logger.printf(" Service '%s' [%s] is in %s mode%n", service.getName(), service.getId(), mode); - if (mode == ServiceRuntimeConfiguration.RuntimeMode.LEARNING || mode == ServiceRuntimeConfiguration.RuntimeMode.SIMULATING) { - logger.println(" Data model: " + getModelName(service.getDataModels(), info.getDataModelId())); - logger.println(" Performance model: " + getModelName(service.getPerfModels(), info.getPerfModelId())); - } - - if (info.getDeploymentErrorMessage() != null) { - logger.println(" Error message: " + info.getDeploymentErrorMessage()); - } - } catch (Exception e) { - String msg = String.format("Failed to get detail of service '%s' [%s]", serviceInfo.getName(), serviceInfo.getId()); - logger.printf(" %s: %s%n", msg, e.getMessage()); - LOG.log(Level.SEVERE, msg, e); - } - } - - private ServiceRuntimeConfiguration.RuntimeMode getDisplayRuntimeMode(ServiceRuntimeConfiguration info) { - // display SIMULATING in case of STAND_BY mode with PM set (as it is done in designer and SVM) - return (info.getRuntimeMode() == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY && info.getPerfModelId() != null) - ? ServiceRuntimeConfiguration.RuntimeMode.SIMULATING - : info.getRuntimeMode(); - } - - private String getModelName(Collection models, String modelId) { - for (IProjectElement model : models) { - if (model.getId().equals(modelId)) { - return String.format("'%s' [%s]", model.getName(), modelId); - } - } - return null; - } - - @Override - protected void logConfig(PrintStream logger, String prefix) { - super.logConfig(logger, prefix); - logger.println(prefix + "Mode: " + model.getMode().toString()); - logger.println(prefix + "Data model: " + model.getDataModel().toString()); - logger.println(prefix + "Performance model: " + model.getPerformanceModel().toString()); - } - - @Extension - public static final class DescriptorImpl extends AbstractSvRunDescriptor { - - public DescriptorImpl() { - super("SV: Change Mode of Virtual Service"); - } - - @SuppressWarnings("unused") - public FormValidation doCheckDataModel(@QueryParameter String value, @QueryParameter("mode") String mode, @QueryParameter("serviceSelectionKind") String kind) { - if (StringUtils.isNotBlank(mode)) { - ServiceRuntimeConfiguration.RuntimeMode runtimeMode = ServiceRuntimeConfiguration.RuntimeMode.valueOf(mode); - if ((ServiceRuntimeConfiguration.RuntimeMode.SIMULATING == runtimeMode - || ServiceRuntimeConfiguration.RuntimeMode.LEARNING == runtimeMode) - && StringUtils.isBlank(value)) { - return FormValidation.ok("First data model will be used if not specified"); - } - if (ServiceRuntimeConfiguration.RuntimeMode.STAND_BY == runtimeMode && StringUtils.isNotBlank(value)) { - return FormValidation.warning("Data model will not be used in Stand-By mode"); - } - } - return FormValidation.ok(); - } - - @SuppressWarnings("unused") - public ListBoxModel doFillModeItems() { - ListBoxModel items = new ListBoxModel(); - items.add("Stand-By", ServiceRuntimeConfiguration.RuntimeMode.STAND_BY.toString()); - items.add("Simulate", ServiceRuntimeConfiguration.RuntimeMode.SIMULATING.toString()); - items.add("Learn", ServiceRuntimeConfiguration.RuntimeMode.LEARNING.toString()); - return items; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/SvDeployBuilder.java b/src/main/java/com/hp/application/automation/tools/run/SvDeployBuilder.java deleted file mode 100644 index 1e4243f6f1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/SvDeployBuilder.java +++ /dev/null @@ -1,120 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; -import java.io.PrintStream; -import java.util.ArrayList; - -import com.hp.application.automation.tools.model.SvDeployModel; -import com.hp.sv.jsvconfigurator.core.IDataModel; -import com.hp.sv.jsvconfigurator.core.IPerfModel; -import com.hp.sv.jsvconfigurator.core.IProject; -import com.hp.sv.jsvconfigurator.core.IService; -import com.hp.sv.jsvconfigurator.processor.DeployProcessor; -import com.hp.sv.jsvconfigurator.processor.DeployProcessorInput; -import com.hp.sv.jsvconfigurator.processor.IDeployProcessor; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import com.hp.sv.jsvconfigurator.service.ServiceAmendingServiceImpl; -import com.hp.sv.jsvconfigurator.util.ProjectUtils; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.util.FormValidation; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -public class SvDeployBuilder extends AbstractSvRunBuilder { - - @DataBoundConstructor - public SvDeployBuilder(String serverName, boolean force, String service, String projectPath, String projectPassword, - boolean firstAgentFallback) { - super(new SvDeployModel(serverName, force, service, projectPath, projectPassword, firstAgentFallback)); - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public void performImpl(@Nonnull Run run, @Nonnull FilePath workspace, Launcher launcher, TaskListener listener) throws Exception { - PrintStream logger = listener.getLogger(); - - IProject project = loadProject(workspace); - printProjectContent(project, logger); - deployServiceFromProject(project, logger); - } - - private Iterable getServiceList(IProject project) { - if (model.getService() == null) { - return project.getServices(); - } else { - ArrayList list = new ArrayList<>(); - list.add(ProjectUtils.findProjElem(project.getServices(), model.getService())); - return list; - } - } - - private void deployServiceFromProject(IProject project, PrintStream logger) throws Exception { - IDeployProcessor processor = new DeployProcessor(null, new ServiceAmendingServiceImpl()); - ICommandExecutor commandExecutor = createCommandExecutor(); - - for (IService service : getServiceList(project)) { - logger.printf(" Deploying service '%s' [%s] %n", service.getName(), service.getId()); - DeployProcessorInput deployInput = new DeployProcessorInput(model.isForce(), false, project, model.getService(), null); - deployInput.setFirstAgentFailover(model.isFirstAgentFallback()); - processor.process(deployInput, commandExecutor); - } - } - - private void printProjectContent(IProject project, PrintStream logger) { - logger.println(" Project content:"); - for (IService service : project.getServices()) { - logger.println(" Service: " + service.getName() + " [" + service.getId() + "]"); - for (IDataModel dataModel : service.getDataModels()) { - logger.println(" DM: " + dataModel.getName() + " [" + dataModel.getId() + "]"); - } - for (IPerfModel perfModel : service.getPerfModels()) { - logger.println(" PM: " + perfModel.getName() + " [" + perfModel.getId() + "]"); - } - } - } - - @Override - protected void logConfig(PrintStream logger, String prefix) { - super.logConfig(logger, prefix); - logger.println(prefix + "First agent fallback: " + model.isFirstAgentFallback()); - } - - @Extension - public static final class DescriptorImpl extends AbstractSvRunDescriptor { - - public DescriptorImpl() { - super("SV: Deploy Virtual Service"); - } - - @SuppressWarnings("unused") - public FormValidation doCheckProjectPath(@QueryParameter String projectPath) { - if (StringUtils.isBlank(projectPath)) { - return FormValidation.error("Project path cannot be empty"); - } - return FormValidation.ok(); - } - - @SuppressWarnings("unused") - public FormValidation doCheckService(@QueryParameter String service) { - if (StringUtils.isBlank(service)) { - return FormValidation.ok("All services from project will be deployed if no service is specified"); - } - return FormValidation.ok(); - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/SvExportBuilder.java b/src/main/java/com/hp/application/automation/tools/run/SvExportBuilder.java deleted file mode 100644 index d9cd624786..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/SvExportBuilder.java +++ /dev/null @@ -1,146 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.PrintStream; - -import com.hp.application.automation.tools.model.SvExportModel; -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.sv.jsvconfigurator.core.IService; -import com.hp.sv.jsvconfigurator.core.impl.exception.CommandExecutorException; -import com.hp.sv.jsvconfigurator.core.impl.exception.CommunicatorException; -import com.hp.sv.jsvconfigurator.core.impl.exception.SVCParseException; -import com.hp.sv.jsvconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; -import com.hp.sv.jsvconfigurator.processor.ChmodeProcessor; -import com.hp.sv.jsvconfigurator.processor.ChmodeProcessorInput; -import com.hp.sv.jsvconfigurator.processor.ExportProcessor; -import com.hp.sv.jsvconfigurator.processor.IChmodeProcessor; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.util.FormValidation; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.DirectoryFileFilter; -import org.apache.commons.io.filefilter.SuffixFileFilter; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; - -/** - * Performs export of of virtual service - */ -public class SvExportBuilder extends AbstractSvRunBuilder { - - @DataBoundConstructor - public SvExportBuilder(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, - SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst) { - super(new SvExportModel(serverName, force, targetDirectory, cleanTargetDirectory, serviceSelection, switchToStandByFirst)); - } - - @Override - protected void logConfig(PrintStream logger, String prefix) { - logger.println(prefix + "Target Directory: " + model.getTargetDirectory()); - logger.println(prefix + "Switch to Stand-By: " + model.isSwitchToStandByFirst()); - super.logConfig(logger, prefix); - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - protected void performImpl(@Nonnull Run run, @Nonnull FilePath workspace, Launcher launcher, TaskListener listener) throws Exception { - PrintStream logger = listener.getLogger(); - - ExportProcessor exportProcessor = new ExportProcessor(null); - IChmodeProcessor chmodeProcessor = new ChmodeProcessor(null); - - ICommandExecutor exec = createCommandExecutor(); - - verifyNotNull(model.getTargetDirectory(), "Target directory must be set"); - - String targetDirectory = workspace.child(model.getTargetDirectory()).getRemote(); - - if (model.isCleanTargetDirectory()) { - cleanTargetDirectory(logger, targetDirectory); - } - - for (ServiceInfo serviceInfo : getServiceList(false, logger, workspace)) { - if (model.isSwitchToStandByFirst()) { - switchToStandBy(serviceInfo, chmodeProcessor, exec, logger); - } - - logger.printf(" Exporting service '%s' [%s] to %s %n", serviceInfo.getName(), serviceInfo.getId(), targetDirectory); - verifyNotLearningBeforeExport(logger, exec, serviceInfo); - exportProcessor.process(exec, targetDirectory, serviceInfo.getId(), false); - } - } - - private void verifyNotLearningBeforeExport(PrintStream logger, ICommandExecutor exec, ServiceInfo serviceInfo) - throws CommunicatorException, CommandExecutorException { - - IService service = exec.findService(serviceInfo.getId(), null); - ServiceRuntimeConfiguration info = exec.getServiceRuntimeInfo(service); - if (info.getRuntimeMode() == ServiceRuntimeConfiguration.RuntimeMode.LEARNING) { - logger.printf(" WARNING: Service '%s' [%s] is in Learning mode. Exported model need not be complete!", - serviceInfo.getName(), serviceInfo.getId()); - } - } - - private void switchToStandBy(ServiceInfo service, IChmodeProcessor chmodeProcessor, ICommandExecutor exec, PrintStream logger) - throws CommandExecutorException, SVCParseException, CommunicatorException { - - logger.printf(" Switching service '%s' [%s] to Stand-By mode before export%n", service.getName(), service.getId()); - ChmodeProcessorInput chmodeInput = new ChmodeProcessorInput(model.isForce(), null, service.getId(), null, null, - ServiceRuntimeConfiguration.RuntimeMode.STAND_BY, false, false); - chmodeProcessor.process(chmodeInput, exec); - } - - /** - * Cleans all sub-folders containing *.vproj file. - */ - private void cleanTargetDirectory(PrintStream logger, String targetDirectory) throws IOException { - File target = new File(targetDirectory); - if (target.exists()) { - File[] subfolders = target.listFiles((FilenameFilter) DirectoryFileFilter.INSTANCE); - if (subfolders.length > 0) { - logger.println(" Cleaning target directory..."); - } - for (File subfolder : subfolders) { - if (subfolder.listFiles((FilenameFilter) new SuffixFileFilter(".vproj")).length > 0) { - logger.println(" Deleting subfolder of target directory: " + subfolder.getAbsolutePath()); - FileUtils.deleteDirectory(subfolder); - } else { - logger.println(" Skipping delete of directory '" + subfolder.getAbsolutePath() + "' because it does not contain any *.vproj file."); - } - } - } - } - - @Extension - public static final class DescriptorImpl extends AbstractSvRunDescriptor { - - public DescriptorImpl() { - super("SV: Export Virtual Service"); - } - - @SuppressWarnings("unused") - public FormValidation doCheckTargetDirectory(@QueryParameter String targetDirectory) { - if (StringUtils.isBlank(targetDirectory)) { - return FormValidation.error("Target directory cannot be empty"); - } - return FormValidation.ok(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/SvUndeployBuilder.java b/src/main/java/com/hp/application/automation/tools/run/SvUndeployBuilder.java deleted file mode 100644 index ff2d61e150..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/SvUndeployBuilder.java +++ /dev/null @@ -1,68 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.run; - -import javax.annotation.Nonnull; -import java.io.PrintStream; - -import com.hp.application.automation.tools.model.SvServiceSelectionModel; -import com.hp.application.automation.tools.model.SvUndeployModel; -import com.hp.sv.jsvconfigurator.processor.IUndeployProcessor; -import com.hp.sv.jsvconfigurator.processor.UndeployProcessor; -import com.hp.sv.jsvconfigurator.processor.UndeployProcessorInput; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import hudson.Extension; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.Run; -import hudson.model.TaskListener; -import org.kohsuke.stapler.DataBoundConstructor; - -/** - * Deletes selected virtual service from server - */ -public class SvUndeployBuilder extends AbstractSvRunBuilder { - - @DataBoundConstructor - public SvUndeployBuilder(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { - super(new SvUndeployModel(serverName, continueIfNotDeployed, force, serviceSelection)); - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - protected void performImpl(@Nonnull Run run, @Nonnull FilePath workspace, Launcher launcher, TaskListener listener) throws Exception { - - PrintStream logger = listener.getLogger(); - - IUndeployProcessor processor = new UndeployProcessor(null); - - ICommandExecutor exec = createCommandExecutor(); - for (ServiceInfo service : getServiceList(model.isContinueIfNotDeployed(), logger, workspace)) { - logger.printf(" Undeploying service '%s' [%s] %n", service.getName(), service.getId()); - UndeployProcessorInput undeployProcessorInput = new UndeployProcessorInput(model.isForce(), null, service.getId()); - processor.process(undeployProcessorInput, exec); - - } - } - - @Override - protected void logConfig(PrintStream logger, String prefix) { - super.logConfig(logger, prefix); - logger.println(prefix + "Continue if not deployed: " + model.isContinueIfNotDeployed()); - } - - @Extension - public static final class DescriptorImpl extends AbstractSvRunDescriptor { - - public DescriptorImpl() { - super("SV: Undeploy Virtual Service"); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/run/UploadAppBuilder.java b/src/main/java/com/hp/application/automation/tools/run/UploadAppBuilder.java deleted file mode 100644 index 87e3ee8603..0000000000 --- a/src/main/java/com/hp/application/automation/tools/run/UploadAppBuilder.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.hp.application.automation.tools.run; - -import com.hp.application.automation.tools.mc.JobConfigurationProxy; -import com.hp.application.automation.tools.model.MCServerSettingsModel; -import com.hp.application.automation.tools.model.ProxySettings; -import com.hp.application.automation.tools.model.UploadAppModel; -import com.hp.application.automation.tools.model.UploadAppPathModel; -import com.hp.application.automation.tools.settings.MCServerSettingsBuilder; -import hudson.Extension; -import hudson.Launcher; -import hudson.Util; -import hudson.model.*; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import net.minidev.json.JSONObject; -import org.kohsuke.stapler.DataBoundConstructor; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintStream; -import java.util.List; - -/** - * Created with IntelliJ IDEA. - * User: jingwei - * Date: 5/17/16 - * Time: 4:36 PM - * To change this template use File | Settings | File Templates. - */ -public class UploadAppBuilder extends Builder { - - private final UploadAppModel uploadAppModel; - - @DataBoundConstructor - public UploadAppBuilder(String mcServerName, String mcUserName, String mcPassword, ProxySettings proxySettings, List applicationPaths) { - uploadAppModel = new UploadAppModel(mcServerName, mcUserName, mcPassword, proxySettings, applicationPaths); - } - - @Override - public DescriptorImpl getDescriptor() { - - return (DescriptorImpl) super.getDescriptor(); - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) - throws InterruptedException, IOException { - // get the mc server settings - MCServerSettingsModel mcServerSettingsModel = getMCServerSettingsModel(); - JobConfigurationProxy job = JobConfigurationProxy.getInstance(); - JSONObject app = null; - String mcServerUrl = ""; - PrintStream out = listener.getLogger(); - List paths = null; - if(uploadAppModel != null){ - paths = uploadAppModel.getApplicationPaths(); - } - if(mcServerSettingsModel == null){ - out.println("Failed to upload app to MC server. Cause: MC url didn't be configured." ); - return false; - }else{ - mcServerUrl = mcServerSettingsModel.getProperties().getProperty("MobileHostAddress"); - out.println(String.format("There are %d apps to be uploaded.", paths.size())); - for(int i=1; i<=paths.size(); i++){ - String path = paths.get(i-1).getMcAppPath(); - try{ - out.println(String.format("starting to upload app %d %s", i, path)); - if(uploadAppModel.getProxySettings() == null){ - app = job.upload(mcServerUrl, uploadAppModel.getMcUserName(),uploadAppModel.getMcPassword(), null, null, null, path); - }else{ - app = job.upload(mcServerUrl, uploadAppModel.getMcUserName(),uploadAppModel.getMcPassword(), uploadAppModel.getProxySettings().getFsProxyAddress(),uploadAppModel.getProxySettings().getFsProxyUserName(), uploadAppModel.getProxySettings().getFsProxyPassword(),path); - } - if(app == null){ - if(uploadAppModel.isUseProxy()){ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s, Proxy url:%s", - mcServerUrl, uploadAppModel.getMcUserName(), uploadAppModel.getProxySettings().getFsProxyAddress())); - }else if(uploadAppModel.isUseAuthentication()){ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s, Proxy url:%s, proxy userName:%s", - mcServerUrl, uploadAppModel.getMcUserName(), uploadAppModel.getProxySettings().getFsProxyAddress(), uploadAppModel.getProxySettings().getFsProxyUserName())); - }else{ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s,", - mcServerUrl, uploadAppModel.getMcUserName())); - } - build.setResult(Result.FAILURE); - return false; - } - out.println("uploaded app info: " + app.toJSONString()); - } catch(FileNotFoundException fnf){ - out.println(String.format("Failed to upload app to MC server. Cause: File: %s is not found.", path)); - build.setResult(Result.FAILURE); - return false; - } catch (IOException ioe) { - Util.displayIOException(ioe, listener); - build.setResult(Result.FAILURE); - return false; - } catch (InterruptedException e) { - build.setResult(Result.ABORTED); - } catch (Exception e){ - if(uploadAppModel.isUseProxy()){ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s, Proxy url:%s", - mcServerUrl, uploadAppModel.getMcUserName(), uploadAppModel.getProxySettings().getFsProxyAddress())); - }else if(uploadAppModel.isUseAuthentication()){ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s, Proxy url:%s, proxy userName:%s", - mcServerUrl, uploadAppModel.getMcUserName(), uploadAppModel.getProxySettings().getFsProxyAddress(), uploadAppModel.getProxySettings().getFsProxyUserName())); - }else{ - out.println(String.format("Failed to upload app, Cause MC connection info is incorrect. url:%s, username:%s,", - mcServerUrl, uploadAppModel.getMcUserName())); - } - build.setResult(Result.FAILURE); - return false; - } - } - } - return true; - } - - public MCServerSettingsModel getMCServerSettingsModel() { - for (MCServerSettingsModel mcServer : getDescriptor().getMcServers()) { - if (this.uploadAppModel != null - && uploadAppModel.getMcServerName().equals(mcServer.getMcServerName())) { - return mcServer; - } - } - return null; - } - - public UploadAppModel getUploadAppModel() { - return uploadAppModel; - } - - // This indicates to Jenkins that this is an implementation of an extension point - @Extension - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { - - load(); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class jobType) { - - return true; - } - - @Override - public String getDisplayName() { - - return "Upload app to Mobile Center"; - } - - public boolean hasMCServers() { - return Hudson.getInstance().getDescriptorByType( - MCServerSettingsBuilder.MCDescriptorImpl.class).hasMCServers(); - } - - public MCServerSettingsModel[] getMcServers() { - return Hudson.getInstance().getDescriptorByType( - MCServerSettingsBuilder.MCDescriptorImpl.class).getInstallations(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder.java b/src/main/java/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder.java deleted file mode 100644 index a81bc105a5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder.java +++ /dev/null @@ -1,185 +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. - -package com.hp.application.automation.tools.settings; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; - -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -import com.hp.application.automation.tools.model.AlmServerSettingsModel; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.sdk.RestAuthenticator; - -import hudson.CopyOnWrite; -import hudson.Extension; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import net.sf.json.JSONObject; - -/** - * Sample {@link Builder}. - * - *

- * When the user configures the project and enables this builder, - * {@link DescriptorImpl#newInstance(StaplerRequest)} is invoked and a new - * {@link AlmServerSettingsBuilder} is created. The created instance is persisted to the project - * configuration XML by using XStream, so this allows you to use instance fields (like {@link #name} - * ) to remember the configuration. - * - *

- * When a build is performed, the {@link #perform(AbstractBuild, Launcher, BuildListener)} method - * will be invoked. - * - * @author Kohsuke Kawaguchi - */ -public class AlmServerSettingsBuilder extends Builder { - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - /** - * Descriptor for {@link AlmServerSettingsBuilder}. Used as a singleton. The class is marked as - * public so that it can be accessed from views. - * - *

- * See src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly for the - * actual HTML fragment for the configuration screen. - */ - @Extension - // This indicates to Jenkins that this is an implementation of an extension - // point. - public static final class DescriptorImpl extends BuildStepDescriptor { - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class aClass) { - // Indicates that this builder can be used with all kinds of project - // types - return true; - } - - /** - * This human readable name is used in the configuration screen. - */ - @Override - public String getDisplayName() { - return ""; - } - - public DescriptorImpl() { - load(); - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - // To persist global configuration information, - // set that to properties and call save(). - // useFrench = formData.getBoolean("useFrench"); - // ^Can also use req.bindJSON(this, formData); - // (easier when there are many fields; need set* methods for this, - // like setUseFrench) - // req.bindParameters(this, "locks."); - - setInstallations(req.bindParametersToList(AlmServerSettingsModel.class, "alm.").toArray( - new AlmServerSettingsModel[0])); - - save(); - - return super.configure(req, formData); - } - - public FormValidation doCheckAlmServerUrl(@QueryParameter String value) { - return checkQcServerURL(value, false); - } - - @CopyOnWrite - private AlmServerSettingsModel[] installations = new AlmServerSettingsModel[0]; - - public AlmServerSettingsModel[] getInstallations() { - return installations; - } - - public void setInstallations(AlmServerSettingsModel... installations) { - this.installations = installations; - } - - public FormValidation doCheckAlmServerName(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("ALM server name cannot be empty"); - } - - return FormValidation.ok(); - } - - private FormValidation checkQcServerURL(String value, Boolean acceptEmpty) { - String url; - // Path to the page to check if the server is alive - String page = RestAuthenticator.IS_AUTHENTICATED; - - // Do will allow empty value? - if (StringUtils.isBlank(value)) { - if (!acceptEmpty) { - return FormValidation.error("ALM server must be defined"); - } else { - return FormValidation.ok(); - } - } - - // Does the URL ends with a "/" ? if not, add it - if (value.lastIndexOf("/") == value.length() - 1) { - url = value + page; - } else { - url = value + "/" + page; - } - - // Open the connection and perform a HEAD request - HttpURLConnection connection; - try { - connection = (HttpURLConnection) RestClient.openConnection(null, url); - connection.setRequestMethod("GET"); - - // Check whether the response is from ALM Server - if (!isALMServerResponse(connection)) { - return FormValidation.error(RestAuthenticator.INVALID_ALM_SERVER_URL); - } - } catch (MalformedURLException ex) { - // This is not a valid URL - return FormValidation.error("ALM server URL is malformed."); - } catch (IOException ex) { - // Cant open connection to the server - return FormValidation.error("Error openning a connection to the ALM server"); - } - - return FormValidation.ok(); - } - - private boolean isALMServerResponse(HttpURLConnection conn) throws IOException { - boolean ret = false; - - if (conn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED - && conn.getHeaderFields().get(RestAuthenticator.AUTHENTICATE_HEADER) != null){ - ret = true; - } - - return ret; - } - - public Boolean hasAlmServers() { - return installations.length > 0; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/settings/MCServerSettingsBuilder.java b/src/main/java/com/hp/application/automation/tools/settings/MCServerSettingsBuilder.java deleted file mode 100644 index e48320c6a3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/settings/MCServerSettingsBuilder.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.hp.application.automation.tools.settings; - -import com.hp.application.automation.tools.model.MCServerSettingsModel; -import hudson.CopyOnWrite; -import hudson.Extension; -import hudson.model.AbstractProject; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -/** - * Sample {@link Builder}. - * - *

- * When the user configures the project and enables this builder, - * {@link com.hp.application.automation.tools.settings.MCServerSettingsBuilder.MCDescriptorImpl#newInstance(StaplerRequest)} is invoked and a new - * {@link AlmServerSettingsBuilder} is created. The created instance is persisted to the project - * configuration XML by using XStream, so this allows you to use instance fields (like {@link #name} - * ) to remember the configuration. - * - *

- * When a build is performed, the {@link #perform(hudson.model.AbstractBuild, hudson.Launcher, hudson.model.BuildListener)} method - * will be invoked. - * - * @author jingwei - */ -public class MCServerSettingsBuilder extends Builder { - @Override - public MCDescriptorImpl getDescriptor() { - return (MCDescriptorImpl) super.getDescriptor(); - } - - /** - * Descriptor for {@link MCServerSettingsBuilder}. Used as a singleton. The class is marked as - * public so that it can be accessed from views. - * - *

- * See src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly for the - * actual HTML fragment for the configuration screen. - */ - @Extension - // This indicates to Jenkins that this is an implementation of an extension - // point. - public static final class MCDescriptorImpl extends BuildStepDescriptor { - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class aClass) { - // Indicates that this builder can be used with all kinds of project - // types - return true; - } - - /** - * This human readable name is used in the configuration screen. - */ - @Override - public String getDisplayName() { - return ""; - } - - public MCDescriptorImpl() { - load(); - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - // To persist global configuration information, - // set that to properties and call save(). - // useFrench = formData.getBoolean("useFrench"); - // ^Can also use req.bindJSON(this, formData); - // (easier when there are many fields; need set* methods for this, - // like setUseFrench) - // req.bindParameters(this, "locks."); - - setInstallations(req.bindParametersToList(MCServerSettingsModel.class, "mc.").toArray( - new MCServerSettingsModel[0])); - - save(); - - return super.configure(req, formData); - } - - public FormValidation doCheckMCServerName(@QueryParameter String value) { - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("MC server name cannot be empty"); - } - - return ret; - } - - public FormValidation doCheckMCServerURL(@QueryParameter String value) { - FormValidation ret = FormValidation.ok(); - if (StringUtils.isBlank(value)) { - ret = FormValidation.error("MC server cannot be empty"); - } - - return ret; - } - - @CopyOnWrite - private MCServerSettingsModel[] installations = new MCServerSettingsModel[0]; - - public MCServerSettingsModel[] getInstallations() { - return installations; - } - - public void setInstallations(MCServerSettingsModel... installations) { - this.installations = installations; - } - - public Boolean hasMCServers() { - return installations.length > 0; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder.java b/src/main/java/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder.java deleted file mode 100644 index babfb32f22..0000000000 --- a/src/main/java/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder.java +++ /dev/null @@ -1,280 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.settings; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.model.OctaneServerSettingsModel; -import com.hp.octane.integrations.OctaneSDK; -import com.hp.application.automation.tools.octane.CIJenkinsServicesImpl; -import com.hp.application.automation.tools.octane.Messages; -import com.hp.application.automation.tools.octane.bridge.BridgesService; -import com.hp.application.automation.tools.octane.buildLogs.BdiConfigurationFetcher; -import com.hp.application.automation.tools.octane.configuration.ConfigurationListener; -import com.hp.application.automation.tools.octane.configuration.ConfigurationParser; -import com.hp.application.automation.tools.octane.configuration.MqmProject; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import com.hp.application.automation.tools.octane.events.EventsService; -import com.thoughtworks.xstream.annotations.XStreamOmitField; -import hudson.CopyOnWrite; -import hudson.Extension; -import hudson.ExtensionList; -import hudson.model.AbstractProject; -import hudson.model.Item; -import hudson.model.User; -import hudson.security.ACL; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import hudson.util.Secret; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.acegisecurity.context.SecurityContext; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -import java.util.Date; -import java.util.List; -import java.util.UUID; - -public class OctaneServerSettingsBuilder extends Builder { - - private static final Logger logger = LogManager.getLogger(OctaneServerSettingsBuilder.class); - - @Inject - private static BdiConfigurationFetcher bdiConfigurationFetcher; - - @Override - public OctaneDescriptorImpl getDescriptor() { - return (OctaneDescriptorImpl) super.getDescriptor(); - } - - /** - * Descriptor for {@link OctaneServerSettingsBuilder}. Used as a singleton. The class is marked as - * public so that it can be accessed from views. - *

- *

- * See src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly for the - * actual HTML fragment for the configuration screen. - */ - @Extension - // This indicates to Jenkins that this is an implementation of an extension - // point. - public static final class OctaneDescriptorImpl extends BuildStepDescriptor { - - @CopyOnWrite - private OctaneServerSettingsModel[] servers; - - @XStreamOmitField - BdiConfigurationFetcher bdiConfigurationFetcher; - - public OctaneDescriptorImpl() { - load(); - - OctaneServerSettingsModel model = getModel(); - if (StringUtils.isEmpty(model.getIdentity())) { - model.setIdentity(UUID.randomUUID().toString()); - model.setIdentityFrom(new Date().getTime()); - save(); - } - - OctaneSDK.init(new CIJenkinsServicesImpl(), false); - - // These ones, once will become part of the SDK, will be hidden from X Plugin and initialized in SDK internally - ServerConfiguration sc = convertToServerConfiguration(getModel()); - EventsService.getExtensionInstance().updateClient(sc); - BridgesService.getExtensionInstance().updateBridge(sc, model.getIdentity()); - } - - private static ServerConfiguration convertToServerConfiguration(OctaneServerSettingsModel model) { - return new ServerConfiguration( - model.getLocation(), - model.getSharedSpace(), - model.getUsername(), - model.getPassword(), - model.getImpersonatedUser()); - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class aClass) { - // Indicates that this builder can be used with all kinds of project - // types - return true; - } - - /** - * This human readable name is used in the configuration screen. - */ - @Override - public String getDisplayName() { - return ""; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - - JSONObject jsonObject = (JSONObject) formData.get("mqm"); - List list = req.bindJSONToList(OctaneServerSettingsModel.class, jsonObject); - OctaneServerSettingsModel newModel = list.get(0); - - if(jsonObject.containsKey("showIdentity")){ - JSONObject showIdentityJo = (JSONObject)jsonObject.get("showIdentity"); - String identity = showIdentityJo.getString("identity"); - validateConfiguration(doCheckInstanceId(identity), "Plugin instance id"); - - OctaneServerSettingsModel oldModel = getModel(); - if(!oldModel.getIdentity().equals(identity)){ - newModel.setIdentity(identity); - } - } - setModel(newModel); - return super.configure(req, formData); - } - - public void setModel(OctaneServerSettingsModel newModel) { - //infer uiLocation - MqmProject mqmProject = null; - try { - mqmProject = ConfigurationParser.parseUiLocation(newModel.getUiLocation()); - newModel.setSharedSpace(mqmProject.getSharedSpace()); - newModel.setLocation(mqmProject.getLocation()); - } catch (FormValidation fv) { - logger.warn("tested configuration failed on Octane URL parse: " + fv.getMessage(), fv); - } - - OctaneServerSettingsModel oldModel = getModel(); - - //set identity in new model - boolean identityChanged = StringUtils.isNotEmpty(newModel.getIdentity()); - if(!identityChanged){ //set identity from old model - newModel.setIdentity(oldModel.getIdentity()); - newModel.setIdentityFrom(oldModel.getIdentityFrom()); - } - - servers = (new OctaneServerSettingsModel[]{newModel}); - save(); - - ServerConfiguration oldConfiguration = convertToServerConfiguration(oldModel); - ServerConfiguration newConfiguration = convertToServerConfiguration(newModel); - if (!oldConfiguration.equals(newConfiguration)) { - fireOnChanged(newConfiguration, oldConfiguration); - } - - // When Jenkins configuration is saved we refresh the bdi configuration - bdiConfigurationFetcher.refresh(); - } - - private void fireOnChanged(ServerConfiguration configuration, ServerConfiguration oldConfiguration) { - ExtensionList listeners = ExtensionList.lookup(ConfigurationListener.class); - for (ConfigurationListener listener : listeners) { - try { - listener.onChanged(configuration, oldConfiguration); - } catch (ThreadDeath t) { - throw t; - } catch (Throwable t) { - logger.warn(t); - } - } - } - - @SuppressWarnings("unused") - public FormValidation doTestConnection(@QueryParameter("uiLocation") String uiLocation, - @QueryParameter("username") String username, - @QueryParameter("password") String password, - @QueryParameter("impersonatedUser") String impersonatedUser) { - MqmProject mqmProject; - try { - mqmProject = ConfigurationParser.parseUiLocation(uiLocation); - } catch (FormValidation fv) { - logger.warn("tested configuration failed on Octane URL parse: " + fv.getMessage(), fv); - return fv; - } - - - // if parse is good, check authentication/authorization - ConfigurationParser parser = Jenkins.getInstance().getExtensionList(ConfigurationParser.class).iterator().next(); - FormValidation validation = parser.checkConfiguration(mqmProject.getLocation(), mqmProject.getSharedSpace(), username, Secret.fromString(password)); - /*if (validation.kind == FormValidation.Kind.OK && - uiLocation.equals(octanePlugin.getUiLocation()) && - username.equals(octanePlugin.getUsername()) && - octanePassword.equals(octanePlugin.getPassword())) { - retryModel.success(); - }*/ - - // if still good, check Jenkins user permissions - try { - SecurityContext preserveContext = impersonate(impersonatedUser); - if (!Jenkins.getInstance().hasPermission(Item.READ)) { - logger.warn("tested configuration failed on insufficient Jenkins' user permissions"); - validation = FormValidation.errorWithMarkup(ConfigurationParser.markup("red", Messages.JenkinsUserPermissionsFailure())); - } - depersonate(preserveContext); - } catch (FormValidation fv) { - logger.warn("tested configuration failed on impersonating Jenkins' user, most likely non existent user provided", fv); - return fv; - } - - return validation; - } - - public OctaneServerSettingsModel[] getServers() { - if (servers == null) { - servers = new OctaneServerSettingsModel[]{new OctaneServerSettingsModel()}; - } - return servers; - } - - public OctaneServerSettingsModel getModel() { - return getServers()[0]; - } - - public ServerConfiguration getServerConfiguration() { - return convertToServerConfiguration(getModel()); - } - - private SecurityContext impersonate(String user) throws FormValidation { - SecurityContext originalContext = null; - if (user != null && !user.equalsIgnoreCase("")) { - User jenkinsUser = User.get(user, false); - if (jenkinsUser != null) { - originalContext = ACL.impersonate(jenkinsUser.impersonate()); - } else { - throw FormValidation.errorWithMarkup(ConfigurationParser.markup("red", Messages.JenkinsUserPermissionsFailure())); - } - } - return originalContext; - } - - private void depersonate(SecurityContext originalContext) { - if (originalContext != null) { - ACL.impersonate(originalContext.getAuthentication()); - } - } - - @Inject - public void setBdiConfigurationFetcher(BdiConfigurationFetcher bdiConfigurationFetcher) { - this.bdiConfigurationFetcher = bdiConfigurationFetcher; - } - - public FormValidation doCheckInstanceId(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Plugin Instance Id cannot be empty"); - } - - return FormValidation.ok(); - } - - private void validateConfiguration(FormValidation result, String formField) throws FormException { - if (!result.equals(FormValidation.ok())) { - throw new FormException("Validation of property in ALM Octane Server Configuration failed: " + result.getMessage(), formField); - } - } - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/settings/SvServerSettingsBuilder.java b/src/main/java/com/hp/application/automation/tools/settings/SvServerSettingsBuilder.java deleted file mode 100644 index 5e30b9eeb0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/settings/SvServerSettingsBuilder.java +++ /dev/null @@ -1,162 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// 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. - -package com.hp.application.automation.tools.settings; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; - -import com.hp.application.automation.tools.model.SvServerSettingsModel; -import com.hp.sv.jsvconfigurator.core.impl.jaxb.ServerInfo; -import com.hp.sv.jsvconfigurator.core.impl.processor.Credentials; -import com.hp.sv.jsvconfigurator.serverclient.ICommandExecutor; -import com.hp.sv.jsvconfigurator.serverclient.impl.CommandExecutorFactory; -import hudson.CopyOnWrite; -import hudson.Extension; -import hudson.model.AbstractProject; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Builder; -import hudson.util.FormValidation; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -public class SvServerSettingsBuilder extends Builder { - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - /** - * Descriptor for {@link SvServerSettingsBuilder}. Used as a singleton. The class is marked as - * public so that it can be accessed from views. - *

- *

- * See src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly for the - * actual HTML fragment for the configuration screen. - */ - @Extension - // This indicates to Jenkins that this is an implementation of an extension - // point. - public static final class DescriptorImpl extends BuildStepDescriptor { - - @CopyOnWrite - private SvServerSettingsModel[] servers; - - public DescriptorImpl() { - load(); - } - - private static boolean isHttpsSchema(String url) { - try { - return "https".equals(new URL(url).getProtocol()); - } catch (MalformedURLException e) { - return false; - } - } - - @Override - public boolean isApplicable( - @SuppressWarnings("rawtypes") Class aClass) { - // Indicates that this builder can be used with all kinds of project - // types - return true; - } - - /** - * This human readable name is used in the configuration screen. - */ - @Override - public String getDisplayName() { - return ""; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - List list = req.bindJSONToList(SvServerSettingsModel.class, formData.get("srv")); - - validateMandatoryFields(list); - - servers = list.toArray(new SvServerSettingsModel[list.size()]); - - save(); - - return super.configure(req, formData); - } - - private void validateMandatoryFields(List servers) throws FormException { - for (SvServerSettingsModel server : servers) { - validateConfiguration(doCheckName(server.getName()), "name"); - validateConfiguration(doCheckUrl(server.getUrl()), "url"); - validateConfiguration(doCheckUsername(server.getUsername(), server.getUrl()), "username"); - validateConfiguration(doCheckPassword(server.getPassword(), server.getUrl()), "password"); - } - } - - private void validateConfiguration(FormValidation result, String formField) throws FormException { - if (!result.equals(FormValidation.ok())) { - throw new FormException("Validation of property in Service Virtualization server configuration failed: " + result.getMessage(), formField); - } - } - - public FormValidation doCheckUrl(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Management Endpoint URL cannot be empty"); - } - try { - new URL(value); - } catch (MalformedURLException e) { - return FormValidation.error("'" + value + "' is not valid URL"); - } - return FormValidation.ok(); - } - - public FormValidation doCheckUsername(@QueryParameter String value, @QueryParameter("url") final String url) { - if (isHttpsSchema(url) && StringUtils.isBlank(value)) { - return FormValidation.error("Username is required for secured server"); - } - return FormValidation.ok(); - } - - public FormValidation doCheckPassword(@QueryParameter String value, @QueryParameter("url") final String url) { - if (isHttpsSchema(url) && StringUtils.isBlank(value)) { - return FormValidation.error("Password is required for secured server"); - } - return FormValidation.ok(); - } - - @SuppressWarnings("unused") - public FormValidation doTestConnection(@QueryParameter("url") final String url, @QueryParameter("username") final String username, - @QueryParameter("password") final String password) { - try { - Credentials credentials = (!StringUtils.isBlank(username)) ? new Credentials(username, password) : null; - ICommandExecutor commandExecutor = new CommandExecutorFactory().createCommandExecutor(new URL(url), credentials); - ServerInfo serverInfo = commandExecutor.getClient().getServerInfo(); - return FormValidation.ok("Validation passed. Connected to %s server of version: %s", serverInfo.getServerType(), serverInfo.getProductVersion()); - } catch (Exception e) { - return FormValidation.error("Validation failed: " + e.getMessage()); - } - } - - public SvServerSettingsModel[] getServers() { - return servers; - } - - public void setServers(SvServerSettingsModel[] servers) { - this.servers = servers; - } - - public FormValidation doCheckName(@QueryParameter String value) { - if (StringUtils.isBlank(value)) { - return FormValidation.error("Name cannot be empty"); - } - - return FormValidation.ok(); - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/ArgsFactory.java b/src/main/java/com/hp/application/automation/tools/sse/ArgsFactory.java deleted file mode 100644 index 1af113c5bf..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/ArgsFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hp.application.automation.tools.sse; - -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.sse.sdk.Args; - -import hudson.Util; -import hudson.util.VariableResolver; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class ArgsFactory { - - public Args create(SseModel model) { - - return new Args( - - model.getAlmServerUrl(), - model.getAlmDomain(), - model.getAlmProject(), - model.getAlmUserName(), - model.getAlmPassword(), - model.getRunType(), - model.getAlmEntityId(), - model.getTimeslotDuration(), - model.getDescription(), - model.getPostRunAction(), - model.getEnvironmentConfigurationId(), - model.getCdaDetails()); - } - - public Args createResolved(SseModel model, VariableResolver buildResolver) { - - return new Args( - - model.getAlmServerUrl(), - Util.replaceMacro(model.getAlmDomain(), buildResolver), - Util.replaceMacro(model.getAlmProject(), buildResolver), - Util.replaceMacro(model.getAlmUserName(), buildResolver), - model.getAlmPassword(), - model.getRunType(), - Util.replaceMacro(model.getAlmEntityId(), buildResolver), - Util.replaceMacro(model.getTimeslotDuration(), buildResolver), - model.getDescription(), - model.getPostRunAction(), - Util.replaceMacro(model.getEnvironmentConfigurationId(), buildResolver), - model.getCdaDetails()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/SSEBuilderPerformer.java b/src/main/java/com/hp/application/automation/tools/sse/SSEBuilderPerformer.java deleted file mode 100644 index df177a3bcb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/SSEBuilderPerformer.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.hp.application.automation.tools.sse; - -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.model.SseProxySettings; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; -import com.hp.application.automation.tools.sse.sdk.Args; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.RunManager; -import hudson.util.VariableResolver; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class SSEBuilderPerformer { - - private final RunManager _runManager = new RunManager(); - - public Testsuites start( - SseModel model, - Logger logger, - VariableResolver buildVariableResolver) throws InterruptedException { - - Testsuites ret = new Testsuites(); - try { - Args args = new ArgsFactory().createResolved(model, buildVariableResolver); - SseProxySettings proxySettings = model.getProxySettings(); - - RestClient restClient; - - if (proxySettings != null) { - // Construct restClient with proxy. - String username = proxySettings.getFsProxyUserName(); - String password = proxySettings.getFsProxyPassword() == null ? null : proxySettings.getFsProxyPassword().getPlainText(); - String passwordCrypt = proxySettings.getFsProxyPassword() == null ? null : proxySettings.getFsProxyPassword().getEncryptedValue(); - - restClient = new RestClient(args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername(), - RestClient.setProxyCfg(proxySettings.getFsProxyAddress(), username, password)); - logger.log(String.format("Connect with proxy. Address: %s, Username: %s, Password: %s", - proxySettings.getFsProxyAddress(), username, passwordCrypt)); - } - else { - // Construct restClient without proxy. - restClient = new RestClient(args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - } - ret = _runManager.execute(restClient, args, logger); - } - catch (InterruptedException ex) { - throw ex; - } - catch (Exception cause) { - logger.log(String.format("Failed to execute ALM tests. Cause: %s", cause.getMessage())); - } - - return ret; - } - - public void stop() { - _runManager.stop(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java deleted file mode 100644 index 7559d556e1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment; - -import java.util.Collection; -import java.util.List; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.AUTEnvironmentResolvedModel; -import com.hp.application.automation.tools.model.AutEnvironmentParameterModel; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.sdk.*; -import hudson.util.VariableResolver; - -/** - * Created by barush on 29/10/2014. - */ -public class AUTEnvironmentBuilderPerformer { - - private Logger logger; - private AUTEnvironmentResolvedModel model; - private RestClient restClient; - private VariableResolver buildVariableResolver; - private String autEnvironmentConfigurationIdToReturn; - - public AUTEnvironmentBuilderPerformer( - AUTEnvironmentResolvedModel model, - VariableResolver buildVariableResolver, - Logger logger) { - - this.model = model; - this.logger = logger; - this.buildVariableResolver = buildVariableResolver; - } - - public void start() throws Throwable { - - try { - if (login(getClient())) { - appendQCSessionCookies(getClient()); - performAutOperations(); - } else { - throw new SSEException("Failed to login to ALM"); - } - } catch (Throwable cause) { - logger.log(String.format( - "Failed to update ALM AUT Environment. Cause: %s", - cause.getMessage())); - throw cause; - } - } - - public String getAutEnvironmentConfigurationIdToReturn() { - return autEnvironmentConfigurationIdToReturn; - } - - private void performAutOperations() { - - String autEnvironmentId = model.getAutEnvironmentId(); - AUTEnvironmentManager autEnvironmentManager = - new AUTEnvironmentManager(getClient(), logger); - String parametersRootFolderId = - autEnvironmentManager.getParametersRootFolderIdByAutEnvId(autEnvironmentId); - String autEnvironmentConfigurationId = - getAutEnvironmentConfigurationId(autEnvironmentManager, autEnvironmentId); - - assignValuesToAutParameters(autEnvironmentConfigurationId, parametersRootFolderId); - autEnvironmentConfigurationIdToReturn = autEnvironmentConfigurationId; - - } - - private void assignValuesToAutParameters( - String autEnvironmentConfigurationId, - String parametersRootFolderId) { - - List autEnvironmentParameters = - model.getAutEnvironmentParameters(); - if (autEnvironmentParameters == null || autEnvironmentParameters.size() == 0) { - logger.log("There's no AUT Environment parameters to assign for this build..."); - return; - } - - AUTEnvironmentParametersManager parametersManager = - new AUTEnvironmentParametersManager( - getClient(), - autEnvironmentParameters, - parametersRootFolderId, - autEnvironmentConfigurationId, - buildVariableResolver, - model.getPathToJsonFile(), - logger); - - Collection parametersToUpdate = - parametersManager.getParametersToUpdate(); - parametersManager.updateParametersValues(parametersToUpdate); - } - - private boolean login(Client client) { - - boolean ret; - try { - ret = - new RestAuthenticator().login( - client, - model.getAlmUserName(), - model.getAlmPassword(), - logger); - } catch (Throwable cause) { - ret = false; - logger.log(String.format( - "Failed login to ALM Server URL: %s. Exception: %s", - model.getAlmServerUrl(), - cause.getMessage())); - } - - return ret; - } - - private void appendQCSessionCookies(RestClient client) { - - Response response = - client.httpPost( - client.build("rest/site-session"), - null, - null, - ResourceAccessLevel.PUBLIC); - if (!response.isOk()) { - throw new SSEException("Cannot append QCSession cookies", response.getFailure()); - } - } - - private String getAutEnvironmentConfigurationId( - AUTEnvironmentManager autEnvironmentManager, - String autEnvironmentId) { - - String autEnvironmentConfigurationId = - autEnvironmentManager.shouldUseExistingConfiguration(model) - ? model.getExistingAutEnvConfId() - : autEnvironmentManager.createNewAutEnvironmentConfiguration( - autEnvironmentId, - model); - - if (StringUtils.isNullOrEmpty(autEnvironmentConfigurationId)) { - throw new SSEException("There's no AUT Environment Configuration in order to proceed"); - } - return autEnvironmentConfigurationId; - - } - - private RestClient getClient() { - if (restClient == null) { - restClient = - new RestClient( - model.getAlmServerUrl(), - model.getAlmDomain(), - model.getAlmProject(), - model.getAlmUserName()); - } - - return restClient; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java deleted file mode 100644 index ea3e1eec62..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment; - -/** - * Created by barush on 02/11/2014. - */ -public class AUTEnvironmentFolder { - - public final static String ALM_PARAMETER_FOLDER_ID_FIELD = "id"; - public final static String ALM_PARAMETER_FOLDER_PARENT_ID_FIELD = "parent-id"; - public final static String ALM_PARAMETER_FOLDER_NAME_FIELD = "name"; - - private String id; - private String name; - private String parentId; - private String path; - - public AUTEnvironmentFolder(String id, String parentId, String name) { - - this.id = id; - this.parentId = parentId; - this.name = name; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getParentId() { - return parentId; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java deleted file mode 100644 index 024873ecbe..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.AUTEnvironmentResolvedModel; -import com.hp.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentByIdOldApiRequest; -import com.hp.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentByIdRequest; -import com.hp.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentConfigurationByIdRequest; -import com.hp.application.automation.tools.sse.autenvironment.request.post.CreateAutEnvConfRequest; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; - -import java.net.HttpURLConnection; -import java.util.Calendar; -import java.util.List; -import java.util.Map; - -/** - * Created by barush on 03/11/2014. - */ -public class AUTEnvironmentManager { - - public final static String ALM_AUT_ENVIRONMENT_CONFIGURATION_ID_FIELD = "id"; - - private Logger logger; - private Client client; - - public AUTEnvironmentManager(Client client, Logger logger) { - - this.client = client; - this.logger = logger; - } - - public String getParametersRootFolderIdByAutEnvId(String autEnvironmentId) { - - String parametersRootFolderId = null; - Response response = new GetAutEnvironmentByIdRequest(client, autEnvironmentId).execute(); - /** - * This if here for backward compatibility to ALM 11.52. After the support for version < - * 12.00 will be removed this 'if' statement can be removed - * **/ - if (!response.isOk() && response.getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { - response = new GetAutEnvironmentByIdOldApiRequest(client, autEnvironmentId).execute(); - } - try { - List> entities = XPathUtils.toEntities(response.toString()); - if (!response.isOk() || entities.size() != 1) { - throw new SSEException(String.format( - "Failed to get AUT Environment with ID: [%s]", - autEnvironmentId), response.getFailure()); - } - - Map autEnvironment = entities.get(0); - parametersRootFolderId = - autEnvironment == null ? null : autEnvironment.get("root-app-param-folder-id"); - } catch (Throwable e) { - logger.log(String.format("Failed to parse response: %s", response)); - } - - return parametersRootFolderId; - } - - public String createNewAutEnvironmentConfiguration( - String autEnvironmentId, - AUTEnvironmentResolvedModel autEnvironmentModel) { - - String newConfigurationName = - autEnvironmentModel.isUseExistingAutEnvConf() - || StringUtils.isNullOrEmpty(autEnvironmentModel.getNewAutEnvConfName()) - ? createTempConfigurationName() - : autEnvironmentModel.getNewAutEnvConfName(); - return createNewAutEnvironmentConfiguration(autEnvironmentId, newConfigurationName); - - } - - private String createNewAutEnvironmentConfiguration( - String autEnvironmentId, - String newAutEnvConfigurationName) { - - String newAutEnvironmentConfigurationId = null; - Response response = - new CreateAutEnvConfRequest(client, autEnvironmentId, newAutEnvConfigurationName).execute(); - if (!response.isOk()) { - logger.log(String.format( - "Failed to create new AUT Environment Configuration named: [%s] for AUT Environment with id: [%s]", - newAutEnvConfigurationName, - autEnvironmentId)); - return null; - } - try { - newAutEnvironmentConfigurationId = - XPathUtils.getAttributeValue( - response.toString(), - ALM_AUT_ENVIRONMENT_CONFIGURATION_ID_FIELD); - } catch (Throwable e) { - logger.log(String.format("Failed to parse response: %s", response)); - } - - return newAutEnvironmentConfigurationId; - } - - public boolean shouldUseExistingConfiguration(AUTEnvironmentResolvedModel autEnvironmentModel) { - - return autEnvironmentModel.isUseExistingAutEnvConf() - && isAutEnvironmentConfigurationExists(autEnvironmentModel.getExistingAutEnvConfId()); - - } - - private boolean isAutEnvironmentConfigurationExists(String existingAutEnvConfId) { - - Response response = - new GetAutEnvironmentConfigurationByIdRequest(client, existingAutEnvConfId).execute(); - if (!response.isOk() || XPathUtils.toEntities(response.toString()).size() != 1) { - logger.log(String.format( - "Failed to get AUT Environment Configuration with ID: [%s]. Will try to create a new one", - existingAutEnvConfId)); - return false; - } - return true; - - } - - private String createTempConfigurationName() { - - return "Configuration_" + Calendar.getInstance().getTime().toString(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java deleted file mode 100644 index 05ab33445f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java +++ /dev/null @@ -1,242 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.AutEnvironmentParameterModel; -import com.hp.application.automation.tools.sse.autenvironment.request.get.GetAutEnvFoldersByIdRequest; -import com.hp.application.automation.tools.sse.autenvironment.request.get.GetParametersByAutEnvConfIdRequest; -import com.hp.application.automation.tools.sse.autenvironment.request.put.PutAutEnvironmentParametersBulkRequest; -import com.hp.application.automation.tools.sse.common.JsonHandler; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import hudson.util.VariableResolver; - -import java.util.*; - -/** - * Created by barush on 29/10/2014. - */ -public class AUTEnvironmentParametersManager { - - public final static String PARAMETER_PATH_DELIMITER = "/"; - - private Logger logger; - private Client client; - private List parametersToAssign; - private String parametersRootFolderId; - private String autEnvironmentConfigurationId; - private Map parameters; - - private VariableResolver buildVariableResolver; - private String pathToJsonFile; - - public AUTEnvironmentParametersManager( - Client client, - List parametersToAssign, - String parametersRootFolderId, - String autEnvironmentConfigurationId, - VariableResolver buildVariableResolver, - String pathToJsonFile, - Logger logger) { - - this.logger = logger; - this.client = client; - this.parametersToAssign = parametersToAssign; - this.parametersRootFolderId = parametersRootFolderId; - this.autEnvironmentConfigurationId = autEnvironmentConfigurationId; - this.buildVariableResolver = buildVariableResolver; - this.pathToJsonFile = pathToJsonFile; - } - - public Collection getParametersToUpdate() { - - parameters = getAllParametersByAutEnvConfId(); - Map parametersFolders = getAllRelevantParametersFolders(); - - for (AUTEnvironmnentParameter parameter : parameters.values()) { - parameter.setFullPath(parametersFolders.get(parameter.getParentId()).getPath() - + PARAMETER_PATH_DELIMITER - + parameter.getName()); - - } - - resolveValuesOfParameters(); - return getResolvedParametersWithAssignedValues(); - } - - public void updateParametersValues(Collection parametersToUpdate) { - - Response response = - new PutAutEnvironmentParametersBulkRequest(client, parametersToUpdate).execute(); - if (!response.isOk()) { - throw new SSEException( - String.format( - "Failed to update the parameters of AUT Environment Configuration with ID: [%s]", - autEnvironmentConfigurationId), - response.getFailure()); - } - logger.log("Submitted all parameters to ALM"); - } - - private Map getAllParametersByAutEnvConfId() { - - Map parametersMap = - new HashMap(); - Response response = - new GetParametersByAutEnvConfIdRequest(client, autEnvironmentConfigurationId).execute(); - if (!response.isOk()) { - throw new SSEException( - String.format( - "Failed to retrieve the parameters of AUT Environment Configuration with ID: [%s]", - autEnvironmentConfigurationId), - response.getFailure()); - } - - List> parameters = XPathUtils.toEntities(response.toString()); - - for (Map parameter : parameters) { - - String id = parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_ID_FIELD); - AUTEnvironmnentParameter param = - new AUTEnvironmnentParameter( - id, - parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_PARENT_ID_FIELD), - parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_NAME_FIELD)); - parametersMap.put(id, param); - - } - - return parametersMap; - - } - - private Map getAllRelevantParametersFolders() { - - Map parametersFolders = - new HashMap(); - StringBuilder foldersToGet = new StringBuilder(parametersRootFolderId); - - for (AUTEnvironmnentParameter parameter : parameters.values()) { - foldersToGet.append("%20OR%20" + parameter.getParentId()); - } - - Response response = - new GetAutEnvFoldersByIdRequest(client, foldersToGet.toString()).execute(); - if (!response.isOk()) { - throw new SSEException( - String.format( - "Failed to retrieve parameters folders of AUT Environment Configuration with ID: [%s]", - autEnvironmentConfigurationId), - response.getFailure()); - } - - List> folders = XPathUtils.toEntities(response.toString()); - - for (Map folder : folders) { - - String folderId = folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_ID_FIELD); - if (!parametersFolders.containsKey(folderId)) { - AUTEnvironmentFolder autEnvironmentFolder = - new AUTEnvironmentFolder( - folderId, - folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_PARENT_ID_FIELD), - folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_NAME_FIELD)); - parametersFolders.put(folderId, autEnvironmentFolder); - - } - } - - for (AUTEnvironmentFolder folder : parametersFolders.values()) { - calculatePaths(folder, parametersFolders); - } - return parametersFolders; - } - - private String calculatePaths( - AUTEnvironmentFolder folder, - Map parametersFolders) { - - String calculatedPath; - if (folder.getId().equals(parametersRootFolderId)) { - calculatedPath = folder.getName(); - } else { - calculatedPath = - StringUtils.isNullOrEmpty(folder.getPath()) - ? calculatePaths( - parametersFolders.get(folder.getParentId()), - parametersFolders) - + PARAMETER_PATH_DELIMITER - + folder.getName() : folder.getPath(); - } - - folder.setPath(calculatedPath); - return calculatedPath; - } - - private void resolveValuesOfParameters() { - - boolean shouldLoadJsonObject = true; - Object jsonObject = null; - JsonHandler jsonHandler = new JsonHandler(logger); - - for (AutEnvironmentParameterModel parameter : parametersToAssign) { - String resolvedValue = ""; - switch (AutEnvironmentParameterModel.AutEnvironmentParameterType.get(parameter.getParamType())) { - - case ENVIRONMENT: - resolvedValue = buildVariableResolver.resolve(parameter.getValue()); - break; - case EXTERNAL: - if (shouldLoadJsonObject) { - jsonObject = jsonHandler.load(pathToJsonFile); - shouldLoadJsonObject = false; - } - resolvedValue = - jsonHandler.getValueFromJsonAsString( - jsonObject, - parameter.getValue(), - parameter.isShouldGetOnlyFirstValueFromJson()); - break; - case USER_DEFINED: - resolvedValue = parameter.getValue(); - break; - case UNDEFINED: - resolvedValue = ""; - break; - } - - parameter.setResolvedValue(resolvedValue); - } - - } - - private Collection getResolvedParametersWithAssignedValues() { - - Collection valuesToReturn = - new ArrayList(); - for (AutEnvironmentParameterModel parameterByModel : parametersToAssign) { - String parameterPathByModel = parameterByModel.getName(); - for (AUTEnvironmnentParameter parameter : parameters.values()) { - if (parameterPathByModel.equalsIgnoreCase(parameter.getFullPath())) { - String resolvedValue = parameterByModel.getResolvedValue(); - parameter.setValue(resolvedValue); - logger.log(String.format( - "Parameter: [%s] of type: [%s] will get the value: [%s] ", - parameter.getFullPath(), - parameterByModel.getParamType(), - resolvedValue)); - valuesToReturn.add(parameter); - break; - } - } - - } - logger.log(parametersToAssign.size() > 0 - ? "Finished assignment of values for all parameters" - : "There was no parameters to assign"); - - return valuesToReturn; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java deleted file mode 100644 index 5aefe0e154..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment; - -/** - * Created by barush on 02/11/2014. - */ -public class AUTEnvironmnentParameter { - - public final static String ALM_PARAMETER_ID_FIELD = "id"; - public final static String ALM_PARAMETER_PARENT_ID_FIELD = "parent-id"; - public final static String ALM_PARAMETER_NAME_FIELD = "name"; - public final static String ALM_PARAMETER_VALUE_FIELD = "value"; - - private String id; - private String parentId; - private String name; - private String value; - private String fullPath; - - public AUTEnvironmnentParameter(String id, String parentId, String name) { - - this.id = id; - this.parentId = parentId; - this.name = name; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getFullPath() { - return fullPath; - } - - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - - public String getId() { - return id; - } - - public String getParentId() { - return parentId; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java deleted file mode 100644 index 92eed9ed3c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request; - -/** - * Created by barush on 29/10/2014. - */ -public class AUTEnvironmentResources { - - public final static String AUT_ENVIRONMENT_CONFIGURATIONS = "aut-environment-configurations"; - public final static String AUT_ENVIRONMENT_PARAMETER_VALUES = - "aut-environment-parameter-values"; - public final static String AUT_ENVIRONMENTS = "aut-environments"; - public final static String AUT_ENVIRONMENTS_OLD = "AppParamSets"; - public final static String AUT_ENVIRONMENT_PARAMETER_FOLDERS = - "aut-environment-parameter-folders"; -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java deleted file mode 100644 index ccf0beb120..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.get; - -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralGetRequest; - -/** - * Created by barush on 02/11/2014. - */ -public class GetAutEnvFoldersByIdRequest extends GeneralGetRequest { - - private String folderId; - - public GetAutEnvFoldersByIdRequest(Client client, String folderId) { - - super(client); - this.folderId = folderId; - } - - @Override - protected String getSuffix() { - - return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_FOLDERS; - } - - @Override - protected String getQueryString() { - - return String.format("query={id[%s]}&page-size=2000", folderId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java deleted file mode 100644 index f222bfc695..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.get; - -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralGetRequest; - -/** - * Created by barush on 02/11/2014. - */ -public class GetAutEnvironmentByIdOldApiRequest extends GeneralGetRequest { - - private String autEnvironmentId; - - public GetAutEnvironmentByIdOldApiRequest(Client client, String autEnvironmentId) { - - super(client); - this.autEnvironmentId = autEnvironmentId; - } - - @Override - protected String getSuffix() { - - return AUTEnvironmentResources.AUT_ENVIRONMENTS_OLD; - - } - - @Override - protected String getQueryString() { - - return String.format("query={id[%s]}", autEnvironmentId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java deleted file mode 100644 index e160989aaa..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.get; - -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralGetRequest; - -/** - * Created by barush on 02/11/2014. - */ -public class GetAutEnvironmentByIdRequest extends GeneralGetRequest { - - private String autEnvironmentId; - - public GetAutEnvironmentByIdRequest(Client client, String autEnvironmentId) { - - super(client); - this.autEnvironmentId = autEnvironmentId; - } - - @Override - protected String getSuffix() { - - return AUTEnvironmentResources.AUT_ENVIRONMENTS; - - } - - @Override - protected String getQueryString() { - - return String.format("query={id[%s]}", autEnvironmentId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java deleted file mode 100644 index f5bd8ab08d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.get; - -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralGetRequest; - -/** - * Created by barush on 03/11/2014. - */ -public class GetAutEnvironmentConfigurationByIdRequest extends GeneralGetRequest { - - private String autEnvironmentConfigurationId; - - public GetAutEnvironmentConfigurationByIdRequest( - Client client, - String autEnvironmentConfigurationId) { - - super(client); - this.autEnvironmentConfigurationId = autEnvironmentConfigurationId; - } - - @Override - protected String getSuffix() { - - return AUTEnvironmentResources.AUT_ENVIRONMENT_CONFIGURATIONS; - - } - - @Override - protected String getQueryString() { - - return String.format("query={id[%s]}", autEnvironmentConfigurationId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java deleted file mode 100644 index 6acbc85a4c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.get; - -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralGetRequest; - -/** - * Created by barush on 30/10/2014. - */ -public class GetParametersByAutEnvConfIdRequest extends GeneralGetRequest { - - String configurationId; - - public GetParametersByAutEnvConfIdRequest(Client client, String configurationId) { - - super(client); - this.configurationId = configurationId; - } - - @Override - protected String getSuffix() { - - return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_VALUES; - } - - @Override - protected String getQueryString() { - - return String.format("query={app-param-value-set-id[%s]}&page-size=2000", configurationId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java deleted file mode 100644 index 065e4608ee..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.post; - -import java.util.ArrayList; -import java.util.List; - -import com.hp.application.automation.tools.common.Pair; -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralPostRequest; - -/** - * Created by barush on 29/10/2014. - */ -public class CreateAutEnvConfRequest extends GeneralPostRequest { - - private String autEnvironmentId; - private String name; - - public CreateAutEnvConfRequest(Client client, String autEnvironmentId, String name) { - - super(client); - this.autEnvironmentId = autEnvironmentId; - this.name = name; - } - - @Override - protected String getSuffix() { - return AUTEnvironmentResources.AUT_ENVIRONMENT_CONFIGURATIONS; - } - - @Override - protected List> getDataFields() { - - List> ret = new ArrayList>(); - ret.add(new Pair("app-param-set-id", autEnvironmentId)); - ret.add(new Pair("name", name)); - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java b/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java deleted file mode 100644 index 6cdcf7efd1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.hp.application.automation.tools.sse.autenvironment.request.put; - -import com.hp.application.automation.tools.sse.autenvironment.AUTEnvironmnentParameter; -import com.hp.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.request.GeneralPutBulkRequest; - -import java.util.*; - -/** - * Created by barush on 03/11/2014. - */ -public class PutAutEnvironmentParametersBulkRequest extends GeneralPutBulkRequest { - - private Collection parameters; - - public PutAutEnvironmentParametersBulkRequest( - Client client, - Collection parameters) { - super(client); - this.parameters = parameters; - } - - @Override - protected List> getFields() { - - List> fieldsToUpdate = new ArrayList>(); - for (AUTEnvironmnentParameter autEnvironmnentParameter : parameters) { - Map mapOfValues = new HashMap(); - mapOfValues.put( - AUTEnvironmnentParameter.ALM_PARAMETER_ID_FIELD, - autEnvironmnentParameter.getId()); - mapOfValues.put( - AUTEnvironmnentParameter.ALM_PARAMETER_VALUE_FIELD, - autEnvironmnentParameter.getValue()); - fieldsToUpdate.add(mapOfValues); - } - - return fieldsToUpdate; - } - - @Override - protected String getSuffix() { - return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_VALUES; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/common/JsonHandler.java b/src/main/java/com/hp/application/automation/tools/sse/common/JsonHandler.java deleted file mode 100644 index 94a78436b9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/common/JsonHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.hp.application.automation.tools.sse.common; - -import java.io.FileInputStream; -import java.io.InputStream; - -import net.minidev.json.JSONArray; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.jayway.jsonpath.Configuration; -import com.jayway.jsonpath.JsonPath; -import com.jayway.jsonpath.Option; -import hudson.util.IOUtils; - -/** - * Created by barush on 06/11/2014. - */ -public class JsonHandler { - - private Logger logger; - - public JsonHandler(Logger logger) { - this.logger = logger; - } - - public Object load(String path) { - - logger.log(String.format("Loading JSON file from: [%s]", path)); - Object parsedJson; - try { - InputStream is = new FileInputStream(path); - String jsonTxt; - jsonTxt = IOUtils.toString(is, "UTF-8"); - parsedJson = - Configuration.defaultConfiguration().addOptions(Option.ALWAYS_RETURN_LIST).jsonProvider().parse( - jsonTxt); - } catch (Throwable e) { - throw new SSEException(String.format("Failed to load JSON from: [%s]", path), e); - } - - return parsedJson; - } - - public String getValueFromJsonAsString( - Object jsonObject, - String pathToRead, - boolean shouldGetSingleValueOnly) { - - String value = ""; - try { - Object extractedObject = JsonPath.read(jsonObject, pathToRead); - while (extractedObject instanceof JSONArray && shouldGetSingleValueOnly) { - extractedObject = ((JSONArray) extractedObject).get(0); - } - value = extractedObject.toString(); - } catch (Throwable e) { - logger.log(String.format( - "Failed to get the value of [%s] from the JSON file.\n\tError was: %s", - pathToRead, - e.getMessage())); - } - return value; - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/common/RestXmlUtils.java b/src/main/java/com/hp/application/automation/tools/sse/common/RestXmlUtils.java deleted file mode 100644 index 78b10e24e9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/common/RestXmlUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.hp.application.automation.tools.sse.common; - -import com.hp.application.automation.tools.rest.RESTConstants; - -import java.util.HashMap; -import java.util.Map; - - -/*** - * @author Effi Bar-She'an - * @author Dani Schreiber - */ -public class RestXmlUtils { - - public static String fieldXml(String field, String value) { - - return String.format("%s", field, value); - } - - public static Map getAppXmlHeaders() { - - Map ret = new HashMap(); - ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); - ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); - - return ret; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/common/StringUtils.java b/src/main/java/com/hp/application/automation/tools/sse/common/StringUtils.java deleted file mode 100644 index 238076774c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/common/StringUtils.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hp.application.automation.tools.sse.common; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class StringUtils { - - public static final String NEW_LINE = System.getProperty("line.separator"); - public static final String FILE_SEPARATOR = System.getProperty("file.separator"); - public static final String PATH_SEPARATOR = System.getProperty("path.separator"); - - public static final String EMPTY_STRING = ""; - public static final String SPACE = " "; - public static final String PERIOD = "."; - public static final String TAB = "\t"; - - public static boolean isNullOrEmpty(String value) { - - return (value == null) || (value.length() == 0); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/common/XPathUtils.java b/src/main/java/com/hp/application/automation/tools/sse/common/XPathUtils.java deleted file mode 100644 index 60ca4361a3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/common/XPathUtils.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.hp.application.automation.tools.sse.common; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - -import com.hp.application.automation.tools.common.SSEException; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class XPathUtils { - - public static List> toEntities(String xml) { - - Document document = getDocument(xml); - - List> ret = new ArrayList>(); - NodeList entities = document.getElementsByTagName("Entity"); - for (int i = 0; i < entities.getLength(); i++) { - Map currEntity = new HashMap(); - NodeList fields = ((Element) entities.item(i)).getElementsByTagName("Field"); - for (int j = 0; j < fields.getLength(); j++) { - Node item = fields.item(j); - currEntity.put(item.getAttributes().item(0).getNodeValue(), getFieldValue(item)); - } - ret.add(currEntity); - } - - return ret; - } - - public static String getAttributeValue(String xml, String attrName) { - - NodeList nodes = getChildNodes(xml, "Entity/Fields/Field"); - String ret = StringUtils.EMPTY_STRING; - for (int i = 0; i < nodes.getLength(); i++) { - Node currNode = nodes.item(i); - String attr; - try { - attr = getNecessaryAttribute(currNode, "Name"); - } catch (Throwable cause) { - throw new SSEException(cause); - } - if (attr.equals(attrName)) { - ret = getFieldValue(currNode); - break; - } - } - - return ret; - } - - private static String getFieldValue(Node node) { - - String ret = null; - Node child = node.getFirstChild(); - if (child != null) { - Node child2 = child.getFirstChild(); - if (child2 != null) { - ret = child2.getNodeValue(); - } - } - - return ret; - } - - private static NodeList getChildNodes(String xml, String xpath) { - - NodeList ret = null; - try { - Document document = getDocument(xml); - XPathFactory factory = XPathFactory.newInstance(); - XPathExpression expression = factory.newXPath().compile(xpath); - ret = (NodeList) expression.evaluate(document, XPathConstants.NODESET); - } catch (Throwable cause) { - throw new SSEException(cause); - } - - return ret; - } - - private static String getNecessaryAttribute(Node node, String attributeName) { - - if (!node.hasAttributes()) { - return null; - } - Node attr = node.getAttributes().getNamedItem(attributeName); - if (attr == null) { - throw new SSEException(String.format( - "Error parsing XML, missing mandatory attribute '%s'", - attributeName)); - } - String ret = attr.getNodeValue(); - if (StringUtils.isNullOrEmpty(ret)) { - throw new SSEException(String.format( - "Error parsing XML, mandatory attribute '%s' cannot be empty", //$NON-NLS-1$ - attributeName)); - } - - return ret; - } - - private static Document getDocument(String xml) { - - Document ret = null; - try { - DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - InputSource inputSource = new InputSource(); - inputSource.setCharacterStream(new StringReader(xml)); - ret = builder.parse(inputSource); - } catch (Throwable cause) { - throw new SSEException(cause); - } - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/JUnitParser.java b/src/main/java/com/hp/application/automation/tools/sse/result/JUnitParser.java deleted file mode 100644 index f5a4911ea8..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/JUnitParser.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.hp.application.automation.tools.sse.result; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.result.model.junit.Error; -import com.hp.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; -import com.hp.application.automation.tools.sse.result.model.junit.Testcase; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuite; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; - -public class JUnitParser { - - public Testsuites toModel( - List> testInstanceRuns, - String entityName, - String runEntityId, - String url, - String domain, - String project) { - - Map testSetIdToTestsuite = getTestSets(testInstanceRuns); - addTestcases( - testInstanceRuns, - testSetIdToTestsuite, - entityName, - runEntityId, - url, - domain, - project); - - return createTestsuites(testSetIdToTestsuite); - } - - private Testsuites createTestsuites(Map testSetIdToTestsuite) { - - Testsuites ret = new Testsuites(); - List testsuites = ret.getTestsuite(); - for (Testsuite currTestsuite : testSetIdToTestsuite.values()) { - testsuites.add(currTestsuite); - } - - return ret; - } - - private void addTestcases( - List> testInstanceRuns, - Map testSetIdToTestsuite, - String bvsName, - String runEntityId, - String url, - String domain, - String project) { - - for (Map currEntity : testInstanceRuns) { - addTestcase( - testSetIdToTestsuite, - currEntity, - bvsName, - runEntityId, - url, - domain, - project); - } - } - - private void addTestcase( - Map testSetIdToTestsuite, - Map currEntity, - String bvsName, - String runEntityId, - String url, - String domain, - String project) { - - testSetIdToTestsuite.get(getTestSetId(currEntity)).getTestcase().add( - getTestcase(currEntity, bvsName, runEntityId, url, domain, project)); - } - - private Testcase getTestcase( - Map entity, - String bvsName, - String runEntityId, - String url, - String domain, - String project) { - - Testcase ret = new Testcase(); - ret.setClassname(getTestSetName(entity, bvsName, runEntityId)); - ret.setName(getTestName(entity)); - ret.setTime(getTime(entity)); - new TestcaseStatusUpdater().update(ret, entity, url, domain, project); - - return ret; - } - - private String getTestSetName(Map entity, String bvsName, String runEntityId) { - - String ret = String.format("%s.(Unnamed test set)", bvsName); - String testSetName = entity.get("testset-name"); - if (!StringUtils.isNullOrEmpty(testSetName)) { - ret = String.format("%s (RunId:%s).%s", bvsName, runEntityId, testSetName); - } - - return ret; - } - - private String getTestInstanceRunId(Map entity) { - - String ret = "No test instance run ID"; - String runId = entity.get("run-id"); - if (!StringUtils.isNullOrEmpty(runId)) { - ret = String.format("Test instance run ID: %s", runId); - } - - return ret; - } - - private String getTestName(Map entity) { - - String testName = entity.get("test-name"); - if (StringUtils.isNullOrEmpty(testName)) { - testName = "Unnamed test"; - } - - return String.format("%s (%s)", testName, getTestInstanceRunId(entity)); - } - - private String getTime(Map entity) { - - String ret = entity.get("duration"); - if (StringUtils.isNullOrEmpty(ret)) { - ret = "0"; - } else { - ret = String.valueOf(Double.parseDouble(ret) * 1000); - } - - return ret; - } - - private Map getTestSets(List> testInstanceRuns) { - - Map ret = new HashMap(); - for (Map currEntity : testInstanceRuns) { - - String testSetId = getTestSetId(currEntity); - if (!ret.containsKey(testSetId)) { - ret.put(testSetId, new Testsuite()); - } - } - - return ret; - } - - private String getTestSetId(Map entity) { - - return entity.get("testcycl-id"); - } - - private static class TestcaseStatusUpdater { - - public void update( - Testcase testcase, - Map entity, - String url, - String domain, - String project) { - - String status = entity.get("status"); - testcase.setStatus(getJenkinsStatus(status)); - if (testcase.getStatus().equals(JUnitTestCaseStatus.ERROR)) { - String errorMessage = status; - if (errorMessage != null) { - Error error = new Error(); - error.setMessage(String.format( - "Error: %s. %s", - errorMessage, - getTestInstanceRunLink(entity, url, domain, project))); - testcase.getError().add(error); - } - } - } - - private String getTestInstanceRunLink( - Map entity, - String url, - String domain, - String project) { - - String ret = StringUtils.EMPTY_STRING; - String runId = entity.get("run-id"); - if (!StringUtils.isNullOrEmpty(runId)) { - try { - ret = - String.format( - "To see the test instance run in ALM, go to: td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", - project, - domain, - new URL(url).getHost(), - runId); - } catch (MalformedURLException ex) { - throw new SSEException(ex); - } - } - - return ret; - } - - private String getJenkinsStatus(String status) { - - return (!StringUtils.isNullOrEmpty(status) && "Passed".equals(status)) - ? JUnitTestCaseStatus.PASS - : JUnitTestCaseStatus.ERROR; - } - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/LabPublisher.java b/src/main/java/com/hp/application/automation/tools/sse/result/LabPublisher.java deleted file mode 100644 index b43c99919c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/LabPublisher.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.hp.application.automation.tools.sse.result; - -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.request.GetLabRunEntityTestSetRunsRequest; -import com.hp.application.automation.tools.sse.sdk.request.GetRequest; - -/** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class LabPublisher extends Publisher { - - public LabPublisher(Client client, String entityId, String runId) { - - super(client, entityId, runId); - } - - @Override - protected String getEntityName(String nameSuffix, Logger logger) { - - String ret = "Unnamed Entity"; - try { - Response response = getEntityName(nameSuffix); - if (response.isOk() && !response.toString().equals("")) { - ret = XPathUtils.getAttributeValue(response.toString(), "name"); - } else { - Throwable failure = response.getFailure(); - logger.log(String.format( - "Failed to get Entity name. Exception: %s", - failure == null ? "null" : failure.getMessage())); - } - } catch (Throwable e) { - logger.log("Failed to get Entity name"); - } - - return ret; - } - - @Override - protected GetRequest getRunEntityTestSetRunsRequest(Client client, String runId) { - - return new GetLabRunEntityTestSetRunsRequest(_client, _runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/PCPublisher.java b/src/main/java/com/hp/application/automation/tools/sse/result/PCPublisher.java deleted file mode 100644 index 9557ed6e6c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/PCPublisher.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.hp.application.automation.tools.sse.result; - -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.request.GetPCRunEntityTestSetRunsRequest; -import com.hp.application.automation.tools.sse.sdk.request.GetRequest; - -/** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class PCPublisher extends Publisher { - - public PCPublisher(Client client, String entityId, String runId) { - - super(client, entityId, runId); - } - - protected String getEntityName(String nameSuffix, Logger logger) { - - String ret = "Unnamed Entity"; - try { - Response response = getEntityName(nameSuffix); - if (response.isOk() && !response.toString().equals("")) { - String runId = XPathUtils.getAttributeValue(response.toString(), "id"); - String testId = XPathUtils.getAttributeValue(response.toString(), "testcycl-id"); - String testSetId = XPathUtils.getAttributeValue(response.toString(), "cycle-id"); - ret = - String.format( - "PC Test ID: %s, Run ID: %s, Test Set ID: %s", - testId, - runId, - testSetId); - } else { - Throwable failure = response.getFailure(); - logger.log(String.format( - "Failed to get Entity name. Exception: %s", - failure == null ? "null" : failure.getMessage())); - } - } catch (Throwable e) { - logger.log("Failed to get Entity name"); - } - - return ret; - } - - @Override - protected GetRequest getRunEntityTestSetRunsRequest(Client client, String runId) { - - return new GetPCRunEntityTestSetRunsRequest(client, runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/Publisher.java b/src/main/java/com/hp/application/automation/tools/sse/result/Publisher.java deleted file mode 100644 index 18221a7f80..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/Publisher.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.hp.application.automation.tools.sse.result; - -import java.util.List; -import java.util.Map; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.handler.Handler; -import com.hp.application.automation.tools.sse.sdk.request.GetRequest; -import com.hp.application.automation.tools.sse.sdk.request.GetRunEntityNameRequest; - -public abstract class Publisher extends Handler { - - public Publisher(Client client, String entityId, String runId) { - - super(client, entityId, runId); - } - - public Testsuites publish( - String nameSuffix, - String url, - String domain, - String project, - Logger logger) { - - Testsuites ret = null; - GetRequest testSetRunsRequest = getRunEntityTestSetRunsRequest(_client, _runId); - Response response = testSetRunsRequest.execute(); - List> testInstanceRun = getTestInstanceRun(response, logger); - String entityName = getEntityName(nameSuffix, logger); - if (testInstanceRun != null) { - ret = - new JUnitParser().toModel( - testInstanceRun, - entityName, - _runId, - url, - domain, - project); - } - - return ret; - } - - protected Response getEntityName(String nameSuffix) { - - return new GetRunEntityNameRequest(_client, nameSuffix, _entityId).execute(); - } - - protected List> getTestInstanceRun(Response response, Logger logger) { - - List> ret = null; - try { - if (!StringUtils.isNullOrEmpty(response.toString())) { - ret = XPathUtils.toEntities(response.toString()); - } - } catch (Throwable cause) { - logger.log(String.format( - "Failed to parse TestInstanceRuns response XML. Exception: %s, XML: %s", - cause.getMessage(), - response.toString())); - } - - return ret; - } - - protected abstract GetRequest getRunEntityTestSetRunsRequest(Client client, String runId); - - protected abstract String getEntityName(String nameSuffix, Logger logger); -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/PublisherFactory.java b/src/main/java/com/hp/application/automation/tools/sse/result/PublisherFactory.java deleted file mode 100644 index 59c793caf3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/PublisherFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hp.application.automation.tools.sse.result; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.sse.sdk.Client; - -public class PublisherFactory { - - public Publisher create(Client client, String runType, String entityId, String runId) { - - Publisher ret = null; - if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { - ret = new LabPublisher(client, entityId, runId); - } else if (SseModel.PC.equals(runType)) { - ret = new PCPublisher(client, entityId, runId); - } else { - throw new SSEException("PublisherFactory: Unrecognized run type"); - } - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Error.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Error.java deleted file mode 100644 index 74a2094164..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Error.java +++ /dev/null @@ -1,112 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "content" }) -@XmlRootElement(name = "error") -public class Error { - - @XmlValue - protected String content; - @XmlAttribute - protected String type; - @XmlAttribute - protected String message; - - /** - * Gets the value of the content property. - * - * @return possible object is {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return possible object is {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return possible object is {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Failure.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Failure.java deleted file mode 100644 index ba490a8dec..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Failure.java +++ /dev/null @@ -1,112 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "content" }) -@XmlRootElement(name = "failure") -public class Failure { - - @XmlValue - protected String content; - @XmlAttribute - protected String type; - @XmlAttribute - protected String message; - - /** - * Gets the value of the content property. - * - * @return possible object is {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return possible object is {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the message property. - * - * @return possible object is {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java deleted file mode 100644 index 4c323881e7..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hp.application.automation.tools.sse.result.model.junit; - -/** - * - * @author Amir Zahavi - * - */ -public interface JUnitTestCaseStatus { - - String ERROR = "error"; - String PASS = "pass"; - String FAILURE = "failure"; -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Properties.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Properties.java deleted file mode 100644 index c0eff13719..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Properties.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}property" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "property" }) -@XmlRootElement(name = "properties") -public class Properties { - - @XmlElement(required = true) - protected List property; - - /** - * Gets the value of the property property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the property property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getProperty().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link Property } - * - * - */ - public List getProperty() { - if (property == null) { - property = new ArrayList(); - } - return this.property; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Property.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Property.java deleted file mode 100644 index ea9df9b6eb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Property.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "property") -public class Property { - - @XmlAttribute(required = true) - protected String name; - @XmlAttribute(required = true) - protected String value; - - /** - * Gets the value of the name property. - * - * @return possible object is {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the value property. - * - * @return possible object is {@link String } - * - */ - public String getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setValue(String value) { - this.value = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testcase.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testcase.java deleted file mode 100644 index c777b9acdb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testcase.java +++ /dev/null @@ -1,359 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}skipped" minOccurs="0"/>
- *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="report" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "skipped", "error", "failure", "systemOut", "systemErr" }) -@XmlRootElement(name = "testcase") -public class Testcase { - - protected String skipped; - protected List error; - protected List failure; - @XmlElement(name = "system-out") - protected List systemOut; - @XmlElement(name = "system-err") - protected List systemErr; - @XmlAttribute(required = true) - protected String name; - @XmlAttribute - protected String assertions; - @XmlAttribute - protected String time; - @XmlAttribute - protected String classname; - @XmlAttribute - protected String status; - @XmlAttribute - protected String type; - @XmlAttribute - protected String report; - - /** - * Gets the value of the skipped property. - * - * @return possible object is {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the error property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the error property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getError().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link Error } - * - * - */ - public List getError() { - if (error == null) { - error = new ArrayList(); - } - return this.error; - } - - /** - * Gets the value of the failure property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the failure property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getFailure().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link Failure } - * - * - */ - public List getFailure() { - if (failure == null) { - failure = new ArrayList(); - } - return this.failure; - } - - /** - * Gets the value of the systemOut property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the systemOut property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getSystemOut().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link String } - * - * - */ - public List getSystemOut() { - if (systemOut == null) { - systemOut = new ArrayList(); - } - return this.systemOut; - } - - /** - * Gets the value of the systemErr property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the systemErr property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getSystemErr().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link String } - * - * - */ - public List getSystemErr() { - if (systemErr == null) { - systemErr = new ArrayList(); - } - return this.systemErr; - } - - /** - * Gets the value of the name property. - * - * @return possible object is {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the assertions property. - * - * @return possible object is {@link String } - * - */ - public String getAssertions() { - return assertions; - } - - /** - * Sets the value of the assertions property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setAssertions(String value) { - this.assertions = value; - } - - /** - * Gets the value of the time property. - * - * @return possible object is {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the classname property. - * - * @return possible object is {@link String } - * - */ - public String getClassname() { - return classname; - } - - /** - * Sets the value of the classname property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setClassname(String value) { - this.classname = value; - } - - /** - * Gets the value of the status property. - * - * @return possible object is {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - - /** - * Gets the value of the type property. - * - * @return possible object is {@link String } - * - */ - public String getType() { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setType(String value) { - this.type = value; - } - - /** - * Gets the value of the report property. - * - * @return possible object is {@link String } - * - */ - public String getReport() { - return report; - } - - /** - * Sets the value of the report property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setReport(String value) { - this.report = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuite.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuite.java deleted file mode 100644 index 2e5316ff63..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuite.java +++ /dev/null @@ -1,411 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}properties" minOccurs="0"/>
- *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
- *         <element ref="{}system-out" minOccurs="0"/>
- *         <element ref="{}system-err" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "properties", "testcase", "systemOut", "systemErr" }) -@XmlRootElement(name = "testsuite") -public class Testsuite { - - protected Properties properties; - protected List testcase; - @XmlElement(name = "system-out") - protected String systemOut; - @XmlElement(name = "system-err") - protected String systemErr; - @XmlAttribute(required = true) - protected String name; - @XmlAttribute(required = true) - protected String tests; - @XmlAttribute - protected String failures; - @XmlAttribute - protected String errors; - @XmlAttribute - protected String time; - @XmlAttribute - protected String disabled; - @XmlAttribute - protected String skipped; - @XmlAttribute - protected String timestamp; - @XmlAttribute - protected String hostname; - @XmlAttribute - protected String id; - @XmlAttribute(name = "package") - protected String _package; - - /** - * Gets the value of the properties property. - * - * @return possible object is {@link Properties } - * - */ - public Properties getProperties() { - return properties; - } - - /** - * Sets the value of the properties property. - * - * @param value - * allowed object is {@link Properties } - * - */ - public void setProperties(Properties value) { - this.properties = value; - } - - /** - * Gets the value of the testcase property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the testcase property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getTestcase().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link Testcase } - * - * - */ - public List getTestcase() { - if (testcase == null) { - testcase = new ArrayList(); - } - return this.testcase; - } - - /** - * Gets the value of the systemOut property. - * - * @return possible object is {@link String } - * - */ - public String getSystemOut() { - return systemOut; - } - - /** - * Sets the value of the systemOut property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setSystemOut(String value) { - this.systemOut = value; - } - - /** - * Gets the value of the systemErr property. - * - * @return possible object is {@link String } - * - */ - public String getSystemErr() { - return systemErr; - } - - /** - * Sets the value of the systemErr property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setSystemErr(String value) { - this.systemErr = value; - } - - /** - * Gets the value of the name property. - * - * @return possible object is {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the tests property. - * - * @return possible object is {@link String } - * - */ - public String getTests() { - return tests; - } - - /** - * Sets the value of the tests property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTests(String value) { - this.tests = value; - } - - /** - * Gets the value of the failures property. - * - * @return possible object is {@link String } - * - */ - public String getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setFailures(String value) { - this.failures = value; - } - - /** - * Gets the value of the errors property. - * - * @return possible object is {@link String } - * - */ - public String getErrors() { - return errors; - } - - /** - * Sets the value of the errors property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setErrors(String value) { - this.errors = value; - } - - /** - * Gets the value of the time property. - * - * @return possible object is {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the disabled property. - * - * @return possible object is {@link String } - * - */ - public String getDisabled() { - return disabled; - } - - /** - * Sets the value of the disabled property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setDisabled(String value) { - this.disabled = value; - } - - /** - * Gets the value of the skipped property. - * - * @return possible object is {@link String } - * - */ - public String getSkipped() { - return skipped; - } - - /** - * Sets the value of the skipped property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setSkipped(String value) { - this.skipped = value; - } - - /** - * Gets the value of the timestamp property. - * - * @return possible object is {@link String } - * - */ - public String getTimestamp() { - return timestamp; - } - - /** - * Sets the value of the timestamp property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTimestamp(String value) { - this.timestamp = value; - } - - /** - * Gets the value of the hostname property. - * - * @return possible object is {@link String } - * - */ - public String getHostname() { - return hostname; - } - - /** - * Sets the value of the hostname property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setHostname(String value) { - this.hostname = value; - } - - /** - * Gets the value of the id property. - * - * @return possible object is {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the package property. - * - * @return possible object is {@link String } - * - */ - public String getPackage() { - return _package; - } - - /** - * Sets the value of the package property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setPackage(String value) { - this._package = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuites.java b/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuites.java deleted file mode 100644 index de0f7a51c5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/result/model/junit/Testsuites.java +++ /dev/null @@ -1,219 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.01.09 at 04:58:42 PM IST -// - -package com.hp.application.automation.tools.sse.result.model.junit; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

- * Java class for anonymous complex type. - * - *

- * The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}testsuite" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="tests" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { "testsuite" }) -@XmlRootElement(name = "testsuites") -public class Testsuites { - - protected List testsuite; - @XmlAttribute - protected String name; - @XmlAttribute - protected String time; - @XmlAttribute - protected String tests; - @XmlAttribute - protected String failures; - @XmlAttribute - protected String disabled; - @XmlAttribute - protected String errors; - - /** - * Gets the value of the testsuite property. - * - *

- * This accessor method returns a reference to the live list, not a snapshot. Therefore any - * modification you make to the returned list will be present inside the JAXB object. This is - * why there is not a set method for the testsuite property. - * - *

- * For example, to add a new item, do as follows: - * - *

-     * getTestsuite().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list {@link Testsuite } - * - * - */ - public List getTestsuite() { - if (testsuite == null) { - testsuite = new ArrayList(); - } - return this.testsuite; - } - - /** - * Gets the value of the name property. - * - * @return possible object is {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the time property. - * - * @return possible object is {@link String } - * - */ - public String getTime() { - return time; - } - - /** - * Sets the value of the time property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTime(String value) { - this.time = value; - } - - /** - * Gets the value of the tests property. - * - * @return possible object is {@link String } - * - */ - public String getTests() { - return tests; - } - - /** - * Sets the value of the tests property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setTests(String value) { - this.tests = value; - } - - /** - * Gets the value of the failures property. - * - * @return possible object is {@link String } - * - */ - public String getFailures() { - return failures; - } - - /** - * Sets the value of the failures property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setFailures(String value) { - this.failures = value; - } - - /** - * Gets the value of the disabled property. - * - * @return possible object is {@link String } - * - */ - public String getDisabled() { - return disabled; - } - - /** - * Sets the value of the disabled property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setDisabled(String value) { - this.disabled = value; - } - - /** - * Gets the value of the errors property. - * - * @return possible object is {@link String } - * - */ - public String getErrors() { - return errors; - } - - /** - * Sets the value of the errors property. - * - * @param value - * allowed object is {@link String } - * - */ - public void setErrors(String value) { - this.errors = value; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java deleted file mode 100644 index 22dcd59e65..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.common.ALMRESTVersionUtils; -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.ALMVersion; -import com.hp.application.automation.tools.sse.sdk.request.GetALMVersionRequest; - -/** - * @author Effi Bar-She'an - */ -public class ALMRunReportUrlBuilder { - - public String build(Client client, String serverUrl, String domain, String project, String runId) { - - String ret = "NA"; - try { - if (isNewReport(client)) { - ret = String.format("%sui/?redirected&p=%s/%s&execution-report#/test-set-report/%s", - serverUrl, - domain, - project, - runId); - } else { - ret = client.buildWebUIRequest(String.format("lab/index.jsp?processRunId=%s", runId)); - } - } catch (Exception e) { - // result url will be NA (in case of failure like getting ALM version, convert ALM version to number) - } - - return ret; - } - - public boolean isNewReport(Client client) { - - ALMVersion version = getALMVersion(client); - - return toInt(version.getMajorVersion()) >= 12 && toInt(version.getMinorVersion()) >= 2; - } - - private int toInt(String str) { - - return Integer.parseInt(str); - } - - private ALMVersion getALMVersion(Client client) { - - ALMVersion ret = null; - Response response = new GetALMVersionRequest(client).execute(); - if(response.isOk()) { - ret = ALMRESTVersionUtils.toModel(response.getData()); - } else { - throw new SSEException( - String.format("Failed to get ALM version. HTTP status code: %d", response.getStatusCode()), - response.getFailure()); - } - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/Args.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/Args.java deleted file mode 100644 index 20a25db9e5..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/Args.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.model.CdaDetails; - -/** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class Args { - - private final String _url; - private final String _domain; - private final String _project; - private final String _username; - private final String _password; - private final String _runType; - private final String _entityId; - private final String _duration; - private final String _description; - private final String _postRunAction; - private final String _environmentConfigurationId; - - private final CdaDetails _cdaDetails; - - public Args( - String url, - String domain, - String project, - String username, - String password, - String runType, - String entityId, - String duration, - String description, - String postRunAction, - String environmentConfigurationId, - CdaDetails cdaDetails) { - - _url = url; - _domain = domain; - _project = project; - _username = username; - _password = password; - _entityId = entityId; - _runType = runType; - _duration = duration; - _description = description; - _postRunAction = postRunAction; - _environmentConfigurationId = environmentConfigurationId; - _cdaDetails = cdaDetails; - } - - public String getUrl() { - - return _url; - } - - public String getDomain() { - - return _domain; - } - - public String getProject() { - - return _project; - } - - public String getUsername() { - - return _username; - } - - public String getPassword() { - - return _password; - } - - public String getEntityId() { - - return _entityId; - } - - public String getRunType() { - return _runType; - } - - public String getDuration() { - - return _duration; - } - - public String getDescription() { - - return _description; - } - - public String getPostRunAction() { - - return _postRunAction; - } - - public String getEnvironmentConfigurationId() { - - return _environmentConfigurationId; - } - - public CdaDetails getCdaDetails() { - - return _cdaDetails; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/Base64Encoder.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/Base64Encoder.java deleted file mode 100644 index be8b820606..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/Base64Encoder.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class Base64Encoder { - - private final static char[] ALPHABET = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); - private static int[] _toInt = new int[128]; - - static { - for (int i = 0; i < ALPHABET.length; i++) { - _toInt[ALPHABET[i]] = i; - } - } - - /** - * Translates the specified byte array into Base64 string. - * - * @param buf - * the byte array (not null) - * @return the translated Base64 string (not null) - */ - public static String encode(byte[] buf) { - - int size = buf.length; - char[] ar = new char[((size + 2) / 3) * 4]; - int a = 0; - int i = 0; - while (i < size) { - byte b0 = buf[i++]; - byte b1 = (i < size) ? buf[i++] : 0; - byte b2 = (i < size) ? buf[i++] : 0; - - int mask = 0x3F; - ar[a++] = ALPHABET[(b0 >> 2) & mask]; - ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask]; - ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask]; - ar[a++] = ALPHABET[b2 & mask]; - } - switch (size % 3) { - case 1: - ar[--a] = '='; - case 2: - ar[--a] = '='; - break; - } - - return new String(ar); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/Client.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/Client.java deleted file mode 100644 index 36d5281c7b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/Client.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import java.util.Map; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public interface Client { - - Response httpGet( - String url, - String queryString, - Map headers, - ResourceAccessLevel resourceAccessLevel); - - Response httpPost( - String url, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel); - - Response httpPut( - String url, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel); - - String build(String suffix); - - String buildRestRequest(String suffix); - - String buildWebUIRequest(String suffix); - - String getServerUrl(); - - String getUsername(); -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/ConsoleLogger.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/ConsoleLogger.java deleted file mode 100644 index 39ca4534f4..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/ConsoleLogger.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -/** - * - * @author Amir Zahavi - * - */ -public class ConsoleLogger implements Logger { - - @Override - public void log(String message) { - - System.out.println(message); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/HttpRequestDecorator.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/HttpRequestDecorator.java deleted file mode 100644 index 39a09657ec..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/HttpRequestDecorator.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Map; - -import com.hp.application.automation.tools.common.SSEException; - -public class HttpRequestDecorator { - - /** - * - * @param headers - * headrs to decorate with user info depending on the resource access level. - * @param userName - * @param resourceAccessLevel - */ - public static void decorateHeaderWithUserInfo( - final Map headers, - String userName, - ResourceAccessLevel resourceAccessLevel) { - - if (headers == null) { - throw new IllegalArgumentException("header must not be null"); - } - //attach encrypted user name for protected and public resources - if (resourceAccessLevel.equals(ResourceAccessLevel.PROTECTED) - || resourceAccessLevel.equals(ResourceAccessLevel.PRIVATE)) { - String userHeaderName = resourceAccessLevel.getUserHeaderName(); - String encryptedUserName = getDigestString("MD5", userName); - if (userHeaderName != null) { - headers.put(userHeaderName, encryptedUserName); - } - } - } - - private static String getDigestString(String algorithmName, String dataToDigest) { - - try { - MessageDigest md = MessageDigest.getInstance(algorithmName); - byte[] digested = md.digest(dataToDigest.getBytes()); - - return digestToString(digested); - } catch (NoSuchAlgorithmException ex) { - throw new SSEException(ex); - } - } - - /** - * This method convert byte array to string regardless the charset - * - * @param b - * byte array input - * @return the corresponding string - */ - private static String digestToString(byte[] b) { - - StringBuilder result = new StringBuilder(128); - for (byte aB : b) { - result.append(Integer.toString((aB & 0xff) + 0x100, 16).substring(1)); - } - - return result.toString(); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/Logger.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/Logger.java deleted file mode 100644 index a10f66a4ee..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/Logger.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public interface Logger { - - public void log(String message); -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/PCRunResponse.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/PCRunResponse.java deleted file mode 100644 index 5bdc12ea22..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/PCRunResponse.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.sse.common.StringUtils; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class PCRunResponse extends RunResponse { - - @Override - protected String parseRunId(String runIdResponse) { - String ret = runIdResponse; - if (!StringUtils.isNullOrEmpty(ret)) { - String runIdStr = "qcRunID="; - if (ret.contains(runIdStr)) { - ret = ret.substring(ret.indexOf(runIdStr) + runIdStr.length(), ret.length()); - } - } - return ret; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/ResourceAccessLevel.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/ResourceAccessLevel.java deleted file mode 100644 index 246f1a4795..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/ResourceAccessLevel.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.rest.RESTConstants; - -public enum ResourceAccessLevel { - PUBLIC(null), PROTECTED(RESTConstants.PtaL), PRIVATE(RESTConstants.PvaL); - - private String _headerName; - - private ResourceAccessLevel(String headerName) { - - _headerName = headerName; - } - - public String getUserHeaderName() { - - return _headerName; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/Response.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/Response.java deleted file mode 100644 index c5961e23ff..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/Response.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import java.net.HttpURLConnection; -import java.util.List; -import java.util.Map; - -/** - * This is a naive implementation of an HTTP response. We use it to simplify matters in the - * examples. It is nothing more than a container of the response headers and the response body. - */ -public class Response { - - private Map> _headers; - private byte[] _data; - private Throwable _failure; - private int _statusCode = -1; - - public Response() { - - this(null, null, null, -1); - } - - public Response(Exception failure) { - - this(null, null, failure, -1); - } - - public Response( - Map> headers, - byte[] data, - Exception failure, - int statusCode) { - - _headers = headers; - _data = data; - _failure = failure; - _statusCode = statusCode; - } - - public Map> getHeaders() { - - return _headers; - } - - public void setHeaders(Map> responseHeaders) { - - _headers = responseHeaders; - } - - public byte[] getData() { - - return _data; - } - - public void setData(byte[] data) { - - _data = data; - } - - /** - * @return the failure if the access to the requested URL failed, such as a 404 or 500. If no - * such failure occurred this method returns null. - */ - public Throwable getFailure() { - - return _failure; - } - - public void setFailure(Throwable cause) { - - this._failure = cause; - } - - public int getStatusCode() { - - return _statusCode; - } - - public void setStatusCode(int statusCode) { - - _statusCode = statusCode; - } - - public boolean isOk() { - - return getFailure() == null - && (getStatusCode() == HttpURLConnection.HTTP_OK - || getStatusCode() == HttpURLConnection.HTTP_CREATED || getStatusCode() == HttpURLConnection.HTTP_ACCEPTED); - } - - /** - * @see Object#toString() return the contents of the byte[] data as a string. - */ - @Override - public String toString() { - - return new String(_data); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/RestAuthenticator.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/RestAuthenticator.java deleted file mode 100644 index fc6b0fff5a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/RestAuthenticator.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import java.net.HttpURLConnection; -import java.util.HashMap; -import java.util.Map; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.rest.RestClient; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class RestAuthenticator { - - public static final String IS_AUTHENTICATED = "rest/is-authenticated"; - public static String AUTHENTICATE_HEADER = "WWW-Authenticate"; - public static String INVALID_ALM_SERVER_URL = "Invalid ALM Server URL"; - public static String AUTHENTICATEION_INFO = "AuthenticationInfo"; - public static String USER_NAME = "Username"; - - public boolean login(Client client, String username, String password, Logger logger) { - - boolean ret = true; - String authenticationPoint = isAuthenticated(client, logger); - if (authenticationPoint != null) { - Response response = login(client, authenticationPoint, username, password); - if (response.isOk()) { - logLoggedInSuccessfully(username, client.getServerUrl(), logger); - } else { - logger.log(String.format( - "Login to ALM Server at %s failed. Status Code: %s", - client.getServerUrl(), - response.getStatusCode())); - ret = false; - } - } - - return ret; - } - - /** - * @param loginUrl - * to authenticate at - * @return true on operation success, false otherwise Basic authentication (must store returned - * cookies for further use) - */ - private Response login(Client client, String loginUrl, String username, String password) { - - // create a string that looks like: - // "Basic ((username:password))<64encoded>" - byte[] credBytes = (username + ":" + password).getBytes(); - String credEncodedString = "Basic " + Base64Encoder.encode(credBytes); - Map headers = new HashMap(); - headers.put(RESTConstants.AUTHORIZATION, credEncodedString); - - return client.httpGet(loginUrl, null, headers, ResourceAccessLevel.PUBLIC); - } - - /** - * @return true if logout successful - * @throws Exception - * close session on server and clean session cookies on client - */ - public boolean logout(RestClient client, String username) { - - // note the get operation logs us out by setting authentication cookies to: - // LWSSO_COOKIE_KEY="" via server response header Set-Cookie - Response response = - client.httpGet( - client.build("authentication-point/logout"), - null, - null, - ResourceAccessLevel.PUBLIC); - - return response.isOk(); - - } - - /** - * @return null if authenticated.
- * a URL to authenticate against if not authenticated. - * @throws Exception - * if error such as 404, or 500 - */ - public String isAuthenticated(Client client, Logger logger) { - - String ret; - Response response = - client.httpGet( - client.build(IS_AUTHENTICATED), - null, - null, - ResourceAccessLevel.PUBLIC); - int responseCode = response.getStatusCode(); - - // already authenticated - if (isAlreadyAuthenticated(response, client.getUsername())) { - ret = null; - logLoggedInSuccessfully(client.getUsername(), client.getServerUrl(), logger); - } - // if not authenticated - get the address where to authenticate via WWW-Authenticate - else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { - String newUrl = response.getHeaders().get(AUTHENTICATE_HEADER).get(0).split("=")[1]; - newUrl = newUrl.replace("\"", ""); - newUrl += "/authenticate"; - ret = newUrl; - } - // error such as 404, or 500 - else { - try { - throw response.getFailure(); - } catch (Throwable cause) { - throw new SSEException(cause); - } - } - - return ret; - } - - private boolean isAlreadyAuthenticated(Response response, String authUser) { - boolean ret = false; - - if (response.getStatusCode() == HttpURLConnection.HTTP_OK){ - - if (response.getData() != null && containAuthenticatedInfo(new String(response.getData()), authUser)){ - ret = true; - } - else{ - throw new SSEException(INVALID_ALM_SERVER_URL); - } - } - - return ret; - } - - //if it's authenticated, the response should look like that: - //sa - private boolean containAuthenticatedInfo(String authInfo, String authUser){ - - return authInfo.contains(AUTHENTICATEION_INFO) && authInfo.contains(USER_NAME) && authInfo.contains(authUser); - } - - - private void logLoggedInSuccessfully(String username, String loginServerUrl, Logger logger) { - - logger.log(String.format( - "Logged in successfully to ALM Server %s using %s", - loginServerUrl, - username)); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/RunManager.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/RunManager.java deleted file mode 100644 index 9367141bfb..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/RunManager.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.result.PublisherFactory; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; -import com.hp.application.automation.tools.sse.sdk.handler.PollHandler; -import com.hp.application.automation.tools.sse.sdk.handler.PollHandlerFactory; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; - -/** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class RunManager { - - private RunHandler _runHandler; - private PollHandler _pollHandler; - private Logger _logger; - private boolean _running = false; - private boolean _polling = false; - - public Testsuites execute(RestClient client, Args args, Logger logger) - throws InterruptedException { - - Testsuites ret = null; - _logger = logger; - _running = true; - if (login(client, args)) { - initialize(args, client); - if (start(args)) { - _polling = true; - if (poll()) { - ret = - new PublisherFactory().create( - client, - args.getRunType(), - args.getEntityId(), - _runHandler.getRunId()).publish( - _runHandler.getNameSuffix(), - args.getUrl(), - args.getDomain(), - args.getProject(), - logger); - } - _polling = false; - } - } - - return ret; - } - - private void initialize(Args args, RestClient client) { - - String entityId = args.getEntityId(); - appendQCSessionCookies(client); - _runHandler = new RunHandlerFactory().create(client, args.getRunType(), entityId); - _pollHandler = new PollHandlerFactory().create(client, args.getRunType(), entityId); - } - - private void appendQCSessionCookies(RestClient client) { - - // issue a post request so that cookies relevant to the QC Session will be added to the RestClient - Response response = - client.httpPost( - client.build("rest/site-session"), - null, - null, - ResourceAccessLevel.PUBLIC); - if (!response.isOk()) { - throw new SSEException("Cannot appned QCSession cookies", response.getFailure()); - } - } - - private boolean poll() throws InterruptedException { - - return _pollHandler.poll(_logger); - } - - public void stop() { - - _logger.log("Stopping run..."); - if (_runHandler != null) { - _runHandler.stop(); - _running = false; - } - if (_pollHandler != null) { - _polling = false; - } - } - - private boolean login(Client client, Args args) { - - boolean ret = true; - try { - ret = - new RestAuthenticator().login( - client, - args.getUsername(), - args.getPassword(), - _logger); - } catch (Throwable cause) { - ret = false; - _logger.log(String.format( - "Failed login to ALM Server URL: %s. Exception: %s", - args.getUrl(), - cause.getMessage())); - } - - return ret; - } - - private boolean start(Args args) { - - boolean ret = false; - Response response = - _runHandler.start( - args.getDuration(), - args.getPostRunAction(), - args.getEnvironmentConfigurationId(), - args.getCdaDetails()); - if (isOk(response, args)) { - RunResponse runResponse = getRunResponse(response); - setRunId(runResponse); - if (runResponse.isSucceeded()) { - ret = true; - } - } - logReportUrl(ret, args); - - return ret; - } - - private void setRunId(RunResponse runResponse) { - - String runId = runResponse.getRunId(); - if (StringUtils.isNullOrEmpty(runId)) { - _logger.log("No run ID"); - throw new SSEException("No run ID"); - } else { - _runHandler.setRunId(runId); - _pollHandler.setRunId(runId); - } - } - - private void logReportUrl(boolean isSucceeded, Args args) { - - if (isSucceeded) { - _logger.log(String.format( - "%s run report for run id %s is at: %s", - args.getRunType(), - _runHandler.getRunId(), - _runHandler.getReportUrl(args))); - } else { - _logger.log(String.format( - "Failed to start %s ID:%s, run id: %s " - + "\nNote: You can run only functional test sets and build verification suites using this plugin. " - + "Check to make sure that the configured ID is valid " - + "(and that it is not a performance test ID).", - args.getRunType(), - args.getEntityId(), - _runHandler.getRunId())); - } - } - - private RunResponse getRunResponse(Response response) { - - return _runHandler.getRunResponse(response); - } - - private boolean isOk(Response response, Args args) { - - boolean ret = false; - if (response.isOk()) { - _logger.log(String.format( - "Executing %s ID: %s in %s/%s %sDescription: %s", - args.getRunType(), - args.getEntityId(), - args.getDomain(), - args.getProject(), - StringUtils.NEW_LINE, - args.getDescription())); - ret = true; - } else { - Throwable cause = response.getFailure(); - if (cause != null) { - _logger.log(String.format( - "Failed to start %s ID: %s, ALM Server URL: %s (Exception: %s)", - args.getRunType(), - args.getEntityId(), - args.getUrl(), - cause.getMessage())); - } else { - _logger.log(String.format( - "Failed to execute %s ID: %s, ALM Server URL: %s (Response: %s)", - args.getRunType(), - args.getEntityId(), - args.getUrl(), - response.getStatusCode())); - } - } - - return ret; - } - - public boolean getRunning() { - - return _running; - } - - public boolean getPolling() { - - return _polling; - } - -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/RunResponse.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/RunResponse.java deleted file mode 100644 index 8f560ddd33..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/RunResponse.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class RunResponse { - - private String _successStatus; - private String _runId; - - public void initialize(Response response) { - - String xml = response.toString(); - _successStatus = XPathUtils.getAttributeValue(xml, "SuccessStaus"); - _runId = parseRunId(XPathUtils.getAttributeValue(xml, "info")); - } - - protected String parseRunId(String runIdResponse) { - - String ret = runIdResponse; - if (StringUtils.isNullOrEmpty(ret)) { - ret = "No Run ID"; - } - - return ret; - } - - public String getRunId() { - - return _runId; - } - - public boolean isSucceeded() { - - return "1".equals(_successStatus); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/BvsRunHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/BvsRunHandler.java deleted file mode 100644 index 13d493b6ea..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/BvsRunHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class BvsRunHandler extends RunHandler { - - public BvsRunHandler(Client client, String entityId) { - - super(client, entityId); - } - - @Override - protected String getStartSuffix() { - - return String.format("procedures/%s/startrunprocedure", _entityId); - } - - @Override - public String getNameSuffix() { - - return String.format("procedures/%s", getEntityId()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/EventLogHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/EventLogHandler.java deleted file mode 100644 index 6437ca1ec0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/EventLogHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import java.util.List; -import java.util.Map; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.request.EventLogRequest; - -public class EventLogHandler extends Handler { - - private String _timeslotId = StringUtils.EMPTY_STRING; - private int _lastRead = -1; - - public EventLogHandler(Client client, String timeslotId) { - - super(client, timeslotId); - _timeslotId = timeslotId; - } - - public boolean log(Logger logger) { - - boolean ret = false; - Response eventLog = null; - try { - eventLog = getEventLog(); - String xml = eventLog.toString(); - List> entities = XPathUtils.toEntities(xml); - for (Map currEntity : entities) { - if (isNew(currEntity)) { - logger.log(String.format( - "%s:%s", - currEntity.get("creation-time"), - currEntity.get("description"))); - } - } - ret = true; - } catch (Throwable cause) { - logger.log(String.format( - "Failed to print Event Log: %s (run id: %s, reservation id: %s). Cause: %s", - eventLog, - _runId, - _timeslotId, - cause)); - } - - return ret; - } - - private boolean isNew(Map currEntity) { - - boolean ret = false; - int currEvent = Integer.parseInt(currEntity.get("id")); - if (currEvent > _lastRead) { - _lastRead = currEvent; - ret = true; - } - - return ret; - } - - private Response getEventLog() { - - return new EventLogRequest(_client, _timeslotId).execute(); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/Handler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/Handler.java deleted file mode 100644 index 83b3a511b8..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/Handler.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.sdk.Client; - -public abstract class Handler { - - protected final Client _client; - protected final String _entityId; - protected String _runId = StringUtils.EMPTY_STRING; - protected String _timeslotId = StringUtils.EMPTY_STRING; - - public Handler(Client client, String entityId) { - - _client = client; - _entityId = entityId; - } - - public Handler(Client client, String entityId, String runId) { - - this(client, entityId); - _runId = runId; - } - - public String getRunId() { - - return _runId; - } - - public String getEntityId() { - - return _entityId; - } - - public void setRunId(String runId) { - _runId = runId; - } - - public String getTimeslotId() { - - return _timeslotId; - } - - public void setTimeslotId(String timeslotId) { - - _timeslotId = timeslotId; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/LabPollHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/LabPollHandler.java deleted file mode 100644 index 4437fc7117..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/LabPollHandler.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.request.GetLabRunEntityDataRequest; -import com.hp.application.automation.tools.sse.sdk.request.PollSSERunRequest; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class LabPollHandler extends PollHandler { - - private EventLogHandler _eventLogHandler; - - public LabPollHandler(Client client, String entityId) { - - super(client, entityId); - } - - public LabPollHandler(Client client, String entityId, int interval) { - - super(client, entityId, interval); - } - - @Override - protected boolean doPoll(Logger logger) throws InterruptedException { - - boolean ret = false; - - Response runEntityResponse = getRunEntityData(); - if (isOk(runEntityResponse, logger)) { - setTimeslotId(runEntityResponse, logger); - _eventLogHandler = new EventLogHandler(_client, _timeslotId); - if (!StringUtils.isNullOrEmpty(_timeslotId)) { - ret = super.doPoll(logger); - } - } - return ret; - - } - - @Override - protected Response getResponse() { - - return new PollSSERunRequest(_client, _runId).execute(); - } - - @Override - protected void log(Logger logger) { - - _eventLogHandler.log(logger); - } - - @Override - protected boolean isFinished(Response response, Logger logger) { - - boolean ret = false; - try { - String xml = response.toString(); - String endTime = XPathUtils.getAttributeValue(xml, "end-time"); - if (!StringUtils.isNullOrEmpty(endTime)) { - String startTime = XPathUtils.getAttributeValue(xml, "start-time"); - String currentRunState = XPathUtils.getAttributeValue(xml, "state"); - logger.log(String.format( - "Timeslot %s is %s.\nRun start time: %s, Run end time: %s", - _timeslotId, - currentRunState, - startTime, - endTime)); - ret = true; - } - } catch (Throwable cause) { - logger.log(String.format("Failed to parse response: %s", response)); - ret = true; - } - - return ret; - } - - @Override - protected boolean logRunEntityResults(Response response, Logger logger) { - - boolean ret = false; - try { - String xml = response.toString(); - String state = XPathUtils.getAttributeValue(xml, "state"); - String completedSuccessfully = - XPathUtils.getAttributeValue(xml, "completed-successfully"); - logger.log(String.format( - "Run state of %s: %s, Completed successfully: %s", - _runId, - state, - completedSuccessfully)); - ret = true; - - } catch (Throwable cause) { - logger.log(String.format("Failed to parse response: %s", response)); - } - - return ret; - } - - private void setTimeslotId(Response runEntityResponse, Logger logger) { - - _timeslotId = getTimeslotId(runEntityResponse, logger); - if (!StringUtils.isNullOrEmpty(_timeslotId)) { - logger.log(String.format("Timeslot id: %s", _timeslotId)); - } - } - - private Response getRunEntityData() { - - return new GetLabRunEntityDataRequest(_client, _runId).execute(); - } - - private String getTimeslotId(Response response, Logger logger) { - - String ret = StringUtils.EMPTY_STRING; - try { - String xml = response.toString(); - ret = XPathUtils.getAttributeValue(xml, "reservation-id"); - } catch (Throwable cause) { - logger.log(String.format("Failed to parse response for timeslot ID: %s", response)); - } - - return ret; - } - - @Override - protected Response getRunEntityResultsResponse() { - return new GetLabRunEntityDataRequest(_client, _runId).execute(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCPollHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCPollHandler.java deleted file mode 100644 index 8e94e8f0cc..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCPollHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import java.util.Arrays; -import java.util.List; - -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.XPathUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.request.GetPCRunEntityDataRequest; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class PCPollHandler extends PollHandler { - - private final static List FINAL_STATES = Arrays.asList("N/A", "Failed", "Passed"); - - public PCPollHandler(Client client, String entityId) { - - super(client, entityId); - } - - public PCPollHandler(Client client, String entityId, int interval) { - - super(client, entityId, interval); - } - - @Override - protected Response getResponse() { - - return new GetPCRunEntityDataRequest(_client, _runId).execute(); - } - - @Override - protected boolean isFinished(Response response, Logger logger) { - - boolean ret = false; - try { - String xml = response.toString(); - String pcEndTime = XPathUtils.getAttributeValue(xml, "pc-end-time"); - String status = XPathUtils.getAttributeValue(xml, "status"); - if (!StringUtils.isNullOrEmpty(pcEndTime)) { - logger.log(String.format("PC test end time: %s", pcEndTime)); - ret = true; - } else if (!StringUtils.isNullOrEmpty(status)) { - if (FINAL_STATES.contains(status)) { - ret = true; - } - } - } catch (Throwable cause) { - logger.log(String.format("Failed to parse response: %s", response)); - ret = true; - } - - return ret; - } - - @Override - protected boolean logRunEntityResults(Response response, Logger logger) { - - boolean ret = false; - try { - String xml = response.toString(); - String status = XPathUtils.getAttributeValue(xml, "status"); - String state = XPathUtils.getAttributeValue(xml, "state"); - logger.log(String.format("Run status of %s: %s, State: %s", _runId, status, state)); - ret = true; - - } catch (Throwable cause) { - logger.log(String.format("Failed to parse response: %s", response)); - } - - return ret; - } - - @Override - protected Response getRunEntityResultsResponse() { - - return new GetPCRunEntityDataRequest(_client, _runId).execute(); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCRunHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCRunHandler.java deleted file mode 100644 index 6339ca651e..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PCRunHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import java.net.MalformedURLException; -import java.net.URL; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.sse.sdk.Args; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.PCRunResponse; -import com.hp.application.automation.tools.sse.sdk.Response; -import com.hp.application.automation.tools.sse.sdk.RunResponse; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class PCRunHandler extends RunHandler { - - public PCRunHandler(Client client, String entityId) { - - super(client, entityId); - } - - @Override - protected String getStartSuffix() { - - return String.format("test-instances/%s/startrun", _entityId); - } - - @Override - public String getNameSuffix() { - - return String.format("runs/%s", _runId); - } - - @Override - public String getReportUrl(Args args) { - - String ret = "No report URL available"; - try { - ret = - String.format( - "td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", - args.getProject(), - args.getDomain(), - new URL(args.getUrl()).getHost(), - _runId); - } catch (MalformedURLException ex) { - throw new SSEException(ex); - } - return ret; - } - - @Override - public RunResponse getRunResponse(Response response) { - - RunResponse ret = new PCRunResponse(); - ret.initialize(response); - - return ret; - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandler.java deleted file mode 100644 index 7757ab2212..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Logger; -import com.hp.application.automation.tools.sse.sdk.Response; - -public abstract class PollHandler extends Handler { - - private int _interval = 5000; // millisecond - - public PollHandler(Client client, String entityId) { - - super(client, entityId); - } - - public PollHandler(Client client, String entityId, int interval) { - - super(client, entityId); - _interval = interval; - } - - public PollHandler(Client client, String entityId, String runId) { - - super(client, entityId, runId); - } - - public boolean poll(Logger logger) throws InterruptedException { - - logger.log(String.format("Polling... Run ID: %s", _runId)); - - return doPoll(logger); - } - - protected boolean doPoll(Logger logger) throws InterruptedException { - - boolean ret = false; - int failures = 0; - while (failures < 3) { - Response response = getResponse(); - if (isOk(response, logger)) { - log(logger); - if (isFinished(response, logger)) { - ret = true; - logRunEntityResults(getRunEntityResultsResponse(), logger); - break; - } - } else { - ++failures; - } - if (sleep(logger)) { // interrupted - break; - } - } - - return ret; - } - - protected abstract Response getRunEntityResultsResponse(); - - protected abstract boolean logRunEntityResults(Response response, Logger logger); - - protected abstract boolean isFinished(Response response, Logger logger); - - protected abstract Response getResponse(); - - protected boolean isOk(Response response, Logger logger) { - - boolean ret = false; - if (!response.isOk()) { - Throwable cause = response.getFailure(); - logger.log(String.format( - "Polling try failed. Status code: %s, Exception: %s", - response.getStatusCode(), - cause != null ? cause.getMessage() : "Not Available")); - } else { - ret = true; - } - - return ret; - } - - protected boolean sleep(Logger logger) throws InterruptedException { - - boolean ret = false; - try { - Thread.sleep(_interval); - } catch (InterruptedException ex) { - logger.log("Interrupted while polling"); - throw ex; - } - - return ret; - } - - protected void log(Logger logger) {} -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java deleted file mode 100644 index e7dfdcb846..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.sse.sdk.Client; - -public class PollHandlerFactory { - - public PollHandler create(Client client, String runType, String entityId) { - - PollHandler ret = null; - if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { - ret = new LabPollHandler(client, entityId); - } else if (SseModel.PC.equals(runType)) { - ret = new PCPollHandler(client, entityId); - } else { - throw new SSEException("PollHandlerFactory: Unrecognized run type"); - } - - return ret; - } - - public PollHandler create(Client client, String runType, String entityId, int interval) { - - PollHandler ret = null; - if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { - ret = new LabPollHandler(client, entityId, interval); - } else if (SseModel.PC.equals(runType)) { - ret = new PCPollHandler(client, entityId, interval); - } else { - throw new SSEException("PollHandlerFactory: Unrecognized run type"); - } - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandler.java deleted file mode 100644 index 959d2de37d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.sse.sdk.*; -import com.hp.application.automation.tools.sse.sdk.request.StartRunEntityRequest; -import com.hp.application.automation.tools.sse.sdk.request.StopEntityRequest; - -public abstract class RunHandler extends Handler { - - protected abstract String getStartSuffix(); - - public abstract String getNameSuffix(); - - public RunHandler(Client client, String entityId) { - - super(client, entityId); - } - - public Response start( - String duration, - String postRunAction, - String environmentConfigurationId, - CdaDetails cdaDetails) { - - return new StartRunEntityRequest( - _client, - getStartSuffix(), - _entityId, - duration, - postRunAction, - environmentConfigurationId, - cdaDetails).execute(); - } - - public Response stop() { - - return new StopEntityRequest(_client, _runId).execute(); - } - - public String getReportUrl(Args args) { - - return new ALMRunReportUrlBuilder().build(_client, _client.getServerUrl(), args.getDomain(), args.getProject(), _runId); - } - - public RunResponse getRunResponse(Response response) { - - RunResponse ret = new RunResponse(); - ret.initialize(response); - - return ret; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java deleted file mode 100644 index c84fab83a0..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.sse.sdk.Client; - -public class RunHandlerFactory { - - public RunHandler create(Client client, String runType, String entityId) { - - RunHandler ret = null; - if (SseModel.BVS.equals(runType)) { - ret = new BvsRunHandler(client, entityId); - } else if (SseModel.TEST_SET.equals(runType)) { - ret = new TestSetRunHandler(client, entityId); - } else if (SseModel.PC.equals(runType)) { - ret = new PCRunHandler(client, entityId); - } else { - throw new SSEException("RunHandlerFactory: Unrecognized run type"); - } - - return ret; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java deleted file mode 100644 index 08d87e4e8d..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.handler; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class TestSetRunHandler extends RunHandler { - - public TestSetRunHandler(Client client, String entityId) { - - super(client, entityId); - } - - @Override - protected String getStartSuffix() { - - return String.format("test-sets/%s/startruntestset", _entityId); - } - - @Override - public String getNameSuffix() { - - return String.format("test-sets/%s", getEntityId()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java deleted file mode 100644 index 05650c1f55..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.sse.sdk.Client; - -import java.util.HashMap; -import java.util.Map; - -public class CreateSiteSessionRequest extends GeneralPostRequest { - - public CreateSiteSessionRequest(Client client) { - - super(client); - } - - @Override - protected String getUrl() { - - return _client.build("rest/site-session"); - } - - @Override - protected Map getHeaders() { - - Map ret = new HashMap(); - ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.TEXT_PLAIN); - - return ret; - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/EventLogRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/EventLogRequest.java deleted file mode 100644 index 0c891d2fa1..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/EventLogRequest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -public class EventLogRequest extends GetRequest { - - private final String _timeslotId; - - public EventLogRequest(Client client, String timeslotId) { - - super(client, timeslotId); - _timeslotId = timeslotId; - } - - @Override - protected String getSuffix() { - - return String.format( - "event-log-reads?query={context[\"*Timeslot:%%20%s%%3B*\"]}&fields=id,event-type,creation-time,action,description", - _timeslotId); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralGetRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralGetRequest.java deleted file mode 100644 index ed10ad9c70..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralGetRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; - -/** - * Created by barush on 29/10/2014. - */ -public abstract class GeneralGetRequest extends GeneralRequest { - - protected GeneralGetRequest(Client client) { - super(client); - } - - protected String getQueryString() { - - return null; - } - - @Override - public Response perform() { - - return _client.httpGet( - getUrl(), - getQueryString(), - getHeaders(), - ResourceAccessLevel.PROTECTED); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPostRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPostRequest.java deleted file mode 100644 index 5b4f8402b3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPostRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.common.Pair; -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.sse.common.RestXmlUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by barush on 29/10/2014. - */ -public abstract class GeneralPostRequest extends GeneralRequest { - - protected GeneralPostRequest(Client client) { - super(client); - } - - @Override - protected Map getHeaders() { - - Map ret = new HashMap(); - ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); - ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); - - return ret; - } - - @Override - public Response perform() { - - return _client.httpPost( - getUrl(), - getDataBytes(), - getHeaders(), - ResourceAccessLevel.PROTECTED); - } - - private byte[] getDataBytes() { - - StringBuilder builder = new StringBuilder(""); - for (Pair currPair : getDataFields()) { - builder.append(RestXmlUtils.fieldXml(currPair.getFirst(), currPair.getSecond())); - } - - return builder.append("").toString().getBytes(); - } - - protected List> getDataFields() { - - return new ArrayList>(0); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java deleted file mode 100644 index ecdc4a9997..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.sse.common.RestXmlUtils; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by barush on 03/11/2014. - */ -public abstract class GeneralPutBulkRequest extends GeneralRequest { - - protected GeneralPutBulkRequest(Client client) { - super(client); - } - - protected abstract List> getFields(); - - @Override - protected Map getHeaders() { - - Map ret = new HashMap(); - ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML_BULK); - ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); - - return ret; - } - - @Override - protected Response perform() { - return _client.httpPut( - getUrl(), - getDataBytes(), - getHeaders(), - ResourceAccessLevel.PROTECTED); - } - - private byte[] getDataBytes() { - - StringBuilder builder = new StringBuilder(""); - for (Map values : getFields()) { - builder.append(""); - for (String key : values.keySet()) { - builder.append(RestXmlUtils.fieldXml(key, values.get(key))); - } - builder.append(""); - } - - return builder.append("").toString().getBytes(); - - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralRequest.java deleted file mode 100644 index 385580d103..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GeneralRequest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.Response; - -import java.util.Map; - -/** - * Created by barush on 29/10/2014. - */ -public abstract class GeneralRequest { - - protected final Client _client; - - protected GeneralRequest(Client client) { - - _client = client; - } - - public final Response execute() { - - Response ret = new Response(); - try { - ret = perform(); - } catch (Throwable cause) { - ret.setFailure(cause); - } - - return ret; - } - - protected abstract Response perform(); - - protected String getSuffix() { - return null; - } - - protected Map getHeaders() { - - return null; - } - - protected String getBody() { - - return null; - } - - protected String getUrl() { - - return _client.buildRestRequest(getSuffix()); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java deleted file mode 100644 index fc5122b3a9..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.rest.RESTConstants; -import com.hp.application.automation.tools.sse.common.RestXmlUtils; -import com.hp.application.automation.tools.sse.sdk.Client; - -import java.util.Map; - -/** - * @author Effi Bar-She'an - */ -public class GetALMVersionRequest extends GetRequest { - - public GetALMVersionRequest(Client client) { - - super(client, null); - } - - @Override - protected String getSuffix() { - - return String.format("%s/sa/version", RESTConstants.REST_PROTOCOL); - } - - @Override - protected String getUrl() { - - return String.format("%s%s", _client.getServerUrl(), getSuffix()); - } - - @Override - protected Map getHeaders() { - - return RestXmlUtils.getAppXmlHeaders(); - } -} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java deleted file mode 100644 index 0b0debf37b..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class GetLabRunEntityDataRequest extends GetRequest { - - public GetLabRunEntityDataRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - - return String.format("procedure-runs/%s", _runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java deleted file mode 100644 index f5d10e4d88..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class GetLabRunEntityTestSetRunsRequest extends GetRequest { - - public GetLabRunEntityTestSetRunsRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - return "procedure-testset-instance-runs"; - } - - @Override - protected String getQueryString() { - - return String.format("query={procedure-run[%s]}&page-size=2000", _runId); - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java deleted file mode 100644 index 77403cb99a..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class GetPCRunEntityDataRequest extends GetRequest { - - public GetPCRunEntityDataRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - - return String.format("runs/%s", _runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java deleted file mode 100644 index 36ecfb3140..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class GetPCRunEntityTestSetRunsRequest extends GetRequest { - - public GetPCRunEntityTestSetRunsRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - - return String.format("runs/%s", _runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRequest.java deleted file mode 100644 index 6e9372d7d3..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRequest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public abstract class GetRequest extends GeneralGetRequest { - - protected final String _runId; - - protected GetRequest(Client client, String runId) { - - super(client); - _runId = runId; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java deleted file mode 100644 index 266d7b981c..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public class GetRunEntityNameRequest extends GetRequest { - - private final String _nameSuffix; - - public GetRunEntityNameRequest(Client client, String suffix, String entityId) { - - super(client, entityId); - _nameSuffix = suffix; - - } - - @Override - protected String getSuffix() { - - return _nameSuffix; - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PollSSERunRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PollSSERunRequest.java deleted file mode 100644 index 115b9c81c8..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PollSSERunRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class PollSSERunRequest extends GetRequest { - - private final String _runId; - - public PollSSERunRequest(Client client, String runId) { - - super(client, runId); - _runId = runId; - } - - @Override - protected String getSuffix() { - - return String.format("procedure-runs/%s", _runId); - } -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PostRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PostRequest.java deleted file mode 100644 index f8532af1db..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/PostRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ -public abstract class PostRequest extends GeneralPostRequest { - - protected final String _runId; - - protected PostRequest(Client client, String runId) { - - super(client); - _runId = runId; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java deleted file mode 100644 index 10e465eb57..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import java.util.ArrayList; -import java.util.List; - -import com.hp.application.automation.tools.common.Pair; -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class StartRunEntityRequest extends PostRequest { - - private final String _duration; - private final String _suffix; - private final String _environmentConfigurationId; - private final CdaDetails _cdaDetails; - - public StartRunEntityRequest( - Client client, - String suffix, - String runId, - String duration, - String postRunAction, - String environmentConfigurationId, - CdaDetails cdaDetails) { - - super(client, runId); - _duration = duration; - _suffix = suffix; - _environmentConfigurationId = environmentConfigurationId; - _cdaDetails = cdaDetails; - } - - @Override - protected List> getDataFields() { - - List> ret = new ArrayList>(); - ret.add(new Pair("duration", _duration)); - ret.add(new Pair("vudsMode", "false")); - ret.add(new Pair("reservationId", "-1")); - if (!StringUtils.isNullOrEmpty(_environmentConfigurationId)) { - ret.add(new Pair("valueSetId", _environmentConfigurationId)); - if (_cdaDetails != null) { - ret.add(new Pair("topologyAction", _cdaDetails.getTopologyAction())); - ret.add(new Pair( - "realizedTopologyName", - _cdaDetails.getDeployedEnvironmentName())); - - } - } - - return ret; - } - - @Override - protected String getSuffix() { - - return _suffix; - } - -} diff --git a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StopEntityRequest.java b/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StopEntityRequest.java deleted file mode 100644 index 4dce76959f..0000000000 --- a/src/main/java/com/hp/application/automation/tools/sse/sdk/request/StopEntityRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hp.application.automation.tools.sse.sdk.request; - -import com.hp.application.automation.tools.sse.sdk.Client; - -/*** - * - * @author Effi Bar-She'an - * @author Dani Schreiber - * - */ - -public class StopEntityRequest extends PostRequest { - - public StopEntityRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - - return String.format("procedure-runs/%s/stop", _runId); - } - -} diff --git a/src/main/java/com/microfocus/application/automation/tools/AlmToolsUtils.java b/src/main/java/com/microfocus/application/automation/tools/AlmToolsUtils.java new file mode 100644 index 0000000000..cbeb435d3f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/AlmToolsUtils.java @@ -0,0 +1,234 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools; + +import com.microfocus.application.automation.tools.settings.UFTEncryptionGlobalConfiguration; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.util.ArgumentListBuilder; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.*; + +@SuppressWarnings("squid:S1160") +public final class AlmToolsUtils { + + private AlmToolsUtils() { + // no meaning instantiating + } + public static void runOnBuildEnv( + Run build, + Launcher launcher, + TaskListener listener, + FilePath file, + String paramFileName, + Node node) throws IOException, InterruptedException { + runOnBuildEnv(build, launcher, listener, file, paramFileName, node, "UTF-8"); + } + public static void runOnBuildEnv( + Run build, + Launcher launcher, + TaskListener listener, + FilePath file, + String paramFileName, + Node node, + String encoding) throws IOException, InterruptedException { + + ArgumentListBuilder args = new ArgumentListBuilder(); + PrintStream out = listener.getLogger(); + + // Use script to run the cmdLine and get the console output + args.add(file); + args.add("-paramfile"); + args.add(paramFileName); + if (StringUtils.isNotBlank(encoding)) { + args.add("-encoding"); + args.add(encoding); + } + + // for encryption + Map envs = new HashMap<>(); + + try { + UFTEncryptionGlobalConfiguration config = UFTEncryptionGlobalConfiguration.getInstance(); + envs.put("hptoolslauncher.key", Secret.fromString(config.getEncKey()).getPlainText()); + } catch (NullPointerException ignored) { + throw new IOException("Failed to access encryption key, the module UFTEncryption is unavailable."); + } + + if (node == null) { + node = JenkinsUtils.getCurrentNode(file); + + if (node == null) { + throw new IOException("Failed to access current executor node."); + } + } + + try { + envs.put("hptoolslauncher.rootpath", Objects.requireNonNull(node.getRootPath()).getRemote()); + } catch (NullPointerException e) { + throw new IOException(e.getMessage()); + } + + // Run the script on node + // Execution result should be 0 + int returnCode = launcher.launch().cmds(args).stdout(out).pwd(file.getParent()).envs(envs).join(); + + if (returnCode != 0) { + if (returnCode == -1) { + build.setResult(Result.FAILURE); + } else if (returnCode == -2) { + build.setResult(Result.UNSTABLE); + } else if (returnCode == -3) { + build.setResult(Result.ABORTED); + // throwing this exception ensures we enter into the respective catch branch in the callstack + throw new InterruptedException(); + } else { + listener.getLogger().println("Launch return code " + returnCode); + build.setResult(Result.FAILURE); + if(returnCode == -2146232576 && file.getRemote().toLowerCase(Locale.ROOT).contains("\\system32\\config")) { + listener.getLogger().println("!!! Move 'JENKINS_HOME' out of the 'windows\\\\system32' folder because the plugin may not have permissions to launch tests under this folder."); + } + } + } + } + + public static void runHpToolsAborterOnBuildEnv( + AbstractBuild build, + Launcher launcher, + BuildListener listener, + String paramFileName) throws IOException, InterruptedException { + + runHpToolsAborterOnBuildEnv(build, launcher, listener, paramFileName, build.getWorkspace()); + } + + @SuppressWarnings("squid:S2259") + public static void runHpToolsAborterOnBuildEnv( + Run build, + Launcher launcher, + TaskListener listener, + String paramFileName, FilePath runWorkspace) throws IOException, InterruptedException { + + ArgumentListBuilder args = new ArgumentListBuilder(); + PrintStream out = listener.getLogger(); + + String hpToolsAborter_exe = "HpToolsAborter.exe"; + + URL hpToolsAborterUrl = Jenkins.get().pluginManager.uberClassLoader.getResource("HpToolsAborter.exe"); + FilePath hpToolsAborterFile = runWorkspace.child(hpToolsAborter_exe); + + args.add(hpToolsAborterFile); + args.add(paramFileName); + + hpToolsAborterFile.copyFrom(hpToolsAborterUrl); + + int returnCode = launcher.launch().cmds(args).stdout(out).pwd(hpToolsAborterFile.getParent()).join(); + + try { + hpToolsAborterFile.delete(); + } catch (Exception e) { + listener.error("failed copying HpToolsAborter: " + e); + } + + + if (returnCode != 0) { + if (returnCode == 1) { + build.setResult(Result.FAILURE); + } else if (returnCode == 2) { + build.setResult(Result.UNSTABLE); + } else if (returnCode == 3) { + build.setResult(Result.ABORTED); + } + } + } + + public static boolean tryCreatePropsFile(TaskListener listener, String props, FilePath fileProps) throws InterruptedException, IOException { + + if (StringUtils.isBlank(props)) { + listener.fatalError("Missing properties text content."); //should never happen + return false; + } + if (fileProps.exists() && fileProps.length() > 0) { // this should never happen + listener.getLogger().println(String.format("NOTE: The file [%s] already exists.", fileProps.getRemote())); + } + + String msg = String.format("Trying to create or replace the file [%s] ...", fileProps.getRemote()); + listener.getLogger().println(msg); + return trySaveAndCheckPropsFile(listener, props, fileProps, 0); + } + + private static boolean trySaveAndCheckPropsFile(TaskListener listener, String props, FilePath fileProps, int idxOfRetry) throws InterruptedException { + boolean ok = false; + try { + try (InputStream in = IOUtils.toInputStream(props, StandardCharsets.UTF_8)) { + fileProps.copyFrom(in); + } + Thread.sleep(1500); + if (fileProps.exists() && fileProps.length() > 0) { + String msg = "Successfully created the file"; + if (idxOfRetry == 0) { + listener.getLogger().println(String.format("%s [%s].", msg, fileProps.getName())); + } else { + listener.getLogger().println(String.format("%s after %d %s.", msg, idxOfRetry, (idxOfRetry == 1 ? "retry" : "retries"))); + } + ok = true; + } else if (idxOfRetry > 5) { + listener.fatalError("Failed to save the file " + fileProps.getName() + " after 5 retries."); + } else { + ok = trySaveAndCheckPropsFile(listener, props, fileProps, ++idxOfRetry); + } + } catch (IOException ioe) { + if (idxOfRetry > 5) { + listener.fatalError("Failed to save the file " + fileProps.getName() + " after 5 retries: " + ioe.getMessage()); + } else { + Thread.sleep(1500); + ok = trySaveAndCheckPropsFile(listener, props, fileProps, ++idxOfRetry); + } + } + return ok; + } + + public static String getPropsAsString(Properties props) throws IOException { + try (OutputStream stream = new ByteArrayOutputStream()) { + props.store(stream, ""); + return stream.toString(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/EncryptionUtils.java b/src/main/java/com/microfocus/application/automation/tools/EncryptionUtils.java new file mode 100644 index 0000000000..06713de0b0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/EncryptionUtils.java @@ -0,0 +1,348 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.application.automation.tools.nodes.EncryptionNodeProperty; +import com.microfocus.application.automation.tools.settings.UFTEncryptionGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.FilePath; +import hudson.model.Node; +import hudson.util.Secret; +import org.apache.commons.io.IOUtils; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.spec.EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; +import java.util.Base64; + +public final class EncryptionUtils { + + private static final int KEY_SIZE = 3072; // should be secure for some time + private static final String ENC_TYPE_FOR_PROPS = "RSA"; + private static final String ENC_TYPE_FOR_NODE = "AES/CBC/PKCS7Padding"; + private static final String PRIVATE_SPEC_FOR_NODE = "AES"; + private static final String KEY_PATH = "secrets/.hptoolslaunchersecret.key"; + private static final String NL = System.getProperty("line.separator"); + + private EncryptionUtils() { + // no meaning instantiating + } + + /** + * Parses a public key returns its PublicKey instance. + * @param publicKeyStr public key in base64 string format + * @return PublicKey instance + * @throws EncryptionException if an error occurs while recreating the PublicKey + */ + private static PublicKey tryParsePublicKey(String publicKeyStr) throws EncryptionException { + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance(ENC_TYPE_FOR_PROPS); + } catch (NoSuchAlgorithmException ignored) { + throw new EncryptionException("Failed to get key factory."); + } + + EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr.replace("\n", "").getBytes(StandardCharsets.UTF_8))); + + PublicKey publicKey; + try { + publicKey = keyFactory.generatePublic(publicKeySpec); + } catch (InvalidKeySpecException ignored) { + throw new EncryptionException("Failed to regenerate public key."); + } + + return publicKey; + } + + /** + * Generates a new random public-private key pair. + * @return Public and Private Keys + * @throws EncryptionException if an error occurs while creating the keys + */ + private static Pair generatePair() throws EncryptionException { + KeyPairGenerator generator; + + try { + generator = KeyPairGenerator.getInstance(ENC_TYPE_FOR_PROPS); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Failed to get key pair generator."); + } + + generator.initialize(KEY_SIZE); + KeyPair pair = generator.generateKeyPair(); + return new Pair<>(pair.getPublic(), pair.getPrivate()); + } + + /** + * Convert an array of bytes into base64 string format. + * @param bytes + * @return string + */ + private static String getBase64(byte[] bytes) { + return Base64.getEncoder().encodeToString(bytes); + } + + private static String getPublicKeyEncoded(PublicKey publicKey) { + return getBase64(publicKey.getEncoded()); + } + + /** + * Convert a BigInteger instance into an array of bytes, takes into account the sign bit as well. + * @param bigInt + * @return + */ + static byte[] getBytes(BigInteger bigInt) { + byte[] bytes = bigInt.toByteArray(); + int length = bytes.length; + + if (length % 2 != 0 && bytes[0] == 0) { + bytes = Arrays.copyOfRange(bytes, 1, length); + } + + return bytes; + } + + /** + * Used in XML format conversion, creates a new string formatted XML node. + * @param name + * @param bigInt + * @return + */ + private static String getElement(String name, BigInteger bigInt) { + String cnt = getBase64(getBytes(bigInt)); + return String.format("<%s>%s%s", name, cnt, name, NL); + } + + /** + * Converts a Private Key into XML format used in C#, needed when we want to save the private key for the hptoolslauncher, currently a limitation. + * @param key + * @return + * @throws EncryptionException if an error occurs while the conversion + */ + private static String convertPrivateKeyToXMLFormat(PrivateKey key) throws EncryptionException { + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance(ENC_TYPE_FOR_PROPS); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Failed to get key factory."); + } + + RSAPrivateCrtKeySpec spec; + try { + spec = keyFactory.getKeySpec(key, RSAPrivateCrtKeySpec.class); + } catch (InvalidKeySpecException e) { + throw new EncryptionException("Failed to create specification for private key."); + } + + return "" + NL + + getElement("Modulus", spec.getModulus()) + + getElement("Exponent", spec.getPublicExponent()) + + getElement("P", spec.getPrimeP()) + + getElement("Q", spec.getPrimeQ()) + + getElement("DP", spec.getPrimeExponentP()) + + getElement("DQ", spec.getPrimeExponentQ()) + + getElement("InverseQ", spec.getCrtCoefficient()) + + getElement("D", spec.getPrivateExponent()) + + ""; + } + + /** + * Saves the private key on the executor node. + * @param root + * @param key + * @throws EncryptionException + */ + private static void savePrivateKeyForNode(FilePath root, PrivateKey key) throws EncryptionException { + // we have a private key, needs to be saved to the agent's fs encrypted + Secret sk; + try { + sk = Secret.fromString(UFTEncryptionGlobalConfiguration.getInstance().getEncKey()); + } catch (NullPointerException ignored) { + throw new EncryptionException("Jenkins cannot find the module for encryption secret key."); + } + + String privateKey = convertPrivateKeyToXMLFormat(key); + String encrypted = encryptWithPwd(privateKey, sk.getPlainText()); + InputStream encryptedAsStream = IOUtils.toInputStream(encrypted, StandardCharsets.UTF_8); + + try { + root.child(KEY_PATH).copyFrom(encryptedAsStream); + } catch (IOException | InterruptedException e) { + throw new EncryptionException("Failed to save private key to executor node: " + e.getMessage() + "."); + } + } + + /** + * Encrypts the data using the node's public key. + * @param text to be encrypted + * @param currNode current executor + * @return encrypted string in base64 format + * @throws EncryptionException + */ + public static String encrypt(String text, Node currNode) throws EncryptionException { + EncryptionNodeProperty publicKeyProp = currNode.getNodeProperty(EncryptionNodeProperty.class); + + if (publicKeyProp == null) { + // if the encryption node property is not enabled for this node, enable it automatically + currNode.getNodeProperties().add(new EncryptionNodeProperty()); + publicKeyProp = currNode.getNodeProperty(EncryptionNodeProperty.class); + } + + if (publicKeyProp == null) throw new EncryptionException("You need to enable encryption in Node configuration manually first, automatic addition failed before running UFT tests."); + + String publicKeyStr = Secret.fromString(publicKeyProp.getPublicKey()).getPlainText(); + PublicKey publicKey; + + if (StringUtils.isNullOrEmpty(publicKeyStr)) { + Pair encPair; + try { + // we generate a new pair for this node + encPair = generatePair(); + } catch (EncryptionException ignored) { + throw new EncryptionException("Failed to generate key pairs for encryption."); + } + + publicKey = encPair.getFirst(); + publicKeyStr = getPublicKeyEncoded(publicKey); + + // save the private to the node, encrypted, we will provide during runtime the decryption key + savePrivateKeyForNode(currNode.getRootPath(), encPair.getSecond()); + + // save the public on the server + publicKeyProp.setPublicKey(publicKeyStr); + + try { + currNode.save(); + } catch (IOException e) { + throw new EncryptionException("Failed to save public key on executor node: " + e.getMessage() + "."); + } + } else { + publicKey = tryParsePublicKey(publicKeyStr); + } + + return encrypt(text, publicKey); + } + + /** + * Encrypts the data with the given PublicKey. + * @param text to be encrypted + * @param publicKey + * @return encrypted string in base64 format + * @throws EncryptionException + */ + public static String encrypt(String text, PublicKey publicKey) throws EncryptionException { + Cipher encryptCipher; + try { + encryptCipher = Cipher.getInstance(ENC_TYPE_FOR_PROPS); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ignored) { + throw new EncryptionException("Failed to obtain " + ENC_TYPE_FOR_PROPS + " cipher."); + } + + try { + encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey); + } catch (InvalidKeyException ignored) { + throw new EncryptionException("Failed to initialize " + ENC_TYPE_FOR_PROPS + " cipher."); + } + + byte[] plainBytes = text.getBytes(StandardCharsets.UTF_8); + byte[] encryptedBytes; + try { + encryptedBytes = encryptCipher.doFinal(plainBytes); + } catch (IllegalBlockSizeException | BadPaddingException ignored) { + throw new EncryptionException("Failed to encrypt data."); + } + + return getBase64(encryptedBytes); + } + + /** + * Internal usage only, used when saving private key on executor node. + * @param text + * @param pwd + * @return + * @throws EncryptionException + */ + private static String encryptWithPwd(String text, String pwd) throws EncryptionException { + Cipher cipher; + try { + cipher = Cipher.getInstance(ENC_TYPE_FOR_NODE); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ignored) { + throw new EncryptionException("Failed to obtain " + ENC_TYPE_FOR_NODE + " cipher."); + } + + SecretKeySpec keySpec = new SecretKeySpec(pwd.getBytes(StandardCharsets.UTF_8), PRIVATE_SPEC_FOR_NODE); + try { + cipher.init(Cipher.ENCRYPT_MODE, keySpec, new SecureRandom()); + } catch (InvalidKeyException ignored) { + throw new EncryptionException("Failed to initialize " + ENC_TYPE_FOR_NODE + " cipher."); + } + + byte[] encrypted; + try { + encrypted = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8)); + } catch (IllegalBlockSizeException | BadPaddingException ignored) { + throw new EncryptionException("Failed to encrypt data."); + } + + byte[] ivBytes = cipher.getIV(); + byte[] combined = new byte[ivBytes.length + encrypted.length]; + System.arraycopy(ivBytes, 0, combined, 0, ivBytes.length); + System.arraycopy(encrypted, 0, combined, ivBytes.length, encrypted.length); + + return getBase64(combined); + } + + public static class EncryptionException extends Exception { + public EncryptionException(String message) { + super(message); + } + + @Override + public String getMessage() { + return super.getMessage(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/JenkinsUtils.java b/src/main/java/com/microfocus/application/automation/tools/JenkinsUtils.java new file mode 100644 index 0000000000..0f8f646eba --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/JenkinsUtils.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import hudson.FilePath; +import hudson.model.Node; +import hudson.model.Run; + +import javax.annotation.Nonnull; +import java.util.Objects; + +public final class JenkinsUtils { + + private JenkinsUtils() { + // no meaning instantiating + } + + /** + * Returns the current executor node from the Run instance. + * @param build current job + * @return executor + */ + @CheckForNull + public static Node getCurrentNode(@Nonnull FilePath workspace) { + try { + Node currNode; + // throws NullPointerException if failed to access executor node + currNode = Objects.requireNonNull(workspace.toComputer()).getNode(); + return currNode; + } catch (NullPointerException ignored) { + // ignore + } + + return null; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/ALMRESTVersionUtils.java b/src/main/java/com/microfocus/application/automation/tools/common/ALMRESTVersionUtils.java new file mode 100644 index 0000000000..d11085952d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/ALMRESTVersionUtils.java @@ -0,0 +1,67 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +import com.microfocus.application.automation.tools.model.ALMVersion; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import java.io.ByteArrayInputStream; + +/** + * @author Effi Bar-She'an + */ +public class ALMRESTVersionUtils { + + public static ALMVersion toModel(byte[] xml) { + + ALMVersion ret = null; + try { + JAXBContext context; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(ALMRESTVersionUtils.class.getClassLoader()); + try { + context = JAXBContext.newInstance(ALMVersion.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unMarshaller = context.createUnmarshaller(); + ret = (ALMVersion) unMarshaller.unmarshal(new ByteArrayInputStream(xml)); + } catch (Exception e) { + throw new SSEException("Failed to convert XML to ALMVersion", e); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/common/Func.java b/src/main/java/com/microfocus/application/automation/tools/common/Func.java new file mode 100644 index 0000000000..db7f85b4f7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/Func.java @@ -0,0 +1,38 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +public interface Func { + + public TResult execute(); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/Pair.java b/src/main/java/com/microfocus/application/automation/tools/common/Pair.java new file mode 100644 index 0000000000..3defc4d195 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/Pair.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +import java.util.Objects; + +public class Pair { + + private final TFirst _first; + private final TSecond _second; + + public Pair(TFirst first, TSecond second) { + _first = first; + _second = second; + } + + public TFirst getFirst() { + return _first; + } + + public TSecond getSecond() { + return _second; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Pair pair = (Pair) o; + return Objects.equals(_first, pair._first) && Objects.equals(_second, pair._second); + } + + @Override + public int hashCode() { + return Objects.hash(_first, _second); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/RuntimeIOException.java b/src/main/java/com/microfocus/application/automation/tools/common/RuntimeIOException.java new file mode 100644 index 0000000000..5388bc092e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/RuntimeIOException.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +/** + * Class is designed for wrapping java-IO exception + */ +public class RuntimeIOException extends RuntimeException { + + public RuntimeIOException() { + super(); + } + + public RuntimeIOException(String msg) { + super(msg); + } + + public RuntimeIOException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/RuntimeUtils.java b/src/main/java/com/microfocus/application/automation/tools/common/RuntimeUtils.java new file mode 100644 index 0000000000..12a24db387 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/RuntimeUtils.java @@ -0,0 +1,42 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +public class RuntimeUtils { + + @SuppressWarnings("unchecked") + public static T cast(Object obj) { + + return (T) obj; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/SSEException.java b/src/main/java/com/microfocus/application/automation/tools/common/SSEException.java new file mode 100644 index 0000000000..56227098f7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/SSEException.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +public class SSEException extends RuntimeException { + + private static final long serialVersionUID = -5386355008323770858L; + + public SSEException(Throwable cause) { + + super(cause); + } + + public SSEException(String message) { + + super(message); + } + + public SSEException(String message, Throwable cause) { + + super(message, cause); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/FunctionFileCallable.java b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/FunctionFileCallable.java new file mode 100644 index 0000000000..7afe5752a3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/FunctionFileCallable.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.masterToSlave; + +import hudson.FilePath; +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; + +/** + * This class is suppose to be passed as argument to {@link hudson.FilePath#act(FilePath.FileCallable)} in order for + * the master to execute a method that accepts parameter and returns parameter. + * @param The argument which passed to the generic method that will be executed on the slave. + * Note: it has to be serialized. + * @param The return value of the passed method in the constructor + */ +public class FunctionFileCallable extends MasterToSlaveFileCallable { + private final ThrowingFunction function; + private final T value; + + public FunctionFileCallable(ThrowingFunction function, T value) { + this.function = function; + this.value = value; + } + + @Override + public R invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { + return function.apply(value); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/SupplierFileCallable.java b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/SupplierFileCallable.java new file mode 100644 index 0000000000..6a80954ae5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/SupplierFileCallable.java @@ -0,0 +1,58 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.masterToSlave; + +import hudson.FilePath; +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; + +import java.io.File; +import java.io.IOException; + +/** + * This class is suppose to be passed as argument to {@link hudson.FilePath#act(FilePath.FileCallable)} in order for + * the master to execute a method that accepts parameter and returns parameter. + * @param The argument is returned for the method that is passed in the constructor. + */ +public class SupplierFileCallable extends MasterToSlaveFileCallable { + private final ThrowingSupplier supplier; + + public SupplierFileCallable(ThrowingSupplier supplier) { + this.supplier = supplier; + } + + @Override + public T invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { + return supplier.get(); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingFunction.java b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingFunction.java new file mode 100644 index 0000000000..44dc34d6bc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingFunction.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.masterToSlave; + +import hudson.AbortException; +import java.io.Serializable; + + +/** + * The interface was created in order to give a functional method like {@link java.util.function.Function} to throw + * additional + * exceptions + * @param The value which is passed to the method. + * @param The value which is retuend from the method. + */ +@FunctionalInterface +public interface ThrowingFunction extends Serializable { + R apply(T t) throws AbortException, InterruptedException; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingSupplier.java b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingSupplier.java new file mode 100644 index 0000000000..e2ca215458 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/masterToSlave/ThrowingSupplier.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.masterToSlave; + +import hudson.AbortException; + +import java.io.Serializable; + +/** + * The interface was created in order to give a functional method like {@link java.util.function.Supplier} ability to + * throw + * additional + * exceptions. + * @param The value which is returned from the method. + */ +@FunctionalInterface +public interface ThrowingSupplier extends Serializable { + T get() throws AbortException; +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/common/model/HealthAnalyzerModel.java b/src/main/java/com/microfocus/application/automation/tools/common/model/HealthAnalyzerModel.java new file mode 100644 index 0000000000..1ba7a42a76 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/model/HealthAnalyzerModel.java @@ -0,0 +1,73 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.model; + +import hudson.*; +import hudson.model.Describable; +import hudson.model.Descriptor; +import hudson.model.Run; +import hudson.model.TaskListener; +import jenkins.model.Jenkins; + +import javax.annotation.Nonnull; +import java.io.IOException; + +public abstract class HealthAnalyzerModel implements ExtensionPoint, Describable { + + public HealthAnalyzerModelDescriptor getDescriptor() { + return (HealthAnalyzerModelDescriptor) Jenkins.getInstance().getDescriptor(getClass()); + } + + public static ExtensionList all() { + return Jenkins.getInstance().getExtensionList(HealthAnalyzerModel.class); + } + + public abstract void perform( + @Nonnull Run run, @Nonnull FilePath workspace, + @Nonnull Launcher launcher, @Nonnull TaskListener listener) + throws InterruptedException, IOException; + + public abstract static class HealthAnalyzerModelDescriptor extends Descriptor { + protected HealthAnalyzerModelDescriptor() { + } + + @Override + public String toString() { + return "Info from HealthAnalyzerModelDescriptor"; + } + + public static DescriptorExtensionList all() { + return Jenkins.getInstance().getDescriptorList(HealthAnalyzerModel.class); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/model/VariableListWrapper.java b/src/main/java/com/microfocus/application/automation/tools/common/model/VariableListWrapper.java new file mode 100644 index 0000000000..9d7cdae8fc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/model/VariableListWrapper.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.model; + +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.List; + +/** + * This class was used in order as a workaround for + * JENKINS-33891 + * That is used in optionalBlock + */ +public class VariableListWrapper { + private List filesList; + + @DataBoundConstructor + public VariableListWrapper(List filesList) { + this.filesList = filesList; + } + + public List getFilesList() { + return filesList; + } + + public void setFilesList(List filesList) { + this.filesList = filesList; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/model/VariableWrapper.java b/src/main/java/com/microfocus/application/automation/tools/common/model/VariableWrapper.java new file mode 100644 index 0000000000..60d8aac6f3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/model/VariableWrapper.java @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; + +/** + * This class was used in order as a workaround for + * JENKINS-33891 + * That is used in optionalBlock + * With the UI of text box and closeable/addable item, see the corresponding config.jelly + */ +public class VariableWrapper extends AbstractDescribableImpl { + private String field; + + @DataBoundConstructor + public VariableWrapper(@Nonnull String field) { + this.field = field; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return ""; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder.java b/src/main/java/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder.java new file mode 100644 index 0000000000..54a9a71d5f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder.java @@ -0,0 +1,92 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.run; + +import com.microfocus.application.automation.tools.common.Messages; +import com.microfocus.application.automation.tools.common.model.HealthAnalyzerModel; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractProject; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.util.List; + +import static com.microfocus.application.automation.tools.Messages.CompanyName; + +public class HealthAnalyzerBuilder extends Builder implements SimpleBuildStep { + private final List products; + + @DataBoundConstructor + public HealthAnalyzerBuilder(List products) { + this.products = products; + } + + public List getProducts() { + return products; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { + for (HealthAnalyzerModel product : products) + product.perform(run, workspace, launcher, listener); + } + + @Extension + // @Symbol - to expose this step in the snippet generator, it's name as a parameter. + @Symbol("healthAnalyzer") + public static class DescriptorImpl extends BuildStepDescriptor { + @Nonnull + @Override + public String getDisplayName() { + return Messages.HealthAnalyzerBuilder_displayName(CompanyName()); + } + + @Override + public boolean isApplicable(Class jobType) { + return true; + } + + public List getProducts() { + return HealthAnalyzerModel.HealthAnalyzerModelDescriptor.all(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/common/utils/HealthAnalyzerCommon.java b/src/main/java/com/microfocus/application/automation/tools/common/utils/HealthAnalyzerCommon.java new file mode 100644 index 0000000000..c39c9ccffa --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/utils/HealthAnalyzerCommon.java @@ -0,0 +1,174 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.utils; + +import com.microfocus.application.automation.tools.common.Messages; +import com.microfocus.application.automation.tools.common.masterToSlave.FunctionFileCallable; +import com.microfocus.application.automation.tools.common.masterToSlave.SupplierFileCallable; +import com.microfocus.application.automation.tools.common.model.VariableWrapper; +import hudson.AbortException; +import hudson.FilePath; + +import javax.annotation.Nonnull; +import java.io.*; +import java.nio.file.Paths; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +/** + * The HealthAnalyzerCommon provides generic methods for every product to use + * Requires to be initiated with the product name + */ +public class HealthAnalyzerCommon implements Serializable { + private static final String AN_EXCEPTION_WAS_THROWN = "An exception was thrown"; + private static final Logger logger = Logger.getLogger(HealthAnalyzerCommon.class.getName()); + private final String productName; + + public HealthAnalyzerCommon(@Nonnull final String productName) { + Objects.requireNonNull(productName, Messages.HealthAnalyzerCommon_productNameValueMustBeNotNull()); + this.productName = productName; + } + + public void ifCheckedPerformWindowsInstallationCheck(@Nonnull final String registryPath, final boolean toCheck, + FilePath workspace) + throws IOException, InterruptedException { + if (toCheck) { + Objects.requireNonNull(registryPath, Messages.HealthAnalyzerCommon_registryValueMustBeNotNull()); + + if (!isRegistryExistsOnSlave(registryPath, workspace)) + throw new AbortException(Messages.HealthAnalyzerCommon_notInstalled(productName)); + } + } + + public boolean isRegistryExistsOnSlave(@Nonnull final String registryPath, FilePath workspace) throws + InterruptedException { + FunctionFileCallable callable = new FunctionFileCallable<>(this::isRegistryExist, + registryPath); + try { + if (OperatingSystem.isWindows()) + return workspace.act(callable); + throw new AbortException(Messages.HealthAnalyzerCommon_registryWorksOnlyOnWindows()); + } catch (IOException e) { + logger.log(Level.SEVERE, AN_EXCEPTION_WAS_THROWN, e); + } + return false; + } + + public boolean isRegistryExist(@Nonnull String registryPath) + throws InterruptedException, AbortException { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Callable task = () -> startRegistryQueryAndGetStatus(registryPath); + Future future = executor.submit(task); + executor.shutdown(); + executor.awaitTermination(500, TimeUnit.MILLISECONDS); + return getFutureResult(future); + } + + private boolean getFutureResult(Future future) throws InterruptedException, AbortException { + try { + return future.isDone() && future.get(); + } catch (ExecutionException e) { + throw new AbortException("failed to get result from the thread to check if registry exist: " + e + .getMessage()); + } + } + + private boolean startRegistryQueryAndGetStatus(@Nonnull final String registryPath) throws IOException { + ProcessBuilder builder = new ProcessBuilder("reg", "query", registryPath); + Process reg = builder.start(); + return isProcessStreamHasRegistry(reg); + } + + private boolean isProcessStreamHasRegistry(@Nonnull final Process reg) throws IOException { + try (BufferedReader output = new BufferedReader( + new InputStreamReader(reg.getInputStream()))) { + Stream keys = output.lines().filter(l -> !l.isEmpty()); + return keys.findFirst().isPresent(); + } + } + + private boolean isFileExistOnSlave(@Nonnull final String path, FilePath workspace) throws InterruptedException { + FunctionFileCallable callable = new FunctionFileCallable<>(this::isFileExist, path); + + try { + return workspace.act(callable); + } catch (IOException e) { + logger.log(Level.SEVERE, AN_EXCEPTION_WAS_THROWN, e); + } + + return false; + } + + public boolean isFileExist(final String path) throws AbortException { + if (path == null || path.isEmpty()) + return true; + + File file = Paths.get(path).toFile(); + if (file.exists()) { + if (file.isDirectory()) + throw new AbortException(Messages.HealthAnalyzerCommon_isDirectory(path)); + return file.isFile(); + } + + return false; + } + + public void ifCheckedPerformFilesExistenceCheck(final List files, boolean toCheck, FilePath + workspace) + throws AbortException, InterruptedException { + if (!toCheck || files == null || files.isEmpty()) + return; + + for (VariableWrapper file : files) + if (!isFileExistOnSlave(file.getField(), workspace)) + throw new AbortException(Messages.HealthAnalyzerCommon_fileNotExist(file.getField())); + + } + + public void ifCheckedPerformOsCheck(final OperatingSystem os, boolean toCheck, FilePath workspace) throws + InterruptedException { + SupplierFileCallable supplier = new SupplierFileCallable<>(os::equalsCurrentOs); + + try { + if (toCheck && !workspace.act(supplier)) + throw new AbortException(Messages.HealthAnalyzerCommon_operatingSystemIncorrect(os.toString() + .toLowerCase())); + } catch (IOException e) { + logger.log(Level.SEVERE, AN_EXCEPTION_WAS_THROWN, e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/common/utils/OperatingSystem.java b/src/main/java/com/microfocus/application/automation/tools/common/utils/OperatingSystem.java new file mode 100644 index 0000000000..8114927596 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/common/utils/OperatingSystem.java @@ -0,0 +1,77 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common.utils; + +import java.util.Arrays; +import java.util.List; + +public enum OperatingSystem { + LINUX, + WINDOWS, + MAC; + + private static final List POSIX_NAMES = Arrays.asList( + "linux", "os/2", "irix", "hp-ux", "aix", "soalris", "sunos"); + private static String os = System.getProperty("os.name").toLowerCase(); + private static boolean windows = os.contains(WINDOWS.name().toLowerCase()); + private static boolean mac = os.contains(MAC.name().toLowerCase()); + private static boolean linux = POSIX_NAMES.contains(os.toLowerCase()); + + public static String getOs() { + return os; + } + + private static void refreshOsVariablesForSlave() { + os = System.getProperty("os.name").toLowerCase(); + windows = os.contains(WINDOWS.name().toLowerCase()); + mac = os.contains(MAC.name().toLowerCase()); + linux = POSIX_NAMES.contains(os.toLowerCase()); + } + + public boolean equalsCurrentOs() { + refreshOsVariablesForSlave(); + return linux || os.contains(this.name().toLowerCase()); + } + + public static boolean isWindows() { + return windows; + } + + public static boolean isMac() { + return mac; + } + + public static boolean isLinux() { + return linux; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder.java new file mode 100644 index 0000000000..fa90b0eafd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder.java @@ -0,0 +1,414 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.cloudbees.plugins.credentials.matchers.IdMatcher; +import com.microfocus.application.automation.tools.commonResultUpload.uploader.Uploader; +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Util; +import hudson.model.AbstractProject; +import hudson.model.Item; +import hudson.model.Queue; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.model.queue.Tasks; +import hudson.security.ACL; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.VariableResolver; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static com.microfocus.application.automation.tools.Messages.CommonResultUploadBuilderName; +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.*; + +public class CommonResultUploadBuilder extends Recorder implements SimpleBuildStep { + + @DataBoundConstructor + public CommonResultUploadBuilder( + String almServerName, String credentialsId, String almDomain, + String clientType, String almProject, String almTestFolder, + String almTestSetFolder, String testingResultFile, + String runStatusMapping, String fieldMapping, + boolean createNewTest) { + + this.almServerName = almServerName; + this.credentialsId = credentialsId; + this.almDomain = almDomain; + this.clientType = clientType; + this.almProject = almProject; + this.almTestFolder = almTestFolder; + this.almTestSetFolder = almTestSetFolder; + this.testingResultFile = testingResultFile; + this.runStatusMapping = runStatusMapping; + this.fieldMapping = fieldMapping; + this.createNewTest = createNewTest; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) + throws InterruptedException, IOException { + + CommonUploadLogger logger = new CommonUploadLogger(taskListener.getLogger()); + UsernamePasswordCredentials credentials = getCredentialsById(credentialsId, run); + if (credentials == null) { + logger.warn("Can not find credentials with the credentialsId:" + credentialsId); + run.setResult(Result.ABORTED); + return; + } + + VariableResolver varResolver = new VariableResolver.ByMap(run.getEnvironment(taskListener)); + + Map params = new HashMap(); + params.put(ALM_SERVER_NAME, almServerName); + params.put(ALM_SERVER_URL, getAlmServerUrl(almServerName)); + params.put(USERNAME, credentials.getUsername()); + params.put(PASS, credentials.getPassword().getPlainText()); + params.put(ALM_DOMAIN, Util.replaceMacro(almDomain, varResolver)); + params.put(CLIENT_TYPE, clientType); + params.put(ALM_PROJECT, Util.replaceMacro(almProject, varResolver)); + params.put(ALM_TEST_FOLDER, almTestFolder); + params.put(ALM_TESTSET_FOLDER, almTestSetFolder); + params.put(RUN_STATUS_MAPPING, Util.replaceMacro(runStatusMapping, varResolver)); + params.put(TESTING_RESULT_FILE, Util.replaceMacro(testingResultFile, varResolver)); + params.put(FIELD_MAPPING, Util.replaceMacro(fieldMapping, varResolver)); + params.put(CREATE_NEW_TEST, String.valueOf(createNewTest)); + + Uploader uploader = new Uploader(run, workspace, logger, params); + uploader.upload(); + + // Output failed uploaded entities. + if (logger.getFailedMessages().size() > 0) { + logger.log("----------------------------------------------------------------"); + logger.log("Failed upload summary:"); + for (String failedMessage : logger.getFailedMessages()) { + logger.log(failedMessage); + } + run.setResult(Result.UNSTABLE); + } + } + + private String getAlmServerUrl(String almServerName) { + AlmServerSettingsModel[] almServers = AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + if (almServers != null && almServers.length > 0) { + for (AlmServerSettingsModel almServerModel: almServers) { + if (almServerName.equalsIgnoreCase(almServerModel.getAlmServerName())) { + return almServerModel.getAlmServerUrl(); + } + } + } + return ""; + } + + private UsernamePasswordCredentials getCredentialsById(String credentialsId, Run run) { + UsernamePasswordCredentials credentials = CredentialsProvider.findCredentialById(credentialsId, + StandardUsernamePasswordCredentials.class, + run, + URIRequirementBuilder.create().build()); + return credentials; + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Extension + // To expose this builder in the Snippet Generator. + @Symbol("commonResultUploadBuilder") + public static class DescriptorImpl extends BuildStepDescriptor { + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + return true; + } + + @Override + public String getDisplayName() { + return CommonResultUploadBuilderName(); + } + + public boolean hasAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().hasAlmServers(); + } + + public AlmServerSettingsModel[] getAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + public FormValidation doCheckAlmUserName(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("User name must be set"); + } + + return FormValidation.ok(); + } + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Domain must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Project must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmTestFolder(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("TestFolder are missing"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmTestSetFolder(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("TestSetFolder are missing"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckTestingResultFile(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Testing result file must be set"); + } + + return FormValidation.ok(); + } + + /** + * To fill in the credentials drop down list which's field is 'credentialsId'. + * This method's name works with tag . + */ + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + if (project == null || !project.hasPermission(Item.CONFIGURE)) { + return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); + } + return new StandardUsernameListBoxModel() + .includeEmptyValue() + .includeAs( + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + project, + StandardUsernamePasswordCredentials.class, + URIRequirementBuilder.create().build()) + .includeCurrentValue(credentialsId); + } + + public FormValidation doCheckCredentialsId(@AncestorInPath Item project, @QueryParameter String value) { + for (ListBoxModel.Option o : CredentialsProvider.listCredentials( + StandardUsernamePasswordCredentials.class, + project, + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + URIRequirementBuilder.create().build(), + new IdMatcher(value))) { + + if (StringUtils.equals(value, o.value)) { + return FormValidation.ok(); + } + } + // no credentials available, can't check + return FormValidation.warning("Cannot find any credentials with id " + value); + } + + public String defaultFieldMapping() { + return "testset:\n" + + " root: \"x:/result/suites/suite\"\n" + + " name: \"x:name\"\n" + + " udf|duration: \"x:duration\"\n" + + " udf|list: \"x:list\"\n" + + " subtype-id: \"v:hp.qc.test-set.default\"\n" + + " #subtype-id: \"v:hp.qc.test-set.default\"\n" + + " #subtype-id: \"v:hp.qc.test-set.external\"\n" + + " #subtype-id: \"v:hp.sse.test-set.process\"\n" + + "test:\n" + + " root: \"x:cases/case\"\n" + + " name: \"x:testName|v:_|x:testId\" # Use \"|\" to create a combined value, e.g.: _\n" + + " subtype-id: \"v:MANUAL\"\n" + + " #subtype-id: \"v:SERVICE-TEST\"\n" + + " #subtype-id: \"v:SYSTEM-TEST\"\n" + + " #subtype-id: \"v:VAPI-XP-TEST\"\n" + + " #subtype-id: \"v:ALT-SCENARIO\"\n" + + " #subtype-id: \"v:BUSINESS-PROCESS\"\n" + + " #subtype-id: \"v:FLOW\"\n" + + " #subtype-id: \"v:LEANFT-TEST\"\n" + + " #subtype-id: \"v:LR-SCENARIO\"\n" + + " #subtype-id: \"v:QAINSPECT-TEST\"\n" + + "run:\n" + + " root: \"x:.\" # \".\" means the same XML object as defined above in 'test' entity, all elements defined below are searched from the same root element as 'test' root\n" + + " #root: \"x:/result/suites/suite/cases/case\"\n" + + " duration: \"x:duration\" # This system field is integer, if you want to save a float number, please create a string format UDF\n" + + " status: \"x:status\"\n" + + " udf|Run On Version: \"x:RunOnVersion\" # Create an UDF and set its label to \"run on version\", to trigger the versioning logic\n" + + " udf|Date: \"2020-03-30\" # Date type field value should be in format \"yyyy-mm-dd\"\n"; + } + + public String defaultRunStatusMapping() { + return "status:\n" + + " Passed: \"==True\" # If status attribute is \"True\" in report, the run in ALM will be marked as \"Passed\". Else will be \"Failed\".\n" + + " #Failed: \">=0\" # If status attribute value greater or equals than 0, then run in ALM will be marked as \"Failed\". \n" + + " #Passed condition and Failed condition are mutural exclusion." ; + } + } + + private String almServerName; + private String credentialsId; + private String almDomain; + private String clientType; + private String almProject; + private String almTestFolder; + private String almTestSetFolder; + private String testingResultFile; + private String runStatusMapping; + private String fieldMapping; + private boolean createNewTest; + + public String getAlmServerName() { + return almServerName; + } + + public void setAlmServerName(String almServerName) { + this.almServerName = almServerName; + } + + public String getCredentialsId() { + return credentialsId; + } + + public void setCredentialsId(String credentialsId) { + this.credentialsId = credentialsId; + } + + public String getAlmDomain() { + return almDomain; + } + + public void setAlmDomain(String almDomain) { + this.almDomain = almDomain; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public String getAlmProject() { + return almProject; + } + + public void setAlmProject(String almProject) { + this.almProject = almProject; + } + + public String getAlmTestFolder() { + return almTestFolder; + } + + public void setAlmTestFolder(String almTestFolder) { + this.almTestFolder = almTestFolder; + } + + public String getAlmTestSetFolder() { + return almTestSetFolder; + } + + public void setAlmTestSetFolder(String almTestSetFolder) { + this.almTestSetFolder = almTestSetFolder; + } + + public String getTestingResultFile() { + return testingResultFile; + } + + public void setTestingResultFile(String testingResultFile) { + this.testingResultFile = testingResultFile; + } + + public String getRunStatusMapping() { + return runStatusMapping; + } + + public void setRunStatusMapping(String runStatusMapping) { + this.runStatusMapping = runStatusMapping; + } + + public String getFieldMapping() { + return fieldMapping; + } + + public void setFieldMapping(String fieldMapping) { + this.fieldMapping = fieldMapping; + } + + public boolean isCreateNewTest() { + return createNewTest; + } + + public void setCreateNewTest(boolean createNewTest) { + this.createNewTest = createNewTest; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonUploadLogger.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonUploadLogger.java new file mode 100644 index 0000000000..c247c048de --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/CommonUploadLogger.java @@ -0,0 +1,82 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload; + +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +public class CommonUploadLogger implements Logger { + + private static final String ERR_PREFIX = "ERR: "; + private static final String INFO_PREFIX = "INFO: "; + private static final String WARN_PREFIX = "WARN: "; + + private List failedMessages; + private PrintStream printStream; + + public CommonUploadLogger(PrintStream printStream) { + this.printStream = printStream; + failedMessages = new ArrayList<>(); + } + + public void error(String message) { + failedMessages.add(message); + message = ERR_PREFIX + message; + log(message); + } + + public void info(String message) { + message = INFO_PREFIX + message; + log(message); + } + + public void warn(String message) { + message = WARN_PREFIX + message; + log(message); + } + + @Override + public void log(String message) { + if (printStream != null) { + printStream.println(message); + } + } + + public List getFailedMessages() { + return failedMessages; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/ParamConstant.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/ParamConstant.java new file mode 100644 index 0000000000..8bb81cd2c8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/ParamConstant.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload; + +public final class ParamConstant { + private ParamConstant() { + + } + + public static final String ALM_SERVER_NAME = "almServerName"; + public static final String ALM_SERVER_URL = "almServerUrl"; + public static final String USERNAME = "username"; + public static final String PASS = "password"; + public static final String ALM_DOMAIN = "almDomain"; + public static final String CLIENT_TYPE = "clientType"; + public static final String ALM_PROJECT = "almProject"; + public static final String ALM_TEST_FOLDER = "almTestFolder"; + public static final String ALM_TESTSET_FOLDER = "almTestSetFolder"; + public static final String RUN_STATUS_MAPPING = "runStatusMapping"; + public static final String TESTING_RESULT_FILE = "testingResultFile"; + public static final String FIELD_MAPPING = "fieldMapping"; + public static final String ACTUAL_USER = "actualUser"; + public static final String CREATE_NEW_TEST = "createNewTest"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BaseGetEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BaseGetEntityRequest.java new file mode 100644 index 0000000000..a5a4cfd746 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BaseGetEntityRequest.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.rest; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; + +import java.util.HashMap; +import java.util.Map; + +public class BaseGetEntityRequest { + + private static final String X_XSRF_TOKEN = "X-XSRF-TOKEN"; + + protected RestClient client; + protected CommonUploadLogger logger; + + protected Map getHeaders() { + Map ret = new HashMap(); + ret.put(X_XSRF_TOKEN, client.getXsrfTokenValue()); + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BasicPostEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BasicPostEntityRequest.java new file mode 100644 index 0000000000..897edafe52 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/BasicPostEntityRequest.java @@ -0,0 +1,109 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.rest; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.RestXmlUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import org.apache.commons.lang3.StringEscapeUtils; + +import java.util.HashMap; +import java.util.Map; + +public abstract class BasicPostEntityRequest { + + private static final String START = ""; + private static final String END = ""; + private static final String IGNORE_REQUIRED_FIELDS_VALIDATION = "X-QC-Ignore-Customizable-Required-Fields-Validation"; + private static final String X_XSRF_TOKEN = "X-XSRF-TOKEN"; + + protected RestClient client; + protected CommonUploadLogger logger; + protected String operation; + + protected BasicPostEntityRequest(RestClient client, CommonUploadLogger logger, String operation) { + this.client = client; + this.logger = logger; + this.operation = operation; + } + + public abstract Map perform(String restPrefix, Map valueMap); + + protected Map getHeaders() { + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + ret.put(IGNORE_REQUIRED_FIELDS_VALIDATION, "Y"); + ret.put(X_XSRF_TOKEN, client.getXsrfTokenValue()); + return ret; + } + + private String getRestErrorMessage(String responseContent) { + return responseContent.substring( + responseContent.indexOf(START) + START.length(), + responseContent.indexOf(END) + ); + } + + protected byte[] getDataBytes(Map valueMap) { + StringBuilder builder = new StringBuilder(""); + for (Map.Entry entry : valueMap.entrySet()) { + builder.append(RestXmlUtils.fieldXml(entry.getKey(), StringEscapeUtils.escapeXml10(entry.getValue()))); + } + builder.append(""); + logger.info("Request body: " + builder.toString()); + return builder.toString().getBytes(); + } + + private String getResultNameAndId(Map result) { + return "id:" + result.get("id") + ", " + "name:" + result.get("name"); + } + + protected Map handleResult(Response response, Map valueMap, String restPrefix) { + if (response.isOk() && !response.toString().equals("")) { + Map result = XPathUtils.toEntities(response.toString()).get(0); + logger.info(String.format("%s entity success. %s(%s)", operation, restPrefix, + getResultNameAndId(result))); + return result; + } else { + logger.error(String.format("%s entity failed. %s(%s)", operation, restPrefix, + getResultNameAndId(valueMap))); + logger.error(response.getFailure().toString()); + logger.error(getRestErrorMessage(response.toString())); + return null; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/CreateAlmEntityEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/CreateAlmEntityEntityRequest.java new file mode 100644 index 0000000000..9b968ab745 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/CreateAlmEntityEntityRequest.java @@ -0,0 +1,58 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.rest; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.Map; + +public class CreateAlmEntityEntityRequest extends BasicPostEntityRequest { + + public CreateAlmEntityEntityRequest(RestClient client, CommonUploadLogger logger) { + super(client, logger, "Create"); + } + + @Override + public Map perform(String restPrefix, Map valueMap) { + String url = client.buildRestRequest(restPrefix); + Response response = client.httpPost( + url, + getDataBytes(valueMap), + getHeaders(), + ResourceAccessLevel.PROTECTED); + return handleResult(response, valueMap, restPrefix); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/GetAlmEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/GetAlmEntityRequest.java new file mode 100644 index 0000000000..6df604fe6b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/GetAlmEntityRequest.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.rest; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import org.apache.commons.lang.StringUtils; + +import java.util.List; +import java.util.Map; + +public class GetAlmEntityRequest extends BaseGetEntityRequest { + + public GetAlmEntityRequest(RestClient client, CommonUploadLogger logger) { + this.client = client; + this.logger = logger; + } + + public List> perform(String id, String restPrefix, String queryString) { + String suffix = StringUtils.isEmpty(id) + ? restPrefix + : String.format("%s/%s", restPrefix, id); + String url = client.buildRestRequest(suffix); + Response response = client.httpGet( + url, + queryString, + getHeaders(), + ResourceAccessLevel.PROTECTED); + if (response.isOk() && !response.toString().equals("")) { + List> results = XPathUtils.toEntities(response.toString()); + return results; + } else { + logger.error("Get entities failed from: " + url); + logger.error(response.getFailure().toString()); + return null; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/UpdateAlmEntityEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/UpdateAlmEntityEntityRequest.java new file mode 100644 index 0000000000..7a9a3b76e0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/rest/UpdateAlmEntityEntityRequest.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.rest; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.HashMap; +import java.util.Map; + +public class UpdateAlmEntityEntityRequest extends BasicPostEntityRequest { + + private static final String X_XSRF_TOKEN = "X-XSRF-TOKEN"; + + public UpdateAlmEntityEntityRequest(RestClient client, CommonUploadLogger logger) { + super(client, logger, "Update"); + } + + @Override + public Map perform(String restPrefix, Map valueMap) { + String url = client.buildRestRequest(String.format("%s/%s", restPrefix, valueMap.get("id"))); + Response response = client.httpPut( + url, + getDataBytes(valueMap), + getHeaders(), + ResourceAccessLevel.PROTECTED); + return handleResult(response, valueMap, restPrefix); + } + + @Override + protected Map getHeaders() { + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML_BULK); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + ret.put(X_XSRF_TOKEN, client.getXsrfTokenValue()); + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CriteriaTranslator.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CriteriaTranslator.java new file mode 100644 index 0000000000..ea41bf8690 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CriteriaTranslator.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.results.service.AlmRestTool; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CriteriaTranslator { + + public static final String CRITERIA_PREFIX = "q|"; + + private CriteriaTranslator() { + + } + + public static String getCriteriaString(String[] fields, Map entity) { + List tobeRemoved = new ArrayList<>(); + Map tobeAdded = new HashMap<>(); + + StringBuilder sb = new StringBuilder(); + sb.append("fields="); + for (int i = 0; i < fields.length; i++) { + sb.append(fields[i]); + if (i < fields.length - 1) { + sb.append(","); + } + } + + sb.append("&query={"); + for (Map.Entry entry : entity.entrySet()) { + String key = entry.getKey(); + if (key.startsWith(CRITERIA_PREFIX)) { + tobeRemoved.add(key); + String realName = key.substring( + key.indexOf(CRITERIA_PREFIX) + CRITERIA_PREFIX.length()); + tobeAdded.put(realName, entity.get(key)); + sb.append(realName).append("[") + .append(AlmRestTool.getEncodedString(entity.get(key))) + .append("]").append(";"); + } + } + // Search by name by default + if (tobeRemoved.size() == 0) { + sb.append(AlmCommonProperties.NAME).append("[") + .append(AlmRestTool.getEncodedString(entity.get("name"))) + .append("];"); + } + sb.append("}"); + + entity.putAll(tobeAdded); + for (String item : tobeRemoved) { + entity.remove(item); + } + return sb.toString(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CustomizationService.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CustomizationService.java new file mode 100644 index 0000000000..96e9234f5a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/CustomizationService.java @@ -0,0 +1,159 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.HashMap; +import java.util.Map; + +public class CustomizationService { + + public static final String RUN_ENTITY_NAME = "run"; + public static final String TEST_INSTANCE_ENTITY_NAME = "test-instance"; + public static final String TEST_ENTITY_NAME = "test"; + public static final String TEST_SET_ENTITY_NAME = "test-set"; + + private RestClient client; + private CommonUploadLogger logger; + private Map> subtypeCache; + private Map> fieldCache; + + public CustomizationService(RestClient client, CommonUploadLogger logger) { + this.client = client; + this.logger = logger; + subtypeCache = new HashMap<>(); + fieldCache = new HashMap<>(); + } + + public String getRunSubtypeIdByTestInstance(String testInstanceSubtypeId) { + return getSubtypeIdByName(RUN_ENTITY_NAME, + getSubtypeNameById(TEST_INSTANCE_ENTITY_NAME, testInstanceSubtypeId)); + } + + public String getTestInstanceSubtypeIdByTest(String testSubtypeId) { + return getSubtypeIdByName(TEST_INSTANCE_ENTITY_NAME, + getSubtypeNameById(TEST_ENTITY_NAME, testSubtypeId)); + } + + public String getSubtypeIdByName(String entityName, String subtypeName) { + return getEntitySubTypes(entityName).get(subtypeName); + } + + public String getSubtypeNameById(String entityName, String subtypeId) { + for (Map.Entry subtype : getEntitySubTypes(entityName).entrySet()) { + if (subtype.getValue().equals(subtypeId)) { + return subtype.getKey(); + } + } + return null; + } + + public Map getEntitySubTypes(String entityName) { + if (subtypeCache.get(entityName) == null) { + String suffix = String.format("customization/entities/%s/types", entityName); + String url = client.buildRestRequest(suffix); + Response response = client.httpGet( + url, + null, + null, + ResourceAccessLevel.PROTECTED); + if (response.isOk() && !response.toString().equals("")) { + logger.info(String.format("Get customization entity subtypes success. [%s]", entityName)); + Map customizationMap = XPathUtils.getEntitySubtypesMap(response.toString()); + subtypeCache.put(entityName, customizationMap); + return customizationMap; + } else { + logger.error("Get customization entity subtypes failed from: " + url); + logger.error(response.getFailure().toString()); + return null; + } + } else { + return subtypeCache.get(entityName); + } + } + + public String getUDFNameByLabel(String entityName, String label) { + return getEntityFields(entityName).get(label); + } + + public Map getEntityFields(String entityName) { + if (fieldCache.get(entityName) == null) { + String suffix = String.format("customization/entities/%s/fields", entityName); + String url = client.buildRestRequest(suffix); + Response response = client.httpGet( + url, + null, + null, + ResourceAccessLevel.PROTECTED); + if (response.isOk() && !response.toString().equals("")) { + logger.info(String.format("Get customization entity fields success. [%s]", entityName)); + Map entityFieldsMap = XPathUtils.getEntityFieldsMap(response.toString()); + fieldCache.put(entityName, entityFieldsMap); + return entityFieldsMap; + } else { + logger.error("Get customization entity fields failed from: " + url); + logger.error(response.getFailure().toString()); + return null; + } + } else { + return fieldCache.get(entityName); + } + } + + public boolean isVersioningEnabled(String entityName) { + String suffix = String.format("customization/entities/%s", entityName); + String url = client.buildRestRequest(suffix); + Response response = client.httpGet( + url, + null, + null, + ResourceAccessLevel.PROTECTED); + if (response.isOk() && !response.toString().equals("")) { + logger.log(String.format("INFO: -- Get Entity Resource Descriptor success. [%s]", entityName)); + Document document = XPathUtils.getDocument(response.toString()); + Element element = (Element) document.getElementsByTagName("SupportsVC").item(0); + return "true".equals(element.getTextContent()); + } else { + logger.log("ERR: Get entities failed from: " + url); + logger.log("ERR: " + response.getFailure()); + return false; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/FolderService.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/FolderService.java new file mode 100644 index 0000000000..2d6d3c2500 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/FolderService.java @@ -0,0 +1,149 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.results.service.AlmRestTool; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +public class FolderService { + + private static final String FOLDER_SEPERATOR = "\\"; + private RestService restService; + + public FolderService(RestService restService) { + this.restService = restService; + } + + public Map createOrFindPath(String prefix, String parentId, String path) { + List> folders = new ArrayList>(); + StringTokenizer tokenizer = new StringTokenizer(path, FOLDER_SEPERATOR); + while (tokenizer.hasMoreTokens()) { + String itemString = tokenizer.nextToken(); + Map folder = createFolder(prefix, parentId, itemString); + if (folder != null) { + folders.add(folder); + parentId = folder.get("id"); + } + } + if (folders.size() > 0) { + return folders.get(folders.size() - 1); + } else { + return null; + } + } + + public Map createFolder(String prefix, String parentId, String folderName) { + Map existsFolder = checkFolderExits(prefix, parentId, folderName); + if (existsFolder == null) { + existsFolder = new HashMap<>(); + existsFolder.put(AlmCommonProperties.PARENT_ID, parentId); + existsFolder.put(AlmCommonProperties.NAME, folderName); + return restService.create(prefix, existsFolder); + } else { + return existsFolder; + } + } + + public Map checkFolderExits(String prefix, String parentId, String folderName) { + String query = String.format("fields=id,name&query={parent-id[%s];name[%s]}", + parentId, + AlmRestTool.getEncodedString(folderName)); + List> entities = restService.get(null, prefix, query); + if (entities.size() > 0) { + return entities.get(0); + } else { + return null; + } + } + + public List> getSubFolders(String prefix, String parentFolderId) { + String query = String.format("fields=id,name&query={parent-id[%s]}", parentFolderId); + return restService.get(null, prefix, query); + } + + public Map findEntityInFolder( + Map testFolder, + Map test, + String entityPrefix, + String folderPrefix, + String[] queryFields) { + List> foundTests = new ArrayList<>(); + + // Make criteria fields. + test.put(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.PARENT_ID, + testFolder.get(AlmCommonProperties.ID)); + + if (test.get(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.ID) != null + && !test.get(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.ID).isEmpty()) { + // If there's ID in the criteria, ignor name criteria. + } else { + test.put(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.NAME, + test.get(AlmCommonProperties.NAME)); + } + + findEntityInFolderAndSub(foundTests, test, entityPrefix, folderPrefix, queryFields); + return foundTests.size() > 0 ? foundTests.get(0) : null; + } + + private void findEntityInFolderAndSub(List> foundTests, + Map test, String entityPrefix, + String folderPrefix, String[] queryFields) { + List> existTests = restService.get(null, + entityPrefix, CriteriaTranslator.getCriteriaString(queryFields, test)); + + if (existTests == null || existTests.size() == 0) { + // Not in current folder, find in sub folders + List> subFolders = + getSubFolders(folderPrefix, test.get(AlmCommonProperties.PARENT_ID)); + + if (subFolders != null) { + for (Map subfolder : subFolders) { + // Make criteria fields. + test.put(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.PARENT_ID, + subfolder.get(AlmCommonProperties.ID)); + test.put(CriteriaTranslator.CRITERIA_PREFIX + AlmCommonProperties.NAME, + test.get(AlmCommonProperties.NAME)); + findEntityInFolderAndSub(foundTests, test, entityPrefix, folderPrefix, queryFields); + } + } + } else { + foundTests.addAll(existTests); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RestService.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RestService.java new file mode 100644 index 0000000000..a4b77790fa --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RestService.java @@ -0,0 +1,129 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.rest.CreateAlmEntityEntityRequest; +import com.microfocus.application.automation.tools.commonResultUpload.rest.GetAlmEntityRequest; +import com.microfocus.application.automation.tools.commonResultUpload.rest.UpdateAlmEntityEntityRequest; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class RestService { + + private RestClient restClient; + private CreateAlmEntityEntityRequest createAlmEntityRequest; + private GetAlmEntityRequest getAlmEntityRequest; + private UpdateAlmEntityEntityRequest updateAlmEntityRequest; + private UDFTranslator udt; + private CommonUploadLogger logger; + + public RestService(RestClient restClient, CommonUploadLogger logger, UDFTranslator udt) { + this.restClient = restClient; + this.logger = logger; + createAlmEntityRequest = new CreateAlmEntityEntityRequest(restClient, logger); + getAlmEntityRequest = new GetAlmEntityRequest(restClient, logger); + updateAlmEntityRequest = new UpdateAlmEntityEntityRequest(restClient, logger); + this.udt = udt; + } + + public Map create(String restPrefix, Map valueMap) { + udt.translate(restPrefix, valueMap); + return createAlmEntityRequest.perform(restPrefix, valueMap); + } + + public List> get(String id, String restPrefix, String queryString) { + return getAlmEntityRequest.perform(id, restPrefix, queryString); + } + + public Map update(String restPrefix, Map valueMap) { + udt.translate(restPrefix, valueMap); + return updateAlmEntityRequest.perform(restPrefix, valueMap); + } + + public List getDomains() { + String url = restClient.getServerUrl(); + if (!url.endsWith("/")) { + url = String.format("%s/", url); + } + url = String.format("%s%s/domains", url, "rest"); + return getDomainOrProjectListFromResponse("Domain", url); + } + + public List getProjects(String domain) { + String url = restClient.getServerUrl(); + if (!url.endsWith("/")) { + url = String.format("%s/", url); + } + url = String.format("%s%s/domains/%s/projects", url, "rest", domain); + return getDomainOrProjectListFromResponse("Project", url); + } + + private List getDomainOrProjectListFromResponse(String dopo, String url) { + Response response = restClient.httpGet(url, null, null, + ResourceAccessLevel.PROTECTED); + + List list = new ArrayList<>(); + if (response.isOk() && !response.toString().equals("")) { + Document document = null; + try { + document = XPathUtils.getDocument(response.toString()); + } catch (SSEException e) { + logger.error("Get xml document failed: " + e.getMessage()); + logger.error("Please check ALM server's status."); + } + if (document != null) { + NodeList domainList = document.getElementsByTagName(dopo); + for (int i = 0; i < domainList.getLength(); i++) { + String project = domainList.item(i).getAttributes().getNamedItem("Name").getTextContent(); + list.add(project); + } + } else { + logger.error("Cannot get any content from response while getting " + dopo); + } + } else { + logger.error("Get " + dopo + "s failed from: " + url); + logger.error(response.getFailure().toString()); + } + return list; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RunStatusResolver.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RunStatusResolver.java new file mode 100644 index 0000000000..2012097f46 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/RunStatusResolver.java @@ -0,0 +1,109 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import org.apache.commons.lang.StringUtils; + +import java.util.Map; +import java.util.regex.Pattern; + +public final class RunStatusResolver { + + private RunStatusResolver() { } + + public static String getRunStatus(String status, Map runStatusMapping) { + String passCondition = runStatusMapping.get(IAlmConsts.IStatuses.PASSED.value()); + String failedCondition = runStatusMapping.get(IAlmConsts.IStatuses.FAILED.value()); + + if (!StringUtils.isEmpty(passCondition)) { + return resolveCondition(status, passCondition) + ? IAlmConsts.IStatuses.PASSED.value() : IAlmConsts.IStatuses.FAILED.value(); + } + if (!StringUtils.isEmpty(failedCondition)) { + return resolveCondition(status, failedCondition) + ? IAlmConsts.IStatuses.FAILED.value() : IAlmConsts.IStatuses.PASSED.value(); + } + + return IAlmConsts.IStatuses.NO_RUN.value(); + } + + private static boolean resolveCondition(String statusValue, String condition) { + String mark = condition.substring(0, 2); + String conditionValue = condition.substring(2); + + if (conditionValue.equals("NULL")) { + switch (mark) { + case "==": + return StringUtils.isEmpty(statusValue); + case "!=": + return !StringUtils.isEmpty(statusValue); + default: + throw new IllegalArgumentException("Condition mark is incorrect for run status NULL."); + } + } + + switch (mark) { + case "==": + if (isNumeric(conditionValue)) { + return Double.parseDouble(statusValue) == Double.parseDouble(conditionValue); + } else { + return statusValue.equals(conditionValue); + } + case "!=": + if (isNumeric(conditionValue)) { + return Double.parseDouble(statusValue) != Double.parseDouble(conditionValue); + } else { + return !statusValue.equals(conditionValue); + } + case ">>": + return Double.parseDouble(statusValue) > Double.parseDouble(conditionValue); + case ">=": + return Double.parseDouble(statusValue) >= Double.parseDouble(conditionValue); + case "<<": + return Double.parseDouble(statusValue) < Double.parseDouble(conditionValue); + case "<=": + return Double.parseDouble(statusValue) <= Double.parseDouble(conditionValue); + default: + throw new IllegalArgumentException("Condition mark is incorrect."); + } + } + + private static boolean isNumeric(String strNum) { + Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); + if (strNum == null) { + return false; + } + return pattern.matcher(strNum).matches(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/UDFTranslator.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/UDFTranslator.java new file mode 100644 index 0000000000..1eb1614189 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/UDFTranslator.java @@ -0,0 +1,95 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.uploader.RunUploader; +import com.microfocus.application.automation.tools.commonResultUpload.uploader.TestSetUploader; +import com.microfocus.application.automation.tools.commonResultUpload.uploader.TestUploader; +import org.apache.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class UDFTranslator { + + public static final String UDF_PREFIX = "udf|"; + private CommonUploadLogger logger; + private CustomizationService customizationService; + + public UDFTranslator(CustomizationService customizationService, CommonUploadLogger logger) { + this.customizationService = customizationService; + this.logger = logger; + } + + public void translate(String restPrefix, Map valueMap) { + switch (restPrefix) { + case TestSetUploader.TEST_SET_REST_PREFIX: + transUDFNames(CustomizationService.TEST_SET_ENTITY_NAME, valueMap); + break; + case TestUploader.TEST_REST_PREFIX: + transUDFNames(CustomizationService.TEST_ENTITY_NAME, valueMap); + break; + case RunUploader.RUN_PREFIX: + transUDFNames(CustomizationService.RUN_ENTITY_NAME, valueMap); + break; + default: + } + } + + private void transUDFNames(String entityName, Map entityMap) { + List tobeRemoved = new ArrayList<>(); + Map tobeAdded = new HashMap<>(); + + for (Map.Entry entry : entityMap.entrySet()) { + String name = entry.getKey(); + if (name.startsWith(UDF_PREFIX)) { + String label = name.substring( + name.indexOf(UDF_PREFIX) + UDF_PREFIX.length()); + String realName = customizationService.getUDFNameByLabel(entityName, label); + if (StringUtils.isNotEmpty(realName)) { + tobeAdded.put(realName, entityMap.get(name)); + tobeRemoved.add(name); + } else { + logger.error(String.format("No user defined field with label [%s] was found.", label)); + } + } + } + entityMap.putAll(tobeAdded); + for (String item : tobeRemoved) { + entityMap.remove(item); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/VersionControlService.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/VersionControlService.java new file mode 100644 index 0000000000..78ccd7b9cb --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/service/VersionControlService.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.service; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +public class VersionControlService { + + public static final String CHECK_IN = "check-in"; + public static final String CHECK_OUT = "check-out"; + public static final String CHECK_UNDO_CHECK_OUT = "undo-check-out"; + + private RestClient client; + private CommonUploadLogger logger; + + public VersionControlService(RestClient client, CommonUploadLogger logger) { + this.client = client; + this.logger = logger; + } + + /** + * For new created entity, you can only get it's version number after check out and undo check out. + * @param restPrefix + * @param entityId + * @return + */ + public boolean refreshEntityVersion(String restPrefix, String entityId) { + boolean result = false; + result = versionsCheck(restPrefix, entityId, CHECK_OUT); + if (!result) { + return false; + } + return versionsCheck(restPrefix, entityId, CHECK_UNDO_CHECK_OUT); + } + + /** + * check in, check out, undo check out a entity + * @param restPrefix + * @param entityId + * @param operation + * @return + */ + public boolean versionsCheck(String restPrefix, String entityId, String operation) { + String suffix = String.format("%s/%s/versions/%s", restPrefix, entityId, operation); + String url = client.buildRestRequest(suffix); + Response response = client.httpPost(url, null, null, ResourceAccessLevel.PROTECTED); + if (!response.isOk()) { + logger.error(String.format("%s entity failed. %s(%s)", operation, restPrefix, entityId)); + logger.error(response.getFailure().toString()); + return false; + } else { + return true; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/RunUploader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/RunUploader.java new file mode 100644 index 0000000000..eecfab9bd8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/RunUploader.java @@ -0,0 +1,230 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.uploader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.CustomizationService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RestService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RunStatusResolver; +import com.microfocus.application.automation.tools.results.service.AttachmentUploadService; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import org.apache.commons.lang.StringUtils; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; + +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.ACTUAL_USER; + +public class RunUploader { + + public static final String RUN_PREFIX = "runs"; + private static final String RUN_VERSION_MAP_NAME = "udf|Run On Version"; + private static final String VC_VERSION_NUMBER = "vc-version-number"; + + private CommonUploadLogger logger; + private Map params; + private Map runStatusMapping; + private RestService restService; + private CustomizationService customizationService; + + public RunUploader(CommonUploadLogger logger, Map params, + RestService restService, CustomizationService customizationService, + Map runStatusMapping) { + this.logger = logger; + this.params = params; + this.restService = restService; + this.customizationService = customizationService; + this.runStatusMapping = runStatusMapping; + } + + public void upload(Map testset, Map test, + Map testconfig, Map testinstance, + Map run) { + + // Get attachment info and remove + String attachment = run.get("attachment"); + run.remove("attachment"); + + // Set relations + run.put(AlmRun.RUN_CONFIG_ID, testconfig.get(AlmCommonProperties.ID)); + run.put(AlmRun.RUN_CYCLE_ID, testset.get(AlmCommonProperties.ID)); + run.put(AlmRun.RUN_TEST_ID, test.get(AlmCommonProperties.ID)); + run.put(AlmRun.RUN_TESTCYCL_UNIQUE_ID, testinstance.get(AlmCommonProperties.ID)); + // Set calculated values + run.put(AlmCommonProperties.OWNER, params.get(ACTUAL_USER)); + run.put(AlmCommonProperties.NAME, generateImportRunName()); + run.put(AlmRun.RUN_DURATION, convertDuration(run.get(AlmRun.RUN_DURATION))); + run.put(AlmRun.RUN_SUBTYPE_ID, + customizationService.getRunSubtypeIdByTestInstance( + testinstance.get(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID))); + // Set values for external test + if (StringUtils.isNotEmpty(run.get(AlmRun.RUN_DETAIL))) { + run.put(AlmRun.RUN_DETAIL, convertDetail(run.get(AlmRun.RUN_DETAIL))); + } + + if (!shouldProceedVersionForRun(test, run)) { + return; + } + + // Update test instance status + String runstatus = RunStatusResolver.getRunStatus(run.get(AlmRun.RUN_STATUS), runStatusMapping); + + if (StringUtils.isNotEmpty(runstatus)) { + // Create a run without status + run.remove(AlmRun.RUN_STATUS); + Map createdRun = restService.create(RUN_PREFIX, run); + + // Update status of the run + Map updateRun = new HashMap<>(); + updateRun.put(AlmCommonProperties.ID, createdRun.get(AlmCommonProperties.ID)); + updateRun.put(AlmRun.RUN_STATUS, runstatus); + + // Retry update run status 3 times. For some ALM server may has limited DB connections then the update may fail. + // Added here because only here uses RestService.update. + // Otherwise the retry could be in RestService.update or UpdateAlmEntityEntityRequest.perform + // depends on whether the result would be changed if update multiple times. + // But this should be fixed at ALM server side to larger the connection number I think. + + Map updateResult = restService.update(RUN_PREFIX, updateRun); + if (updateResult == null) { + for (int i = 0; i < 3; i++) { + if (updateResult == null) { + updateResult = restService.update(RUN_PREFIX, updateRun); + } else { + break; + } + } + } + if (StringUtils.isNotEmpty(attachment) && updateResult != null) { + AttachmentUploadService.getInstance().upload(attachment, RUN_PREFIX, updateResult.get("id")); + } + + } else { + Map createdRun = restService.create(RUN_PREFIX, run); + if (StringUtils.isNotEmpty(attachment)) { + AttachmentUploadService.getInstance().upload(attachment, RUN_PREFIX, createdRun.get("id")); + } + } + } + + private String convertDetail(String detail) { + if (StringUtils.isNotEmpty(detail)) { + detail = detail.replaceAll("<", "<"); + detail = detail.replaceAll(">", ">"); + return Base64Encoder.encode(detail.getBytes()); + } + return detail; + } + + private String convertDuration(String duration) { + if (duration != null && duration.length() > 0) { + Float durationTime = 0.0f; + try { + durationTime = Float.valueOf(duration); + } catch (NumberFormatException e) { + return String.valueOf(0); + } + return String.valueOf(durationTime.intValue()); + } else { + return String.valueOf(0); + } + } + + private String generateImportRunName() { + Calendar cal = new GregorianCalendar(); + cal.setTime(new java.sql.Date(System.currentTimeMillis())); + return String.format( + IAlmConsts.IMPORT_RUN_NAME_TEMPLATE, + // java.util.Calendar represents months from 0 to 11 instead of from 1 to 12. + // That's why it should be incremented. + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + cal.get(Calendar.SECOND)); + } + + /** + * Project without versioning, proceed + * No "udf|run on version" in Run, proceed + * No "vc-version-number" value in Test, proceed + * Run version should be no bigger than latest test version + * Set latest test version to run if run version has no value. + * @param test + * @param run + * @return + */ + private boolean shouldProceedVersionForRun(Map test, Map run) { + // Some test type doesn't have version support + for (String noVersionTest : TestUploader.NO_VERSION_TESTS) { + if (test.get("subtype-id").equals(noVersionTest)) { + return true; + } + } + + boolean shouldProceed = true; + boolean versioningEnabled = customizationService.isVersioningEnabled( + CustomizationService.TEST_ENTITY_NAME); + if (versioningEnabled && run.containsKey(RUN_VERSION_MAP_NAME) + && StringUtils.isNotEmpty(test.get(VC_VERSION_NUMBER))) { + + if (StringUtils.isEmpty(run.get(RUN_VERSION_MAP_NAME))) { + run.put(RUN_VERSION_MAP_NAME, test.get(VC_VERSION_NUMBER)); + logger.info("Run on version not found. Set it as the latest test version."); + } else { + try { + int testLatestVersion = Integer.parseInt(test.get(VC_VERSION_NUMBER)); + int runVersion = Integer.parseInt(run.get(RUN_VERSION_MAP_NAME)); + if (runVersion > testLatestVersion) { + logger.error("Run version larger than test latest version."); + shouldProceed = false; + } + if (runVersion < 1) { + run.put(RUN_VERSION_MAP_NAME, "1"); + logger.info("Run on version is " + runVersion + ". Minimum version should be 1. Set it to 1."); + } + } catch (NumberFormatException e) { + logger.error("Version number illegal. " + e.getMessage()); + shouldProceed = false; + } + } + } + return shouldProceed; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestInstanceUploader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestInstanceUploader.java new file mode 100644 index 0000000000..49456bd626 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestInstanceUploader.java @@ -0,0 +1,142 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.uploader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.CustomizationService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RestService; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import com.microfocus.application.automation.tools.results.service.AttachmentUploadService; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import org.apache.commons.lang.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.ACTUAL_USER; + +public class TestInstanceUploader { + + private static final String TEST_CONFIG_PREFIX = "test-configs"; + public static final String TEST_INSTANCE_PREFIX = "test-instances"; + + private CommonUploadLogger logger; + private Map params; + private RestService restService; + private RunUploader runUploader; + private CustomizationService customizationService; + + public TestInstanceUploader(CommonUploadLogger logger, Map params, + RestService restService, RunUploader runUploader, + CustomizationService customizationService) { + this.logger = logger; + this.params = params; + this.restService = restService; + this.runUploader = runUploader; + this.customizationService = customizationService; + } + + public void upload(Map testset, XmlResultEntity xmlResultEntity, String attachment) { + Map test = xmlResultEntity.getValueMap(); + Map testconfig = getMainTestConfig(test); + Map testinstance; + + if (testconfig != null) { + List> testInstances = getExistTestInstances(testset, test, testconfig); + if (testInstances != null) { + if (testInstances.size() == 0) { + testinstance = buildNewTestInstance(testset, test, testconfig); + testinstance.putAll(restService.create(TEST_INSTANCE_PREFIX, testinstance)); + } else { + testinstance = testInstances.get(0); + } + + if (StringUtils.isNotEmpty(attachment)) { + AttachmentUploadService.getInstance().upload(attachment, TEST_INSTANCE_PREFIX, testinstance.get("id")); + } + + // Upload run + if (xmlResultEntity.getSubEntities().size() > 0) { + runUploader.upload(testset, test, testconfig, testinstance, + xmlResultEntity.getSubEntities().get(0).getValueMap()); + } else { + logger.info("No run is found for test: " + test.get("name")); + } + } + } + } + + private Map buildNewTestInstance( + Map testset, + Map test, + Map testconfig) { + Map testinstance = new HashMap<>(); + testinstance.put(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, + customizationService.getTestInstanceSubtypeIdByTest(test.get(AlmTest.TEST_TYPE))); + testinstance.put(AlmTestInstance.TEST_INSTANCE_TESTSET_ID, + String.valueOf(testset.get(AlmCommonProperties.ID))); + testinstance.put(AlmTestInstance.TEST_INSTANCE_CONFIG_ID, + String.valueOf(testconfig.get(AlmCommonProperties.ID))); + testinstance.put(AlmTestInstance.TEST_INSTANCE_TEST_ID, + String.valueOf(test.get(AlmCommonProperties.ID))); + testinstance.put(AlmTestInstance.TEST_INSTANCE_TESTER_NAME, + params.get(ACTUAL_USER)); + return testinstance; + } + + private Map getMainTestConfig(Map test) { + String queryString = String.format("query={parent-id[%s]}&fields=id,name", + String.valueOf(test.get(AlmCommonProperties.ID))); + List> testconfigs = restService.get(null, TEST_CONFIG_PREFIX, queryString); + if (testconfigs != null && testconfigs.size() > 0) { + return testconfigs.get(0); + } else { + return null; + } + } + + private List> getExistTestInstances( + Map testset, + Map test, + Map testconfig) { + String queryString = String.format( + "query={cycle-id[%s];test-config-id[%s];test-id[%s]}&fields=id,name,subtype-id", + String.valueOf(testset.get(AlmCommonProperties.ID)), + String.valueOf(testconfig.get(AlmCommonProperties.ID)), + String.valueOf(test.get(AlmCommonProperties.ID))); + return restService.get(null, TEST_INSTANCE_PREFIX, queryString); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestSetUploader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestSetUploader.java new file mode 100644 index 0000000000..b16c611040 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestSetUploader.java @@ -0,0 +1,121 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.uploader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.FolderService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RestService; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import com.microfocus.application.automation.tools.results.service.AttachmentUploadService; +import org.apache.commons.lang.StringUtils; + +import java.util.List; +import java.util.Map; + +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.ALM_TESTSET_FOLDER; + +public class TestSetUploader { + + public static final String TEST_SET_REST_PREFIX = "test-sets"; + private static final String TEST_SET_FOLDERS_REST_PREFIX = "test-set-folders"; + + private Map params; + private CommonUploadLogger logger; + private RestService restService; + private FolderService folderService; + private TestUploader testuploader; + + public TestSetUploader(CommonUploadLogger logger, Map params, + RestService restService, + FolderService folderService, + TestUploader testuploader) { + this.logger = logger; + this.params = params; + this.restService = restService; + this.folderService = folderService; + this.testuploader = testuploader; + } + + public void upload(List xmlResultEntities) { + logger.info("Test set upload start."); + + Map folder = createOrFindTestsetFolder(); + + for (XmlResultEntity xmlResultEntity : xmlResultEntities) { + Map testset = xmlResultEntity.getValueMap(); + + // Find if there is test set with same name in the defined folder + Map existTestset = folderService.findEntityInFolder(folder, testset, + TEST_SET_REST_PREFIX, TEST_SET_FOLDERS_REST_PREFIX, + new String[]{"id", "name", "subtype-id"}); + + uploadOrUpdateTestset(existTestset, testset, xmlResultEntity); + } + } + + private boolean uploadOrUpdateTestset(Map existTestset, + Map testset, XmlResultEntity xmlResultEntity) { + Map newTestset; + String attachment = testset.get("attachment"); + testset.remove("attachment"); + + if (existTestset != null) { + // If yes, use the exist one to update. + newTestset = existTestset; + } else { + // If no, create test set under folder + newTestset = restService.create(TEST_SET_REST_PREFIX, testset); + } + + if (newTestset == null) { + return false; + } else { + if (StringUtils.isNotEmpty(attachment)) { + AttachmentUploadService.getInstance().upload(attachment, TEST_SET_REST_PREFIX, newTestset.get("id")); + } + testuploader.upload(newTestset, xmlResultEntity.getSubEntities()); + } + return true; + } + + private Map createOrFindTestsetFolder() { + if (!StringUtils.isEmpty(params.get(ALM_TESTSET_FOLDER))) { + return folderService.createOrFindPath( + TEST_SET_FOLDERS_REST_PREFIX, + "0", + params.get(ALM_TESTSET_FOLDER)); + } else { + return null; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestUploader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestUploader.java new file mode 100644 index 0000000000..3ec832590c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/TestUploader.java @@ -0,0 +1,165 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.uploader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.CriteriaTranslator; +import com.microfocus.application.automation.tools.commonResultUpload.service.CustomizationService; +import com.microfocus.application.automation.tools.commonResultUpload.service.FolderService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RestService; +import com.microfocus.application.automation.tools.commonResultUpload.service.VersionControlService; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; +import org.apache.commons.lang.StringUtils; + +import java.util.List; +import java.util.Map; + +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.ALM_TEST_FOLDER; +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.CREATE_NEW_TEST; + +public class TestUploader { + + public static final String TEST_REST_PREFIX = "tests"; + private static final String TEST_FOLDERS_REST_PREFIX = "test-folders"; + public static final String[] NO_VERSION_TESTS = new String[]{"ALT-SCENARIO", + "LEANFT-TEST", "LR-SCENARIO", "QAINSPECT-TEST"}; + private static final String VC_VERSION_NUMBER = "vc-version-number"; + private static final String SUB_TYPE_ID = "subtype-id"; + + private Map params; + private CommonUploadLogger logger; + private RestService restService; + private FolderService folderService; + private CustomizationService customizationService; + private TestInstanceUploader testInstanceUploader; + private VersionControlService versionControlService; + + public TestUploader(CommonUploadLogger logger, Map params, + RestService restService, FolderService folderService, + TestInstanceUploader testInstanceUploader, + CustomizationService customizationService, + VersionControlService versionControlService) { + this.logger = logger; + this.params = params; + this.restService = restService; + this.folderService = folderService; + this.testInstanceUploader = testInstanceUploader; + this.customizationService = customizationService; + this.versionControlService = versionControlService; + } + + public void upload(Map testset, List xmlResultEntities) { + logger.info("Test upload start."); + for (XmlResultEntity xmlResultEntity : xmlResultEntities) { + Map test = xmlResultEntity.getValueMap(); + Map newTest; + + String attachment = test.get("attachment"); + test.remove("attachment"); + + if (!StringUtils.isEmpty(params.get(ALM_TEST_FOLDER))) { + // Create or find a exists folder + Map folder = folderService.createOrFindPath( + TEST_FOLDERS_REST_PREFIX, "2", params.get(ALM_TEST_FOLDER)); + if (folder == null) { + continue; + } + + // Find exists test under folder + Map existsTest = folderService.findEntityInFolder(folder, test, + TEST_REST_PREFIX, TEST_FOLDERS_REST_PREFIX, + new String[]{"id", "name", SUB_TYPE_ID, VC_VERSION_NUMBER}); + if (existsTest != null) { + // If exists, update the test. + existsTest.putAll(test); + newTest = restService.update(TEST_REST_PREFIX, existsTest); + } else { + logger.log("Test not found by criteria:"); + for (Map.Entry entry : test.entrySet()) { + if (entry.getKey().equals("name") || entry.getKey().startsWith(CriteriaTranslator.CRITERIA_PREFIX)) { + logger.log("----" + entry.getKey() + "=" + entry.getValue()); + } + } + + // If not, create the test under the folder + test.put(AlmCommonProperties.PARENT_ID, folder.get(AlmCommonProperties.ID)); + if (params.get(CREATE_NEW_TEST).equals("true")) { + newTest = restService.create(TEST_REST_PREFIX, test); + } else { + newTest = null; + logger.log("Test not found and not created: " + test.toString()); + } + } + } else { + // If no path was specified, put test under root + test.put(AlmCommonProperties.PARENT_ID, "0"); + if (params.get(CREATE_NEW_TEST).equals("true")) { + newTest = restService.create(TEST_REST_PREFIX, test); + } else { + newTest = null; + logger.log("Test not found and not created: " + test.toString()); + } + } + + if (newTest == null) { + continue; + } else { + // upload test instance + getVersionNumberForVC(newTest); + test.putAll(newTest); + testInstanceUploader.upload(testset, xmlResultEntity, attachment); + } + } + } + + private void getVersionNumberForVC(Map newTest) { + // Some test type doesn't have version support + for (String noVersionTest : NO_VERSION_TESTS) { + if (newTest.get(SUB_TYPE_ID).equals(noVersionTest)) { + return; + } + } + + boolean versioningEnabled = customizationService.isVersioningEnabled( + CustomizationService.TEST_ENTITY_NAME); + if (versioningEnabled && StringUtils.isEmpty(newTest.get(VC_VERSION_NUMBER))) { + versionControlService.refreshEntityVersion(TEST_REST_PREFIX, + newTest.get(AlmCommonProperties.ID)); + + newTest.putAll(restService.get(newTest.get(AlmCommonProperties.ID), + TEST_REST_PREFIX, CriteriaTranslator.getCriteriaString( + new String[]{"id", "name", SUB_TYPE_ID, VC_VERSION_NUMBER}, newTest)).get(0)); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/Uploader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/Uploader.java new file mode 100644 index 0000000000..2dfa0c3e60 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/uploader/Uploader.java @@ -0,0 +1,150 @@ +/* + * 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. + * ___________________________________________________________________ + */ +package com.microfocus.application.automation.tools.commonResultUpload.uploader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.CustomizationService; +import com.microfocus.application.automation.tools.commonResultUpload.service.FolderService; +import com.microfocus.application.automation.tools.commonResultUpload.service.RestService; +import com.microfocus.application.automation.tools.commonResultUpload.service.UDFTranslator; +import com.microfocus.application.automation.tools.commonResultUpload.service.VersionControlService; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.configloader.RunStatusMapLoader; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.EntitiesFieldMap; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.configloader.EntitiesFieldMapLoader; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.RunStatusMap; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.XmlReader; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.results.service.AlmRestTool; +import com.microfocus.application.automation.tools.results.service.AttachmentUploadService; +import com.microfocus.application.automation.tools.sse.sdk.authenticator.AuthenticationTool; +import hudson.FilePath; +import hudson.model.Run; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.microfocus.application.automation.tools.commonResultUpload.ParamConstant.*; + +public class Uploader { + + private RestClient restClient; + private Map params; + private CommonUploadLogger logger; + private CustomizationService cs; + private VersionControlService vs; + private UDFTranslator udt; + private RestService rs; + private FolderService fs; + private Run run; + private FilePath workspace; + + public Uploader(Run run, FilePath workspace, CommonUploadLogger logger, Map params) { + this.run = run; + this.workspace = workspace; + this.logger = logger; + this.params = params; + } + + public void upload() { + restClient = new RestClient(params.get(ALM_SERVER_URL), + params.get(ALM_DOMAIN), + params.get(ALM_PROJECT), + params.get(USERNAME)); + + boolean login = AuthenticationTool.getInstance().authenticate(restClient, + params.get(USERNAME), params.get(PASS), + params.get(ALM_SERVER_URL), params.get(CLIENT_TYPE), logger); + if (login) { + init(); + if (!rs.getDomains().contains(params.get(ALM_DOMAIN))) { + logger.error("Invalid domain name:" + params.get(ALM_DOMAIN)); + return; + } + if (!rs.getProjects(params.get(ALM_DOMAIN)).contains(params.get(ALM_PROJECT))) { + logger.error("Invalid project name:" + params.get(ALM_PROJECT)); + return; + } + List xmlResultEntities = getUploadData(); + if (xmlResultEntities == null || xmlResultEntities.size() == 0) { + return; + } + TestSetUploader testSetUploader = getTestSetUploader(); + if (testSetUploader == null) { + return; + } + AlmRestTool almRestTool = new AlmRestTool(restClient, logger); + params.put(ACTUAL_USER, almRestTool.getActualUsername()); + testSetUploader.upload(xmlResultEntities); + } else { + logger.error("Login failed."); + } + } + + private void init() { + cs = new CustomizationService(restClient, logger); + vs = new VersionControlService(restClient, logger); + udt = new UDFTranslator(cs, logger); + rs = new RestService(restClient, logger, udt); + fs = new FolderService(rs); + AttachmentUploadService.init(run, workspace, restClient, logger); + } + + private TestSetUploader getTestSetUploader() { + RunStatusMap runStatusMap = RunStatusMapLoader.load(params.get(RUN_STATUS_MAPPING), logger); + if (runStatusMap == null) { + return null; + } + RunUploader runu = new RunUploader(logger, params, rs, cs, runStatusMap.getStatus()); + TestInstanceUploader tiu = new TestInstanceUploader(logger, params, rs, runu, cs); + TestUploader testu = new TestUploader(logger, params, rs, fs, tiu, cs, vs); + return new TestSetUploader(logger, params, rs, fs, testu); + } + + private List getUploadData() { + List xmlResultEntities = new ArrayList<>(); + + EntitiesFieldMap entitiesFieldMap = EntitiesFieldMapLoader.load(params.get(FIELD_MAPPING), logger, cs, + "true".equals(params.get(CREATE_NEW_TEST))); + if (entitiesFieldMap == null) { + return xmlResultEntities; + } + + XmlReader xmlReader = new XmlReader(run, workspace, logger); + xmlResultEntities = xmlReader.scan(params.get(TESTING_RESULT_FILE), entitiesFieldMap); + if (xmlResultEntities == null || xmlResultEntities.size() == 0) { + logger.error("No test result content is found."); + } + return xmlResultEntities; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/TestSetReader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/TestSetReader.java new file mode 100644 index 0000000000..1bfa5a24c5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/TestSetReader.java @@ -0,0 +1,108 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader; + +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.EntitiesFieldMap; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import hudson.FilePath; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TestSetReader { + + private XpathReader xr; + private ValueTranslator translator; + private EntitiesFieldMap entitiesFieldMap; + private static final String ROOT = "root"; + + public TestSetReader(FilePath filePath, EntitiesFieldMap entitiesFieldMap) + throws IOException, ParserConfigurationException, InterruptedException, SAXException { + xr = new XpathReader(filePath); + translator = new ValueTranslator(xr); + this.entitiesFieldMap = entitiesFieldMap; + } + + public TestSetReader(String resultPath, EntitiesFieldMap entitiesFieldMap) + throws IOException, SAXException, ParserConfigurationException { + xr = new XpathReader(resultPath); + translator = new ValueTranslator(xr); + this.entitiesFieldMap = entitiesFieldMap; + } + + public List readTestsets() throws XPathExpressionException { + List testsets = readEntities(entitiesFieldMap.getTestset(), xr.getDoc()); + return testsets; + } + + private List readEntities(Map configMap, Node node) + throws XPathExpressionException { + String rootXpath = configMap.get(ROOT); + rootXpath = rootXpath.substring(2, rootXpath.length()); + NodeList nodes = xr.getNodeListFromNode(rootXpath, node); + + List entities = new ArrayList<>(); + for (int i = 0; i < nodes.getLength(); i++) { + XmlResultEntity entity = new XmlResultEntity(); + Node currentNode = nodes.item(i); + + Map fieldsMap = new HashMap<>(); + for (Map.Entry entry : configMap.entrySet()) { + String fieldName = entry.getKey(); + String fieldValue = configMap.get(fieldName); + if (ROOT.equals(fieldName)) { + continue; + } + fieldValue = translator.translate(fieldValue, currentNode); + fieldsMap.put(fieldName, fieldValue); + } + entity.setValueMap(fieldsMap); + + Map nextConfigMap = entitiesFieldMap.getNextConfigMap(configMap); + if (nextConfigMap != null) { + List subEntities = readEntities(nextConfigMap, currentNode); + entity.setSubEntities(subEntities); + } + entities.add(entity); + } + return entities; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/ValueTranslator.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/ValueTranslator.java new file mode 100644 index 0000000000..b85e37df17 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/ValueTranslator.java @@ -0,0 +1,65 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader; + +import org.w3c.dom.Node; + +import javax.xml.xpath.XPathExpressionException; + +public class ValueTranslator { + + private XpathReader xpathReader; + + public ValueTranslator(XpathReader xpathReader) { + this.xpathReader = xpathReader; + } + + public String translate(String fieldValue, Node node) throws XPathExpressionException { + String[] arr = fieldValue.split("\\|"); + StringBuilder sb = new StringBuilder(); + for (String i : arr) { + sb.append(translateUnit(i, node)); + } + return sb.toString(); + } + + private String translateUnit(String fieldValue, Node node) throws XPathExpressionException { + if ("v:".equals(fieldValue.substring(0, 2))) { + fieldValue = fieldValue.substring(2, fieldValue.length()); + } else if ("x:".equals(fieldValue.substring(0, 2))) { + fieldValue = fieldValue.substring(2, fieldValue.length()); + fieldValue = xpathReader.getValueFromNode(fieldValue, node); + } + return fieldValue; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XmlReader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XmlReader.java new file mode 100644 index 0000000000..49544e6f18 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XmlReader.java @@ -0,0 +1,122 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader; + +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.EntitiesFieldMap; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.XmlResultEntity; +import hudson.FilePath; +import hudson.model.Result; +import hudson.model.Run; +import org.apache.tools.ant.DirectoryScanner; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class XmlReader { + + private CommonUploadLogger logger; + private Run run; + private FilePath workspace; + + public XmlReader(Run run, FilePath workspace, CommonUploadLogger logger) { + this.run = run; + this.logger = logger; + this.workspace = workspace; + } + + public List scan(String filePath, EntitiesFieldMap entitiesFieldMap) { + DirectoryScanner ds = new DirectoryScanner(); + ds.setBasedir(run.getRootDir()); + ds.setIncludes(new String[] {filePath}); + ds.scan(); + + if (ds.getIncludedFilesCount() == 0) { + logger.info("No Test Report found in job folder: " + run.getRootDir().getAbsolutePath()); + return scanInWorkspace(filePath, entitiesFieldMap); + } else { + logger.info(ds.getIncludedFilesCount() + " test result file found in job folder: " + run.getRootDir().getAbsolutePath()); + return readBuildPath(ds.getIncludedFiles(), entitiesFieldMap); + } + } + + private List scanInWorkspace(String filePath, EntitiesFieldMap entitiesFieldMap) { + List files = new ArrayList<>(); + for (String include : new String[] {filePath}) { + try { + files.addAll(Arrays.asList(workspace.list(include))); + } catch (Exception e) { + logger.error(e.getMessage()); + run.setResult(Result.FAILURE); + } + } + if (files.size() < 1) { + logger.info("No Test Report found in workspace: " + workspace); + } + logger.info(files.size() + " test result file found in workspace: " + workspace); + return readWorkspace(files, entitiesFieldMap); + } + + private List readWorkspace(List files, EntitiesFieldMap entitiesFieldMap) { + List xmlResultEntities = new ArrayList<>(); + for (FilePath file : files) { + try { + TestSetReader tr = new TestSetReader(file, entitiesFieldMap); + xmlResultEntities.addAll(tr.readTestsets()); + } catch (Exception e) { + logger.error(e.getMessage()); + e.printStackTrace(); + run.setResult(Result.FAILURE); + } + } + return xmlResultEntities; + } + + private List readBuildPath(String[] files, EntitiesFieldMap entitiesFieldMap) { + List xmlResultEntities = new ArrayList<>(); + for (String fileName : files) { + String fullpath = run.getRootDir().getAbsolutePath() + File.separator + fileName; + try { + TestSetReader tr = new TestSetReader(fullpath, entitiesFieldMap); + xmlResultEntities.addAll(tr.readTestsets()); + } catch (Exception e) { + logger.error(e.getMessage()); + e.printStackTrace(); + run.setResult(Result.FAILURE); + } + } + return xmlResultEntities; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XpathReader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XpathReader.java new file mode 100644 index 0000000000..029cb8084d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/XpathReader.java @@ -0,0 +1,92 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader; + +import hudson.FilePath; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.File; +import java.io.IOException; + +public class XpathReader { + + private XPath xPath; + private Document doc; + + public XpathReader(FilePath filePath) throws IOException, InterruptedException, ParserConfigurationException, + SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + builder = factory.newDocumentBuilder(); + doc = builder.parse(filePath.read()); + xPath = XPathFactory.newInstance().newXPath(); + } + + public XpathReader(String filePath) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + builder = factory.newDocumentBuilder(); + doc = builder.parse(new File(filePath)); + xPath = XPathFactory.newInstance().newXPath(); + } + + public XpathReader(File file) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + builder = factory.newDocumentBuilder(); + doc = builder.parse(file); + xPath = XPathFactory.newInstance().newXPath(); + } + + public Node getDoc() { + return doc; + } + + public NodeList getNodeListFromNode(String xpath, Node node) throws XPathExpressionException { + return (NodeList) xPath.compile(xpath).evaluate(node, XPathConstants.NODESET); + } + + public String getValueFromNode(String xpath, Node node) throws XPathExpressionException { + return (String) xPath.compile(xpath).evaluate(node, XPathConstants.STRING); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/EntitiesFieldMapLoader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/EntitiesFieldMapLoader.java new file mode 100644 index 0000000000..571b74b4f1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/EntitiesFieldMapLoader.java @@ -0,0 +1,182 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader.configloader; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.service.CustomizationService; +import com.microfocus.application.automation.tools.commonResultUpload.service.UDFTranslator; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.EntitiesFieldMap; + +import java.io.IOException; +import java.util.Map; + +import static com.microfocus.application.automation.tools.results.service.almentities.AlmTest.TEST_TYPE; +import static com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet.TESTSET_SUB_TYPE_ID; + +public class EntitiesFieldMapLoader { + + private static final String ILLEGAL = "Illegal "; + private static final String[] TEST_SET_REQUIRED_FIELDS = new String[]{"root", "name", TESTSET_SUB_TYPE_ID}; + private static final String[] RUN_REQUIRED_FIELDS = new String[]{"root"}; + private static String[] testRquiredFields; + + private EntitiesFieldMapLoader() { + + } + + public static EntitiesFieldMap load(String yamlContent, CommonUploadLogger logger, CustomizationService cs, boolean isCreateNewTest) { + if (isCreateNewTest) { + testRquiredFields = new String[]{"root", "name", TEST_TYPE}; + } else { + testRquiredFields = new String[]{"root", TEST_TYPE}; + } + return load(yamlContent, logger, cs); + } + + public static EntitiesFieldMap load(String yamlContent, CommonUploadLogger logger, CustomizationService cs) { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + EntitiesFieldMap entitiesFieldMap; + try { + entitiesFieldMap = mapper.readValue(yamlContent, EntitiesFieldMap.class); + } catch (IOException | RuntimeException e) { + logger.error("Field mapping is not in right format. " + e.getMessage()); + return null; + } + if (!validateFieldMapping(entitiesFieldMap, logger, cs)) { + return null; + } + return entitiesFieldMap; + } + + private static boolean validateFieldMapping(EntitiesFieldMap entitiesFieldMap, + CommonUploadLogger logger, CustomizationService cs) { + if (!checkRequiredFields(entitiesFieldMap, logger)) { + return false; + } + if (!checkEntitiesFieldName(cs, entitiesFieldMap, logger)) { + return false; + } + return checkEntitiesSubtype(cs, entitiesFieldMap, logger); + } + + private static boolean checkEntitiesSubtype(CustomizationService cs, EntitiesFieldMap entitiesFieldMap, + CommonUploadLogger logger) { + if (!checkSubtypeIdLlegal(cs, entitiesFieldMap.getTestset(), CustomizationService.TEST_SET_ENTITY_NAME, logger)) { + return false; + } + return checkSubtypeIdLlegal(cs, entitiesFieldMap.getTest(), CustomizationService.TEST_ENTITY_NAME, logger); + } + + private static boolean checkSubtypeIdLlegal(CustomizationService cs, Map fieldMap, + String entityName, CommonUploadLogger logger) { + String subtypeId = fieldMap.get("subtype-id"); + subtypeId = subtypeId.substring(2, subtypeId.length()); + Map subtypeMap = cs.getEntitySubTypes(entityName); + if (!containsValue(subtypeId, subtypeMap)) { + logger.error(ILLEGAL + entityName + " subtype-id: " + subtypeId); + return false; + } + return true; + } + + private static boolean checkRequiredFields(EntitiesFieldMap entitiesFieldMap, CommonUploadLogger logger) { + for (String field : TEST_SET_REQUIRED_FIELDS) { + if (!entitiesFieldMap.getTestset().containsKey(field)) { + logger.error(field + " should be set in test-set's field mapping."); + return false; + } + } + for (String field : testRquiredFields) { + if (!entitiesFieldMap.getTest().containsKey(field)) { + logger.error(field + " should be set in test's field mapping."); + return false; + } + } + for (String field : RUN_REQUIRED_FIELDS) { + if (!entitiesFieldMap.getRun().containsKey(field)) { + logger.error(field + " should be set in run's field mapping."); + return false; + } + } + return true; + } + + private static boolean checkEntitiesFieldName(CustomizationService cs, EntitiesFieldMap entitiesFieldMap, + CommonUploadLogger logger) { + if (!checkFieldNameLegal(cs, CustomizationService.TEST_SET_ENTITY_NAME, + entitiesFieldMap.getTestset(), logger)) { + return false; + } + if (!checkFieldNameLegal(cs, CustomizationService.TEST_ENTITY_NAME, + entitiesFieldMap.getTest(), logger)) { + return false; + } + return checkFieldNameLegal(cs, CustomizationService.RUN_ENTITY_NAME, + entitiesFieldMap.getRun(), logger); + } + + private static boolean checkFieldNameLegal(CustomizationService cs, + String entityName, Map fieldMap, + CommonUploadLogger logger) { + Map entityFields = cs.getEntityFields(entityName); + for (String fieldName : fieldMap.keySet()) { + // Check if field name exists + if (!containsValue(fieldName, entityFields) && !fieldName.equals("root") && !fieldName.contains("|")) { + logger.error(ILLEGAL + entityName + " field name: " + fieldName); + return false; + } + // Check if field label exists + if (fieldName.startsWith(UDFTranslator.UDF_PREFIX)) { + String label = fieldName.substring( + fieldName.indexOf(UDFTranslator.UDF_PREFIX) + UDFTranslator.UDF_PREFIX.length()); + if (!entityFields.containsKey(label)) { + logger.error(ILLEGAL + entityName + " label: " + fieldName); + return false; + } + } + } + return true; + } + + private static boolean containsValue(String value, Map map) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (value.equals(map.get(key))) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/RunStatusMapLoader.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/RunStatusMapLoader.java new file mode 100644 index 0000000000..e32deb2355 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/configloader/RunStatusMapLoader.java @@ -0,0 +1,60 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader.configloader; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.microfocus.application.automation.tools.commonResultUpload.CommonUploadLogger; +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model.RunStatusMap; + +import java.io.IOException; + +public class RunStatusMapLoader { + + private RunStatusMapLoader() { + + } + + public static RunStatusMap load(String yamlContent, CommonUploadLogger logger) { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + RunStatusMap runStatusMap; + + try { + runStatusMap = mapper.readValue(yamlContent, RunStatusMap.class); + } catch (IOException e) { + logger.error("Run status mapping is not in right format. " + e.getMessage()); + return null; + } + return runStatusMap; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/EntitiesFieldMap.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/EntitiesFieldMap.java new file mode 100644 index 0000000000..54d1f92d24 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/EntitiesFieldMap.java @@ -0,0 +1,77 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model; + +import java.util.Map; + +public class EntitiesFieldMap { + + private Map testset; + private Map test; + private Map run; + + private EntitiesFieldMap() { + + } + + public Map getTestset() { + return testset; + } + public void setTestset(Map testset) { + this.testset = testset; + } + + public Map getTest() { + return test; + } + public void setTest(Map test) { + this.test = test; + } + + public Map getRun() { + return run; + } + public void setRun(Map run) { + this.run = run; + } + + public Map getNextConfigMap(Map map) { + if (map.hashCode() == testset.hashCode()) { + return test; + } else if (map.hashCode() == test.hashCode()) { + return run; + } else { + return null; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/RunStatusMap.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/RunStatusMap.java new file mode 100644 index 0000000000..cb66107fbc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/RunStatusMap.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model; + +import java.util.Map; + +public class RunStatusMap { + + private Map status; + public Map getStatus() { + return status; + } + public void setStatus(Map status) { + this.status = status; + } + + private RunStatusMap() { + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/XmlResultEntity.java b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/XmlResultEntity.java new file mode 100644 index 0000000000..ee1c4445a8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/commonResultUpload/xmlreader/model/XmlResultEntity.java @@ -0,0 +1,58 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.commonResultUpload.xmlreader.model; + +import java.util.List; +import java.util.Map; + +public class XmlResultEntity { + + private Map valueMap; + private List subEntities; + + public Map getValueMap() { + return valueMap; + } + + public void setValueMap(Map valueMap) { + this.valueMap = valueMap; + } + + public List getSubEntities() { + return subEntities; + } + + public void setSubEntities(List subEntities) { + this.subEntities = subEntities; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel.java b/src/main/java/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel.java new file mode 100644 index 0000000000..caa64a2e02 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel.java @@ -0,0 +1,77 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.lr.model; + +import com.microfocus.application.automation.tools.lr.Messages; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; +import javax.annotation.Nonnull; + +/** + * An additional attribute in the controller runtime's settings consists of: name, value and + * description (optional) + * + */ +public class AdditionalAttributeModel extends AbstractDescribableImpl { + private String name; + private String value; + private String description; + + @DataBoundConstructor + 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; + } + + @Extension + public static class DescriptorImpl extends Descriptor + { + @Nonnull + public String getDisplayName() { return Messages.AdditionalAttributeModel(); } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel.java b/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel.java new file mode 100644 index 0000000000..65e7d0bd5f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.lr.model; + +import com.microfocus.application.automation.tools.lr.Messages; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.EnvVars; +import org.kohsuke.stapler.DataBoundConstructor; +import org.apache.commons.lang.StringUtils; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Properties; + +/** + * The Controller's Api call requires the name of the script and an xml string which + * will be generated by HpToolsLauncher based on the specified additional attributes + */ +public class ScriptRTSModel extends AbstractDescribableImpl { + private String scriptName; + private List additionalAttributes; + static int additionalAttributeCounter = 1; + + @DataBoundConstructor + public ScriptRTSModel(String scriptName, List additionalAttributes) { + this.scriptName = scriptName; + this.additionalAttributes = additionalAttributes; + } + + public List getAdditionalAttributes() { + return additionalAttributes; + } + + public String getScriptName() { + return scriptName; + } + + + /** + * Adds additional attributes to the props file containing: + * script name, additional attribute name, value and description + * + * @param props + * @param scriptName + */ + void addAdditionalAttributesToPropsFile(Properties props, String scriptName, EnvVars envVars) + { + for (AdditionalAttributeModel additionalAttribute: this.additionalAttributes) { + if (!StringUtils.isEmpty(additionalAttribute.getName())) { + props.put("AdditionalAttribute" + additionalAttributeCounter, + scriptName + ";" + + additionalAttribute.getName() + ";" + + envVars.expand(additionalAttribute.getValue()) + ";" + + additionalAttribute.getDescription() + ); + additionalAttributeCounter++; + } + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() { return Messages.ScriptRTSModel(); } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel.java b/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel.java new file mode 100644 index 0000000000..19a7ebfaf1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel.java @@ -0,0 +1,90 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.lr.model; + +import com.microfocus.application.automation.tools.lr.Messages; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.EnvVars; +import org.kohsuke.stapler.DataBoundConstructor; +import org.apache.commons.lang.StringUtils; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Properties; + +/** + * Use case: users can add runtime settings to scripts from jenkins (currently only additional + * attributes) + * This model will be sent to HpToolsLauncher (by saving it in the props.txt file) which parses + * the scripts and performs api calls on controller + * + * Describes a container for scripts and their associated runtime settings + */ +public class ScriptRTSSetModel extends AbstractDescribableImpl { + private List scripts; + + @DataBoundConstructor + public ScriptRTSSetModel(List scripts) { + this.scripts = scripts; + } + + public List getScripts() { + return scripts; + } + + /** + * Adds scripts to the props file containing script name + * + * @param props + */ + public void addScriptsToProps(Properties props, EnvVars envVars) { + int scriptCounter = 1; + + ScriptRTSModel.additionalAttributeCounter = 1; + for (ScriptRTSModel script: this.scripts) { + if (!StringUtils.isEmpty(script.getScriptName())) { + props.put("ScriptRTS" + scriptCounter, script.getScriptName()); + script.addAdditionalAttributesToPropsFile(props, script.getScriptName(), envVars); + scriptCounter++; + } + } + } + + @Extension + public static class DescriptorImpl extends Descriptor + { + @Nonnull + public String getDisplayName() { return Messages.ScriptRTSSetModel(); } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel.java b/src/main/java/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel.java new file mode 100644 index 0000000000..2b895fdf48 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel.java @@ -0,0 +1,103 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.lr.model; + +import com.microfocus.application.automation.tools.lr.Messages; +import hudson.Extension; +import hudson.util.FormValidation; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.BooleanUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; +import javax.annotation.Nonnull; +import java.util.Properties; + +public class SummaryDataLogModel extends AbstractDescribableImpl { + private boolean logVusersStates; + private boolean logErrorCount; + private boolean logTransactionStatistics; + private String pollingInterval; + + @DataBoundConstructor + public SummaryDataLogModel(boolean logVusersStates, boolean logErrorCount, boolean logTransactionStatistics, String pollingInterval) { + this.logVusersStates = logVusersStates; + this.logErrorCount = logErrorCount; + this.logTransactionStatistics = logTransactionStatistics; + this.pollingInterval = pollingInterval; + } + + public boolean getLogVusersStates() { + return logVusersStates; + } + + public boolean getLogErrorCount() { + return logErrorCount; + } + + public boolean getLogTransactionStatistics() { + return logTransactionStatistics; + } + + public String getPollingInterval() { return pollingInterval; } + + public void addToProps(Properties props) + { + if (StringUtils.isEmpty(pollingInterval)) + { + pollingInterval = "30"; + } + + props.put("SummaryDataLog", + BooleanUtils.toInteger(logVusersStates) + ";" + + BooleanUtils.toInteger(logErrorCount) + ";" + + BooleanUtils.toInteger(logTransactionStatistics) + ";" + + Integer.parseInt(pollingInterval) + ); + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() { return Messages.SummaryDataLogModel(); } + + public FormValidation doCheckPollingInterval(@QueryParameter String value) { + if (!StringUtils.isNumeric(value)) { + return FormValidation.error("Polling Interval must be a number"); + } + + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep.java b/src/main/java/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep.java new file mode 100644 index 0000000000..d110638846 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.lr.run; + +import com.microfocus.application.automation.tools.common.utils.HealthAnalyzerCommon; +import com.microfocus.application.automation.tools.common.utils.OperatingSystem; +import com.microfocus.application.automation.tools.common.model.HealthAnalyzerModel; +import com.microfocus.application.automation.tools.common.model.VariableWrapper; +import com.microfocus.application.automation.tools.common.model.VariableListWrapper; +import com.microfocus.application.automation.tools.lr.Messages; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.util.List; + +public class HealthAnalyzerLrStep extends HealthAnalyzerModel { + private static final String LR_REGISTRY_PATH = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Mercury Interactive\\LoadRunner\\CurrentVersion"; + private static final transient HealthAnalyzerCommon healthAnalyzerCommon = + new HealthAnalyzerCommon(Messages.ProductName()); + private final boolean checkLrInstallation; + private final boolean checkOsVersion; + private final VariableListWrapper checkFiles; + + + @DataBoundConstructor + public HealthAnalyzerLrStep(boolean checkLrInstallation, boolean checkOsVersion, VariableListWrapper checkFiles) { + this.checkLrInstallation = checkLrInstallation; + this.checkOsVersion = checkOsVersion; + this.checkFiles = checkFiles; + } + + public boolean isCheckOsVersion() { + return checkOsVersion; + } + + public VariableListWrapper getCheckFiles() { + return checkFiles; + } + + public boolean isFilesExist() { + return checkFiles != null; + } + + public List getFilesList() { + return checkFiles != null ? checkFiles.getFilesList() : null; + } + + public boolean isCheckLrInstallation() { + return checkLrInstallation; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException { + healthAnalyzerCommon.ifCheckedPerformWindowsInstallationCheck(LR_REGISTRY_PATH, checkLrInstallation, workspace); + healthAnalyzerCommon.ifCheckedPerformFilesExistenceCheck(getFilesList(), isFilesExist(), workspace); + healthAnalyzerCommon.ifCheckedPerformOsCheck(OperatingSystem.WINDOWS, checkOsVersion, workspace); + } + + @Extension + public static class DescriptorImpl extends HealthAnalyzerModelDescriptor { + @Override + public String toString() { + return "Info in DescriptorImpl at HealthAnalyzerLrStep"; + } + + @Nonnull + @Override + public String getDisplayName() { + return Messages.ProductName(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/AuthType.java b/src/main/java/com/microfocus/application/automation/tools/mc/AuthType.java new file mode 100644 index 0000000000..baa3c889f6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/AuthType.java @@ -0,0 +1,18 @@ +package com.microfocus.application.automation.tools.mc; + +public enum AuthType { + BASE, + TOKEN, + UNKNOWN; + + public static AuthType fromString(String value) { + switch(value.toLowerCase()) { + case "base": + return AuthType.BASE; + case "token": + return AuthType.TOKEN; + default: + return AuthType.UNKNOWN; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/Constants.java b/src/main/java/com/microfocus/application/automation/tools/mc/Constants.java new file mode 100644 index 0000000000..0c1aba7b20 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/Constants.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.mc; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 5/13/16 + * Time: 2:07 PM + * To change this template use File | Settings | File Templates. + */ +public class Constants { + public final static String BOUNDARYSTR = "randomstring"; + public final static String DATA = "data"; + public final static String APP_UPLOAD = "/rest/v2/apps"; // make sure unpacked app is uploaded in case of failure during instrumentation + public final static String CONTENT_TYPE_DOWNLOAD_VALUE = "multipart/form-data; boundary=----"; + public final static String FILENAME = "filename"; + public static final String LOGIN_SECRET = "x-hp4msecret"; + public static final String SPLIT_COMMA = ";"; + public static final String JSESSIONID = "JSESSIONID"; + public static final String LWSSO_COOKIE_KEY = "LWSSO_COOKIE_KEY"; + public static final String OAUTH2_COOKIE_KEY = "OAUTH2_COOKIE_KEY"; + public static final String ACCEPT = "Accept"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String COOKIE = "Cookie"; + public static final String COOKIES = "Cookies"; + public static final String SET_COOKIE = "Set-Cookie"; + public static final String EQUAL = "="; + public static final String LOGIN_URL = "/rest/client/login"; + public static final String LOGIN_URL_OAUTH = "/rest/client/v2/oauth2/login"; + public static final String OAUTH_TOKEN_URL = "/rest/oauth2/token"; + public static final String CREATE_JOB_URL = "/rest/job/createTempJob"; + public static final String GET_JOB_UEL = "/rest/job/"; + public static final String GET_ALL_WORKSPACES_URL = "/rest/v2/workspaces"; + public static final String GET_WORKSPACE_URL = "/rest/v2/workspaces"; + public static final String GET_ADMIN_SETTINGS_URL = "/rest/v2/adminSettings"; + public static final String GET_BROWSER_LAB_URL = "/rest/v2/browser-lab/uftone/templates"; + public final static String ICON = "icon"; + public final static String JSESSIONID_EQ = "JSESSIONID="; + public final static String TENANT_COOKIE = "TENANT_ID_COOKIE"; + public final static String ACCESS_TOKEN = "access_token"; + public final static String TOKEN_TYPE = "token_type"; + public final static String SHARED_ASSETS = "Shared assets"; + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/HttpResponse.java b/src/main/java/com/microfocus/application/automation/tools/mc/HttpResponse.java new file mode 100644 index 0000000000..4c95157035 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/HttpResponse.java @@ -0,0 +1,103 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.mc; + +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +public class HttpResponse { + + private Map> headers; + private String strCookies; + private JSONObject jsonObject; + private JSONArray jsonArray; + + public HttpResponse() { + + } + + public HttpResponse(Map> headers, JSONObject jsonObject) { + this.headers = headers; + this.jsonObject = jsonObject; + } + + public void setHeaders(Map> headers) { + this.headers = headers; + } + + public void setJsonObject(JSONObject jsonObject) { + this.jsonObject = jsonObject; + } + + public void setCookiesString(String cookies) { + this.strCookies = cookies; + } + + public Map> getHeaders() { + return headers; + } + + public JSONObject getJsonObject() { + return jsonObject; + } + + public JSONArray getJsonArray() { + return jsonArray; + } + + public void setJsonArray(JSONArray jsonArray) { + this.jsonArray = jsonArray; + } + + public String getCookiesAsString() { + if (StringUtils.isBlank(strCookies)) + { + StringBuilder sb = new StringBuilder(); + List cookies = headers.get(Constants.SET_COOKIE); + if (cookies != null) + for (String cookie : cookies) { + int eqIdx = cookie.indexOf('='); + int semicolonIdx = cookie.indexOf(';'); + String key = cookie.substring(0, eqIdx); + String val = cookie.substring(eqIdx + 1, semicolonIdx); + sb.append(key).append("=").append(val).append(";"); + } + strCookies = sb.toString(); + } + return strCookies; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/HttpUtils.java b/src/main/java/com/microfocus/application/automation/tools/mc/HttpUtils.java new file mode 100644 index 0000000000..c6045d9b04 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/HttpUtils.java @@ -0,0 +1,289 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.mc; + +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; +import org.apache.commons.lang.StringUtils; + +import java.io.*; +import java.net.*; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class HttpUtils { + + public static final String POST = "POST"; + public static final String GET = "GET"; + + private HttpUtils() { + + } + + public static HttpResponse doPost(ProxyInfo proxyInfo, String url, Map headers, byte[] data) { + HttpResponse response = null; + try { + response = doHttp(proxyInfo, POST, url, null, headers, data, false); + } catch (Exception e) { + e.printStackTrace(); + } + return response; + } + + public static HttpResponse doPost(ProxyInfo proxyInfo, String url, Map headers, byte[] data, boolean useCookieManager) { + HttpResponse response = null; + try { + response = doHttp(proxyInfo, POST, url, null, headers, data, useCookieManager); + } catch (Exception e) { + e.printStackTrace(); + } + return response; + } + + public static HttpResponse doGet(ProxyInfo proxyInfo, String url, Map headers, String queryString) { + HttpResponse response = null; + try { + response = doHttp(proxyInfo, GET, url, queryString, headers, null, false); + } catch (Exception e) { + e.printStackTrace(); + } + return response; + } + + private static HttpResponse doHttp(ProxyInfo proxyInfo, String requestMethod, String connectionUrl, String queryString, Map headers, byte[] data, boolean useCookieManager) throws IOException { + HttpResponse response = new HttpResponse(); + + if ((queryString != null) && !queryString.isEmpty()) { + connectionUrl += "?" + queryString; + } + + URL url = new URL(connectionUrl); + CookieManager cookieManager = null; + if (useCookieManager) { + cookieManager = new CookieManager(); + CookieHandler.setDefault(cookieManager); + } + + HttpURLConnection connection = (HttpURLConnection) openConnection(proxyInfo, url); + + connection.setRequestMethod(requestMethod); + + setConnectionHeaders(connection, headers); + + if (data != null && data.length > 0) { + connection.setDoOutput(true); + try { + OutputStream out = connection.getOutputStream(); + out.write(data); + out.flush(); + out.close(); + } catch (Throwable cause) { + cause.printStackTrace(); + } + } + + connection.connect(); + + int responseCode = connection.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + InputStream inputStream = connection.getInputStream(); + Object object = convertStreamToObject(inputStream); + response.setHeaders(connection.getHeaderFields()); + if (null == object) { + System.out.println(requestMethod + " " + connectionUrl + " return is null."); + } else if (object instanceof JSONObject) { + response.setJsonObject((JSONObject) object); + } else if (object instanceof JSONArray) { + response.setJsonArray((JSONArray) object); + } else if(object instanceof Boolean){ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("error", !((Boolean) object).booleanValue()); + response.setJsonObject(jsonObject); + } + if (useCookieManager) { + response.setCookiesString(getCookiesString(cookieManager)); + } + } else { + System.out.println(requestMethod + " " + connectionUrl + " failed with response code:" + responseCode); + } + connection.disconnect(); + + return response; + } + + private static String getCookiesString(CookieManager cookieManager) { + StringBuilder ret = new StringBuilder(); + if (cookieManager != null) { + List cookies = cookieManager.getCookieStore().getCookies(); + for (HttpCookie cookie : cookies) { + //TODO review each cookie !!!!!!!!!!!!!!!!!!!! + ret.append(cookie.getName()).append("=").append(cookie.getValue()).append(";"); + } + } + return ret.toString(); + } + + + private static URLConnection openConnection(final ProxyInfo proxyInfo, URL _url) throws IOException { + + Proxy proxy = null; + + if (proxyInfo != null && !proxyInfo.isEmpty()) { + try { + int port = Integer.parseInt(proxyInfo.port.trim()); + proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyInfo.host, port)); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + if (proxy != null && !proxyInfo.isEmpty()) { + Authenticator authenticator = new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(proxyInfo.userName, proxyInfo.password.toCharArray()); //To change body of overridden methods use File | Settings | File Templates. + } + }; + + Authenticator.setDefault(authenticator); + } + + if (proxy == null) { + return _url.openConnection(); + } + + + return _url.openConnection(proxy); + } + + + private static void setConnectionHeaders(HttpURLConnection connection, Map headers) { + + if (connection != null && headers != null && headers.size() != 0) { + Iterator> headersIterator = headers.entrySet().iterator(); + while (headersIterator.hasNext()) { + Map.Entry header = headersIterator.next(); + connection.setRequestProperty(header.getKey(), header.getValue()); + } + } + + } + + private static Object convertStreamToObject(InputStream inputStream) { + Object obj = null; + + if (inputStream != null) { + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + StringBuffer res = new StringBuffer(); + String line; + while ((line = reader.readLine()) != null) { + res.append(line); + } + obj = JSONValue.parseStrict(res.toString()); + } catch (ClassCastException e) { + System.out.println("WARN::INVALIDE JSON Object" + e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + } + return obj; + } + + + public static ProxyInfo setProxyCfg(String host, String port, String userName, String password) { + + return new ProxyInfo(host, port, userName, password); + } + + public static ProxyInfo setProxyCfg(String host, String port) { + + ProxyInfo proxyInfo = new ProxyInfo(); + + proxyInfo.host = host; + proxyInfo.port = port; + + return proxyInfo; + } + + public static ProxyInfo setProxyCfg(String address, String userName, String password) { + ProxyInfo proxyInfo = new ProxyInfo(); + + if (address != null) { + if (address.endsWith("/")) { + int end = address.lastIndexOf("/"); + address = address.substring(0, end); + } + + int index = address.lastIndexOf(':'); + if (index > 0) { + proxyInfo.host = address.substring(0, index); + proxyInfo.port = address.substring(index + 1, address.length()); + } else { + proxyInfo.host = address; + proxyInfo.port = "80"; + } + } + proxyInfo.userName = userName; + proxyInfo.password = password; + + return proxyInfo; + } + + static class ProxyInfo { + String host; + String port; + String userName; + String password; + + public ProxyInfo() { + + } + + public ProxyInfo(String host, String port, String userName, String password) { + this.host = host; + this.port = port; + this.userName = userName; + this.password = password; + } + + public boolean isEmpty() { + return StringUtils.isEmpty(host) || StringUtils.isEmpty(port) || StringUtils.isEmpty(userName) || StringUtils.isEmpty(password); + } + + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/JobConfigurationProxy.java b/src/main/java/com/microfocus/application/automation/tools/mc/JobConfigurationProxy.java new file mode 100644 index 0000000000..38ea1975e4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/JobConfigurationProxy.java @@ -0,0 +1,616 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.mc; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.model.AuthModel; +import com.microfocus.application.automation.tools.model.ProxySettings; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; + +/** + * communicate with MC servers, login to MC, upload application to MC server, create job, get job details. + */ +public class JobConfigurationProxy { + + private static final String TOKEN = "token"; + private static final String EXTRA_APPS = "extraApps"; + private static final String INSTRUMENTED = "instrumented"; + private static final String PACKAGED = "Packaged"; + private static final String NOT_PACKAGED = "Not Packaged"; + private static JobConfigurationProxy instance = null; + + private JobConfigurationProxy() { + } + + public static JobConfigurationProxy getInstance() { + if (instance == null) { + instance = new JobConfigurationProxy(); + } + return instance; + } + + //Login to MC + public JSONObject loginToMC(String mcUrl, AuthModel authModel, ProxySettings proxy) { + + JSONObject returnObject = new JSONObject(); + try { + Map headers = getRequestHeaders(); + + JSONObject sendObject = new JSONObject(); + if (null == proxy) { + proxy = new ProxySettings(); + } + HttpResponse response; + AuthType authType = authModel.getAuthType(); + if (authType == AuthType.BASE) { + String tempUsername = authModel.getMcUserName(); + if (!StringUtils.isNullOrEmpty(authModel.getMcTenantId())) { + tempUsername += "#" + authModel.getMcTenantId(); + } + sendObject.put("name", tempUsername); + sendObject.put("password", authModel.getMcPassword()); + sendObject.put("accountName", "default"); + response = doPost(proxy, mcUrl + Constants.LOGIN_URL, headers, sendObject); + } else if (Oauth2TokenUtil.isValid(authModel.getMcExecToken())) { + sendObject = Oauth2TokenUtil.getJSONObject(); + response = doPost(proxy, mcUrl + Constants.LOGIN_URL_OAUTH, headers, sendObject); + } else { + System.out.println("ERROR:: oauth token is invalid."); + return returnObject; + } + return parseLoginResponse(response, authType); + } catch (Exception e) { + e.printStackTrace(); + } + return returnObject; + } + + private JSONObject generateNewToken(String mcUrl, String accessKey, ProxySettings proxy) { + + try { + Map headers = getRequestHeaders(); + + if (null == proxy) { + proxy = new ProxySettings(); + } + HttpResponse response; + if (Oauth2TokenUtil.isValid(accessKey)) { + JSONObject sendObject = Oauth2TokenUtil.getJSONObject(); + String url = mcUrl + Constants.OAUTH_TOKEN_URL; + response = doPost(proxy, url, headers, sendObject); + return parseTokenResponse(response, AuthType.TOKEN); + } + System.out.println("ERROR: oauth token is invalid."); + return null; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private Map getRequestHeaders() { + Map headers = new HashMap<>(); + headers.put(Constants.ACCEPT, "application/json"); + headers.put(Constants.CONTENT_TYPE, "application/json;charset=UTF-8"); + return headers; + } + private JSONObject parseLoginResponse(HttpResponse response, AuthType authType) { + JSONObject returnObject = new JSONObject(); + if (response == null || response.getHeaders() == null) { + return null; + }else if(response.getJsonObject() != null && response.getJsonObject().containsKey("error") && response.getJsonObject().getAsString("error").equals("true")){ + return null; + } + Map> headerFields = response.getHeaders(); + List hp4mSecretList = headerFields.get(Constants.LOGIN_SECRET); + if (hp4mSecretList != null && !hp4mSecretList.isEmpty() && !StringUtils.isNullOrEmpty(hp4mSecretList.get(0))) { + returnObject.put(Constants.LOGIN_SECRET, hp4mSecretList.get(0)); + } + if (authType == AuthType.TOKEN && headerFields.containsKey(Constants.SET_COOKIE)) { + List cookies = headerFields.get(Constants.SET_COOKIE); + if (cookies != null && !cookies.isEmpty()) { + for (String cookie : cookies) { + if (cookie.startsWith(Constants.OAUTH2_COOKIE_KEY)) { + returnObject.put(Constants.OAUTH2_COOKIE_KEY, getCookieValue(cookie, Constants.OAUTH2_COOKIE_KEY)); + break; + } + } + } + } + + returnObject.put(Constants.COOKIES, response.getCookiesAsString()); + return returnObject; + } + + private JSONObject parseTokenResponse(HttpResponse response, AuthType authType) { + JSONObject returnObject = parseLoginResponse(response, authType); + if (returnObject != null) { + JSONObject body = response.getJsonObject(); + if (body != null) { + returnObject.put(Constants.ACCESS_TOKEN, body.getAsString(Constants.ACCESS_TOKEN)); + returnObject.put(Constants.TOKEN_TYPE, body.getAsString(Constants.TOKEN_TYPE)); + } + } + + return returnObject; + } + + //check workspace exist or not in MC + public JSONObject isWorkspaceExist(Map headers, String mcUrl, ProxySettings proxy, String appUploadWorkspace) throws IOException { + if (null == proxy) { + proxy = new ProxySettings(); + } + String getWorkspaceUrl = mcUrl + Constants.GET_WORKSPACE_URL; + if(!StringUtils.isNullOrEmpty(getWorkspaceUrl)){ + getWorkspaceUrl += (String.format("/%s",appUploadWorkspace)); + } + HttpUtils.ProxyInfo proxyInfo = HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doGet(proxyInfo, getWorkspaceUrl, headers, null); + if (response != null && response.getJsonObject() != null) { + return response.getJsonObject(); + } + return null; + } + + //check signing service + public String isSigningServiceEnabled(Map headers, String mcUrl, ProxySettings proxy) throws IOException { + if (null == proxy) { + proxy = new ProxySettings(); + } + String getAdminSettingUrl = mcUrl + Constants.GET_ADMIN_SETTINGS_URL; + if(!StringUtils.isNullOrEmpty(getAdminSettingUrl)){ + getAdminSettingUrl += (String.format("/%s","PACKAGING_IOS")); + } + HttpUtils.ProxyInfo proxyInfo = HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doGet(proxyInfo, getAdminSettingUrl, headers, null); + if (response != null && response.getJsonArray() != null) { + for (int i = 0; i < response.getJsonArray().size(); i++) { + JSONObject setting = (JSONObject) response.getJsonArray().get(i); + if(setting.getAsString("name").equals("IOS_PACKAGER_ENABLE")){ + return setting.getAsString("value"); + } + } + } + return null; + } + + //login into MC server + public Map login(String mcUrl, AuthModel authModel, ProxySettings proxy){ + Map headers = new HashMap<>(); + try{ + if (null == proxy) { + proxy = new ProxySettings(); + } + JSONObject loginJson = loginToMC(mcUrl, authModel, proxy); + headers = initHeaders(authModel, loginJson); + }catch (Exception e) { + e.printStackTrace(); + } + + return headers; + } + + //upload app to MC + public JSONObject upload(Map headers, String mcUrl, ProxySettings proxy, String appPath, String appUploadWorkspace) throws IOException { + File appFile = new File(appPath); + String uploadUrl = mcUrl + Constants.APP_UPLOAD; + String signingServiceEnabled = this.isSigningServiceEnabled(headers, mcUrl, proxy); + if(!StringUtils.isNullOrEmpty(signingServiceEnabled) && signingServiceEnabled.equalsIgnoreCase("true")){ + uploadUrl += "?asyncInstrumentation=false&instrument=true&resign=true&isAppUploadPage=true"; + }else{ + uploadUrl += "?asyncInstrumentation=false&instrument=true&resign=false&isAppUploadPage=true"; + } + if(!StringUtils.isNullOrEmpty(appUploadWorkspace)){ + uploadUrl += (String.format("&workspaceId=%s",appUploadWorkspace)); + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + StringBuilder content = new StringBuilder(); + content.append("\r\n").append("------").append(Constants.BOUNDARYSTR).append("\r\n"); + content.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + appFile.getName() + "\"\r\n"); + content.append("Content-Type: application/octet-stream\r\n\r\n"); + + outputStream.write(content.toString().getBytes()); + + try (FileInputStream in = new FileInputStream(appFile)) { + byte[] b = new byte[1024]; + int i = 0; + while ((i = in.read(b)) != -1) { + outputStream.write(b, 0, i); + } + } + + outputStream.write(("\r\n------" + Constants.BOUNDARYSTR + "--\r\n").getBytes()); + + byte[] bytes = outputStream.toByteArray(); + + outputStream.close(); + + if (null == proxy) { + proxy = new ProxySettings(); + } + + headers.put(Constants.CONTENT_TYPE, Constants.CONTENT_TYPE_DOWNLOAD_VALUE + Constants.BOUNDARYSTR); + headers.put(Constants.FILENAME, appFile.getName()); + + HttpUtils.ProxyInfo proxyInfo = HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doPost(proxyInfo, uploadUrl, headers, bytes); + + if (response != null && response.getJsonObject() != null) { + return response.getJsonObject(); + } + return null; + } + + //get all workspaces from MC + public JSONArray getAllMcWorkspaces(String mcUrl, AuthModel authModel, ProxySettings proxy) throws IOException { + try { + Map headers = login(mcUrl, authModel, proxy); + HttpUtils.ProxyInfo proxyInfo = proxy == null ? null : HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doGet(proxyInfo, mcUrl + Constants.GET_ALL_WORKSPACES_URL, headers, "includeSharedAssets=true"); + if (response != null && response.getJsonArray() != null) { + return response.getJsonArray(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + //create one temp job + public String createTempJob(String mcUrl, AuthModel authModel, ProxySettings proxy) { + try { + JSONObject loginJson = loginToMC(mcUrl, authModel, proxy); + + Map headers = initHeaders(authModel,loginJson); + if (headers != null) { + HttpUtils.ProxyInfo proxyInfo = proxy == null ? null : HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doGet(proxyInfo, mcUrl + Constants.CREATE_JOB_URL, headers, null); + + if (response != null && response.getJsonObject() != null) { + JSONObject job = response.getJsonObject(); + if (job != null && job.get("data") != null) { + JSONObject data = (JSONObject) job.get("data"); + return data.getAsString("id"); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + //get one job by id + public JSONObject getJobById(String mcUrl, AuthModel authModel, ProxySettings proxy, String jobUUID) { + JSONObject jobJsonObject = null; + + try { + JSONObject loginJson = loginToMC(mcUrl, authModel, proxy); + + Map headers = initHeaders(authModel,loginJson); + if (!StringUtils.isNullOrEmpty(jobUUID) && headers != null) { + HttpUtils.ProxyInfo proxyInfo = proxy == null ? null : HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + HttpResponse response = HttpUtils.doGet(proxyInfo, mcUrl + Constants.GET_JOB_UEL + jobUUID, headers, null); + + if (response != null && response.getJsonObject() != null) { + jobJsonObject = response.getJsonObject(); + } + if (jobJsonObject != null) { + jobJsonObject = (JSONObject) jobJsonObject.get(Constants.DATA); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return removeIcon(jobJsonObject); + } + + public JSONObject getBrowserLab(String mcUrl, String accessKey, ProxySettings proxy) { + JSONObject jsonObject = null; + + try { + JSONObject loginJson = generateNewToken(mcUrl, accessKey, proxy); + if (loginJson == null) { + return null; + } + String hp4mSecret = loginJson.getAsString(Constants.LOGIN_SECRET); + String token = loginJson.getAsString(Constants.ACCESS_TOKEN); + String tokenType = loginJson.getAsString(Constants.TOKEN_TYPE); + String cookies = loginJson.getAsString(Constants.COOKIES); + if (thereIsNoArgumentNullOrEmpty(hp4mSecret, token, tokenType, cookies)) { + Map headers = new HashMap<>(); + headers.put(Constants.ACCEPT, "application/json"); + headers.put(Constants.LOGIN_SECRET, hp4mSecret); + headers.put(Constants.COOKIE, cookies); + headers.put(RESTConstants.AUTHORIZATION, String.format("%s %s", tokenType, token)); + HttpUtils.ProxyInfo proxyInfo = proxy == null ? null : HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()); + String url = String.format("%s%s?toolVersion=23.4", mcUrl, Constants.GET_BROWSER_LAB_URL); + HttpResponse response = HttpUtils.doGet(proxyInfo, url, headers, null); + + if (response != null && response.getJsonObject() != null) { + jsonObject = response.getJsonObject(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return jsonObject; + } + + //parse one job.and get the data we want + public JSONObject getJobJSONData(String mcUrl, AuthModel authModel, ProxySettings proxy, String jobUUID) { + JSONObject jobJSON = getJobById(mcUrl, authModel, proxy, jobUUID); + + JSONObject returnJSON = new JSONObject(); + if (jobJSON == null) { + return returnJSON; + } + //Device Capabilities + JSONObject returnDeviceCapabilityJSON = new JSONObject(); + + JSONObject detailJSON = (JSONObject) jobJSON.get("capableDeviceFilterDetails"); + if (detailJSON != null) { + String osType = (String) detailJSON.get("platformName"); + String osVersion = (String) detailJSON.get("platformVersion"); + String manufacturerAndModel = (String) detailJSON.get("deviceName"); + String targetLab = (String) detailJSON.get("source"); + + returnDeviceCapabilityJSON.put("OS", osType + osVersion); + returnDeviceCapabilityJSON.put("manufacturerAndModel", manufacturerAndModel); + returnDeviceCapabilityJSON.put("targetLab", targetLab); + } + + JSONObject returnDeviceJSON = new JSONObject(); + //specific device + JSONArray devices = (JSONArray) jobJSON.get("devices"); + + if (devices != null) { + JSONObject deviceJSON = (JSONObject) devices.get(0); + if (deviceJSON != null) { + String deviceID = deviceJSON.getAsString("deviceID"); + String osType = deviceJSON.getAsString("osType"); + String osVersion = deviceJSON.getAsString("osVersion"); + String manufacturerAndModel = deviceJSON.getAsString("model"); + + returnDeviceJSON.put("deviceId", deviceID); + returnDeviceJSON.put("OS", osType + " " + osVersion); + returnDeviceJSON.put("manufacturerAndModel", manufacturerAndModel); + } + } + //Applications under test + JSONArray returnExtraJSONArray = new JSONArray(); + StringBuilder extraApps = new StringBuilder(); + JSONArray extraAppJSONArray = (JSONArray) jobJSON.get(EXTRA_APPS); + + if (extraAppJSONArray != null) { + Iterator iterator = extraAppJSONArray.iterator(); + + while (iterator.hasNext()) { + JSONObject extraAPPJSON = new JSONObject(); + + JSONObject nextJSONObject = (JSONObject) iterator.next(); + String extraAppName = (String) nextJSONObject.get("name"); + Boolean instrumented = (Boolean) nextJSONObject.get(INSTRUMENTED); + + extraAPPJSON.put("extraAppName", extraAppName); + extraAPPJSON.put(INSTRUMENTED, instrumented ? PACKAGED : NOT_PACKAGED); + if (extraApps.length() > 1) { + extraApps.append(";\n"); + } + extraApps.append(extraAppName).append("\t\t").append(instrumented ? PACKAGED : NOT_PACKAGED); + + returnExtraJSONArray.add(extraAPPJSON); + } + } + //Test Definitions + JSONObject returnDefinitionJSON = new JSONObject(); + + JSONObject applicationJSON = (JSONObject) jobJSON.get("application"); + + if (applicationJSON != null) { + String launchApplicationName = (String) applicationJSON.get("name"); + Boolean instrumented = (Boolean) applicationJSON.get(INSTRUMENTED); + + returnDefinitionJSON.put("launchApplicationName", launchApplicationName); + returnDefinitionJSON.put(INSTRUMENTED, instrumented ? PACKAGED : NOT_PACKAGED); + } + + //Device metrics,Install Restart + String headerStr = (String) jobJSON.get("header"); + JSONObject headerJSON = parseJSONString(headerStr); + if (headerJSON != null) { + JSONObject configurationJSONObject = (JSONObject) headerJSON.get("configuration"); + Boolean restart = (Boolean) configurationJSONObject.get("restartApp"); + Boolean install = (Boolean) configurationJSONObject.get("installAppBeforeExecution"); + Boolean uninstall = (Boolean) configurationJSONObject.get("deleteAppAfterExecution"); + + StringBuilder sb = new StringBuilder(""); + if (restart) { + sb.append("Restart;"); + } + if (install) { + sb.append("Install;"); + } + if (uninstall) { + sb.append("Uninstall;"); + } + JSONObject collectJSON = (JSONObject) headerJSON.get("collect"); + StringBuilder deviceMetricsSb = new StringBuilder(""); + //device metrics + if (collectJSON != null) { + Boolean useCPU = (Boolean) collectJSON.get("cpu"); + Boolean useMemory = (Boolean) collectJSON.get("memory"); + Boolean useLogs = (Boolean) collectJSON.get("logs"); + Boolean useScreenshot = (Boolean) collectJSON.get("screenshot"); + Boolean useFreeMemory = (Boolean) collectJSON.get("freeMemory"); + if (useCPU) { + deviceMetricsSb.append("CPU;"); + } + if (useMemory) { + deviceMetricsSb.append("Memory;"); + } + if (useLogs) { + deviceMetricsSb.append("Log;"); + } + if (useScreenshot) { + deviceMetricsSb.append("Screenshot;"); + } + if (useFreeMemory) { + deviceMetricsSb.append("FreeMomery;"); + } + } + returnDefinitionJSON.put("autActions", removeLastSemicolon(sb)); + returnDefinitionJSON.put("deviceMetrics", removeLastSemicolon(deviceMetricsSb)); + } + returnJSON.put("deviceCapability", returnDeviceCapabilityJSON); + returnJSON.put(EXTRA_APPS, extraApps.toString()); + returnJSON.put("extraApps2", returnExtraJSONArray); + returnJSON.put("definitions", returnDefinitionJSON); + returnJSON.put("jobUUID", jobUUID); + returnJSON.put("deviceJSON", returnDeviceJSON); + return returnJSON; + } + + private JSONObject parseJSONString(String jsonString) { + JSONObject jsonObject = null; + try { + jsonObject = (JSONObject) JSONValue.parseStrict(jsonString); + } catch (Exception e) { + e.printStackTrace(); + } + return jsonObject; + } + + private String getCookieValue(String setCookie, String cookieName) { + if (StringUtils.isNullOrEmpty(setCookie)) { + return null; + } + String id = null; + String[] cookies = setCookie.split(Constants.SPLIT_COMMA); + for (int i = 0; i < cookies.length; i++) { + if (cookies[i].contains(cookieName)) { + int index = cookies[i].indexOf(Constants.EQUAL); + id = cookies[i].substring(index + 1); + break; + } + } + return id; + } + + private boolean thereIsNoArgumentNullOrEmpty(String... args) { + for (String arg : args) { + if (StringUtils.isNullOrEmpty(arg)) { + return false; + } + } + return true; + } + + private String removeLastSemicolon(StringBuilder sb) { + String result = sb.toString(); + int indexOf = result.lastIndexOf(";"); + if (indexOf > 0) { + result = result.substring(0, indexOf); + } + return result; + } + + private JSONObject removeIcon(JSONObject jobJSON) { + if (jobJSON != null) { + JSONObject applicationJSONObject = (JSONObject) jobJSON.get("application"); + if (applicationJSONObject != null) { + applicationJSONObject.remove(Constants.ICON); + } + JSONArray extArr = (JSONArray) jobJSON.get(EXTRA_APPS); + if (extArr != null) { + Iterator iterator = extArr.iterator(); + while (iterator.hasNext()) { + JSONObject extAppJSONObject = (JSONObject) iterator.next(); + extAppJSONObject.remove(Constants.ICON); + } + } + } + return jobJSON; + } + + + private Map initHeaders(AuthModel authModel, JSONObject loginJson) { + Map headers = new HashMap<>(); + if (loginJson != null) { + String hp4mSecret = loginJson.getAsString(Constants.LOGIN_SECRET); + List args = new ArrayList<>(); + args.add(hp4mSecret); + String oauth2 = "", jSessionId = ""; + if (TOKEN.equals(authModel.getValue())) { + oauth2 = loginJson.getAsString(Constants.OAUTH2_COOKIE_KEY); + if (StringUtils.isNullOrEmpty(oauth2)) { + System.out.println("ERROR:: loginToMC failed with null oauth cookie."); + return null; + } + args.add(oauth2); + } else { + jSessionId = loginJson.getAsString(Constants.JSESSIONID); + if (!StringUtils.isNullOrEmpty(jSessionId)) + args.add(jSessionId); + } + + if (thereIsNoArgumentNullOrEmpty(args.toArray(new String[0]))) { + headers.put(Constants.LOGIN_SECRET, hp4mSecret); + if (TOKEN.equals(authModel.getValue())) { + headers.put(Constants.COOKIE, String.format("%s=%s;", Constants.OAUTH2_COOKIE_KEY, oauth2)); + } else if (!StringUtils.isNullOrEmpty(jSessionId)) { + headers.put(Constants.COOKIE, String.format("%s=%s;", Constants.JSESSIONID, jSessionId)); + } else if (loginJson.containsKey(Constants.COOKIES)) { + headers.put(Constants.COOKIE, loginJson.getAsString(Constants.COOKIES)); + } + return headers; + } + } + return null; + } + + private HttpResponse doPost(ProxySettings proxy, String url, Map headers, JSONObject body) { + return HttpUtils.doPost(HttpUtils.setProxyCfg(proxy.getFsProxyAddress(), proxy.getFsProxyUserName(), proxy.getFsProxyPassword()), url, headers, body.toJSONString().getBytes(), true); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/mc/Oauth2TokenUtil.java b/src/main/java/com/microfocus/application/automation/tools/mc/Oauth2TokenUtil.java new file mode 100644 index 0000000000..2b979aeccd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/mc/Oauth2TokenUtil.java @@ -0,0 +1,103 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.mc; + +import net.minidev.json.JSONObject; +import org.apache.commons.lang.StringUtils; + +import java.util.regex.Pattern; + +public class Oauth2TokenUtil { + + private static String client; + private static String secret; + private static String tenant; + + private Oauth2TokenUtil() { + } + + public static boolean isValid(String auth2) { + String strCleaned = removeQuotes(auth2.trim()); + if (StringUtils.isBlank(strCleaned)) { + return false; + } + + String[] a = strCleaned.split(Pattern.quote(";")); + for (String s : a) { + if (StringUtils.isEmpty(s)) { + continue; + } + if (!extractField(s.trim())) { + return false; + } + } + return true; + } + + private static String removeQuotes(final String str) { + if (str.endsWith("\"") && str.startsWith("\"") && str.length() > 1) { + return str.substring(1, str.length() - 1); + } + return str; + } + + private static boolean extractField(String str) { + int pos = str.indexOf('='); + if (pos < 0) { + return false; + } + + String key = str.substring(0, pos).trim(); + String value = str.substring(pos + 1).trim(); + + if ("client".equalsIgnoreCase(key)) { + client = value; + } else if ("secret".equalsIgnoreCase(key)) { + secret = value; + } else if ("tenant".equalsIgnoreCase(key)) { + tenant = value; + } else { + return false; + } + return true; + } + + public static JSONObject getJSONObject() { + JSONObject sendObject = new JSONObject(); + sendObject.put("client", client); + sendObject.put("secret", secret); + sendObject.put("tenant", tenant); + return sendObject; + } + +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/ALMVersion.java b/src/main/java/com/microfocus/application/automation/tools/model/ALMVersion.java new file mode 100644 index 0000000000..c3342a55b9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/ALMVersion.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Effi Bar-She'an + */ +@XmlRootElement(name = "SiteVersions") +public class ALMVersion { + + @XmlElement(name = "MajorVersion") + private String _majorVersion; + @XmlElement(name = "MinorVersion") + private String _minorVersion; + + public String getMajorVersion() { + + return _majorVersion; + } + + public void setMajorVersion(String majorVersion) { + + _majorVersion = majorVersion; + } + + public String getMinorVersion() { + + return _minorVersion; + } + + public void setMinorVersion(String minorVersion) { + + _minorVersion = minorVersion; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentModelResolver.java b/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentModelResolver.java new file mode 100644 index 0000000000..b6d4a734ea --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentModelResolver.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.Util; +import hudson.util.VariableResolver; + +/** + * Created by barush on 09/11/2014. + */ +public class AUTEnvironmentModelResolver { + + public static AUTEnvironmentResolvedModel resolveModel( + AutEnvironmentModel autEnvironmentModel, + VariableResolver buildResolver) { + + String resolvedUserName = + Util.replaceMacro(autEnvironmentModel.getAlmUserName(), buildResolver); + String resolvedAlmDomain = + Util.replaceMacro(autEnvironmentModel.getAlmDomain(), buildResolver); + String resolvedAlmProject = + Util.replaceMacro(autEnvironmentModel.getAlmProject(), buildResolver); + String resolvedAutEnvironmentId = + Util.replaceMacro(autEnvironmentModel.getAutEnvironmentId(), buildResolver); + String resolvedAutEnvConfId = + Util.replaceMacro(autEnvironmentModel.getExistingAutEnvConfId(), buildResolver); + String resolvedAutEnvConfName = + Util.replaceMacro(autEnvironmentModel.getNewAutEnvConfName(), buildResolver); + String resolvedJsonPath = + Util.replaceMacro(autEnvironmentModel.getPathToJsonFile(), buildResolver); + + return new AUTEnvironmentResolvedModel( + autEnvironmentModel.getAlmServerName(), + autEnvironmentModel.getAlmServerUrl(), + resolvedUserName, + autEnvironmentModel.getAlmPassword(), + resolvedAlmDomain, + resolvedAlmProject, + autEnvironmentModel.getClientType(), + resolvedAutEnvironmentId, + autEnvironmentModel.isUseExistingAutEnvConf(), + resolvedAutEnvConfId, + autEnvironmentModel.isCreateNewAutEnvConf(), + resolvedAutEnvConfName, + autEnvironmentModel.getAutEnvironmentParameters(), + resolvedJsonPath, + autEnvironmentModel.getOutputParameter()); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentResolvedModel.java b/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentResolvedModel.java new file mode 100644 index 0000000000..94423d0c30 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AUTEnvironmentResolvedModel.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.util.List; + +/** + * Created by barush + */ +public class AUTEnvironmentResolvedModel { + + private String almServerName; + private String almServerUrl; + private String almUserName; + private String almPassword; + private String almDomain; + private String almProject; + private String clientType; + private String autEnvironmentId; + private boolean useExistingAutEnvConf; + private String existingAutEnvConfId; + private boolean createNewAutEnvConf; + private String newAutEnvConfName; + + private List autEnvironmentParameters; + + private String pathToJsonFile; + private String outputParameter; + + public AUTEnvironmentResolvedModel( + String almServerName, + String almServerUrl, + String almUserName, + String almPassword, + String almDomain, + String almProject, + String clientType, + String autEnvironmentId, + boolean useExistingAutEnvConf, + String existingAutEnvConfId, + boolean createNewAutEnvConf, + String newAutEnvConfName, + List autEnvironmentParameters, + String pathToJsonFile, + String outputParameter) { + + this.almServerName = almServerName; + this.almServerUrl = almServerUrl; + this.almUserName = almUserName; + this.almPassword = almPassword; + this.almDomain = almDomain; + this.almProject = almProject; + this.clientType = clientType; + this.autEnvironmentId = autEnvironmentId; + this.useExistingAutEnvConf = useExistingAutEnvConf; + this.existingAutEnvConfId = existingAutEnvConfId; + this.createNewAutEnvConf = createNewAutEnvConf; + this.newAutEnvConfName = newAutEnvConfName; + this.autEnvironmentParameters = autEnvironmentParameters; + this.pathToJsonFile = pathToJsonFile; + this.outputParameter = outputParameter; + } + + public String getAlmServerName() { + return almServerName; + } + + public String getAlmServerUrl() { + return almServerUrl; + } + + public String getAlmUserName() { + return almUserName; + } + + public String getAlmPassword() { + return almPassword.toString(); + } + + public String getAlmDomain() { + return almDomain; + } + + public String getAlmProject() { + return almProject; + } + + public String getClientType() { + return clientType; + } + + public String getAutEnvironmentId() { + return autEnvironmentId; + } + + public boolean isUseExistingAutEnvConf() { + return useExistingAutEnvConf; + } + + public String getExistingAutEnvConfId() { + return existingAutEnvConfId; + } + + public boolean isCreateNewAutEnvConf() { + return createNewAutEnvConf; + } + + public String getNewAutEnvConfName() { + return newAutEnvConfName; + } + + public List getAutEnvironmentParameters() { + return autEnvironmentParameters; + } + + public String getPathToJsonFile() { + return pathToJsonFile; + } + + public String getOutputParameter() { + return outputParameter; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AlmServerSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/AlmServerSettingsModel.java new file mode 100644 index 0000000000..eb81e5ae45 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AlmServerSettingsModel.java @@ -0,0 +1,133 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; + + +public class AlmServerSettingsModel extends AbstractDescribableImpl implements Comparable{ + + private final String _almServerName; + private final String _almServerUrl; + private List _almCredentials; + private List _almSSOCredentials; + + @DataBoundConstructor + public AlmServerSettingsModel(String almServerName, String almServerUrl, + List almCredentials, + List almSSOCredentials) { + + this._almServerName = almServerName.trim(); + this._almServerUrl = almServerUrl.trim(); + this._almCredentials = almCredentials; + this._almSSOCredentials = almSSOCredentials; + } + + /** + * @return the almServerName + */ + public String getAlmServerName() { + + return _almServerName; + } + + /** + * @return the almServerUrl + */ + public String getAlmServerUrl() { + + return _almServerUrl; + } + + public List getAlmCredentials(){ + if(_almCredentials != null) { + return _almCredentials; + } + + return new ArrayList<>(); + } + + public void set_almCredentials(List almCredentials){ + this._almCredentials = almCredentials; + } + + public List getAlmSSOCredentials() { + if (_almSSOCredentials != null) { + return _almSSOCredentials; + } + + return new ArrayList<>(); + } + + public void set_almSSOCredentials(List almSSOCredentials){ + this._almSSOCredentials = almSSOCredentials; + } + + public Properties getProperties() { + + Properties prop = new Properties(); + + if (!StringUtils.isEmpty(_almServerUrl)) { + prop.put("almServerUrl", _almServerUrl.trim()); + } else { + prop.put("almServerUrl", ""); + } + return prop; + } + + @Override + public int compareTo(AlmServerSettingsModel model) { + return _almServerName.compareTo(model._almServerName); + } + + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "Alm Server Settings Model"; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentModel.java b/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentModel.java new file mode 100644 index 0000000000..024d0250fe --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentModel.java @@ -0,0 +1,248 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.model.Hudson; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import java.util.List; + +/** + * Created by barush on 21/10/2014. + */ +public class AutEnvironmentModel extends AbstractDescribableImpl { + + private final String almServerName; + private String almServerUrl; + private final String almUserName; + private final SecretContainer almPassword; + private final String almDomain; + private final String almProject; + private final String clientType; + + private final String autEnvironmentId; + private final boolean useExistingAutEnvConf; + private final String existingAutEnvConfId; + private final boolean createNewAutEnvConf; + private final String newAutEnvConfName; + + private List autEnvironmentParameters; + + private final String pathToJsonFile; + private final String outputParameter; + + @DataBoundConstructor + public AutEnvironmentModel( + String almServerName, + String almUserName, + String almPassword, + String almDomain, + String almProject, + String clientType, + String autEnvironmentId, + boolean useExistingAutEnvConf, + String existingAutEnvConfId, + boolean createNewAutEnvConf, + String newAutEnvConfName, + List autEnvironmentParameters, + String pathToJsonFile, + String outputParameter) { + + this.almServerName = almServerName; + this.almUserName = almUserName; + this.almPassword = setPassword(almPassword); + this.almDomain = almDomain; + this.almProject = almProject; + this.clientType = clientType; + this.autEnvironmentId = autEnvironmentId; + this.useExistingAutEnvConf = useExistingAutEnvConf; + this.existingAutEnvConfId = existingAutEnvConfId; + this.createNewAutEnvConf = createNewAutEnvConf; + this.newAutEnvConfName = newAutEnvConfName; + this.autEnvironmentParameters = autEnvironmentParameters; + this.pathToJsonFile = pathToJsonFile; + this.outputParameter = outputParameter; + + } + + protected SecretContainer setPassword(String almPassword) { + + SecretContainer secretContainer = new SecretContainerImpl(); + secretContainer.initialize(almPassword); + + return secretContainer; + } + + public String getPathToJsonFile() { + return pathToJsonFile; + } + + public boolean isCreateNewAutEnvConf() { + return createNewAutEnvConf; + } + + public boolean isUseExistingAutEnvConf() { + return useExistingAutEnvConf; + } + + public String getAlmServerName() { + + return almServerName; + } + + public String getAlmServerUrl() { + + return almServerUrl; + } + + public void setAlmServerUrl(String almServerUrl) { + + this.almServerUrl = almServerUrl; + } + + public String getAlmUserName() { + + return almUserName; + } + + public String getAlmPassword() { + + return almPassword.toString(); + } + + public String getAlmDomain() { + + return almDomain; + } + + public String getAlmProject() { + + return almProject; + } + + public String getClientType() { + return clientType; + } + + public String getOutputParameter() { + return outputParameter; + } + + public String getAutEnvironmentId() { + return autEnvironmentId; + } + + public String getExistingAutEnvConfId() { + return existingAutEnvConfId; + } + + public String getNewAutEnvConfName() { + return newAutEnvConfName; + } + + public List getAutEnvironmentParameters() { + return autEnvironmentParameters; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + + public String getDisplayName() { + return "UFT ALM AUT Environment Preparation Model"; + } + + public AlmServerSettingsModel[] getAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + public FormValidation doCheckAlmUserName(@QueryParameter String value) { + + return generalCheckWithError(value, "User name must be set"); + } + + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + + return generalCheckWithError(value, "Domain must be set"); + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + + return generalCheckWithError(value, "Project must be set"); + } + + public FormValidation doCheckAutEnvironmentId(@QueryParameter String value) { + + return generalCheckWithError(value, "AUT Environment ID must be set"); + } + + public FormValidation doCheckAlmPassword(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.warning("Password for ALM server is empty"); + } + + return ret; + } + + public FormValidation doCheckOutputParameter(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = + FormValidation.warning("AUT Environment Configuration ID isn't assigned to any environment variable"); + } + + return ret; + } + + private FormValidation generalCheckWithError(String value, String errorMessage) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error(errorMessage); + } + + return ret; + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentParameterModel.java b/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentParameterModel.java new file mode 100644 index 0000000000..098e5693f1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AutEnvironmentParameterModel.java @@ -0,0 +1,164 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; + +/** + * Created by barush on 21/10/2014. + */ +public class AutEnvironmentParameterModel extends + AbstractDescribableImpl { + + private final String name; + private final String value; + private final String paramType; + private final boolean shouldGetOnlyFirstValueFromJson; + private String resolvedValue; + + public static final List parametersTypes = Arrays.asList( + AutEnvironmentParameterType.USER_DEFINED.value(), + AutEnvironmentParameterType.ENVIRONMENT.value(), + AutEnvironmentParameterType.EXTERNAL.value()); + + @DataBoundConstructor + public AutEnvironmentParameterModel( + String name, + String value, + String paramType, + boolean shouldGetOnlyFirstValueFromJson) { + + this.name = name; + this.value = value; + this.paramType = paramType; + this.shouldGetOnlyFirstValueFromJson = shouldGetOnlyFirstValueFromJson; + } + + public boolean isShouldGetOnlyFirstValueFromJson() { + return shouldGetOnlyFirstValueFromJson; + } + + public String getParamType() { + return paramType; + } + + public String getValue() { + return value; + } + + public String getName() { + return name; + } + + public String getResolvedValue() { + return resolvedValue; + } + + public void setResolvedValue(String resolvedValue) { + this.resolvedValue = resolvedValue; + } + + public enum AutEnvironmentParameterType { + + UNDEFINED(""), ENVIRONMENT("Environment"), EXTERNAL("From JSON"), USER_DEFINED("Manual"); + + private String value; + + private AutEnvironmentParameterType(String value) { + + this.value = value; + } + + public String value() { + + return value; + } + + public static AutEnvironmentParameterType get(String val) { + for (AutEnvironmentParameterType parameterType : AutEnvironmentParameterType.values()) { + if (val.equals(parameterType.value())) + return parameterType; + } + return UNDEFINED; + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + + public String getDisplayName() { + return "AUT Parameter"; + } + + public List getParametersTypes() { + return AutEnvironmentParameterModel.parametersTypes; + } + + public FormValidation doCheckName(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Parameter name must be set"); + } + + return ret; + } + + public FormValidation doCheckValue(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.warning("You didn't assign any value to this parameter"); + } + + return ret; + } + + public String getRandomName(@QueryParameter String prefix) { + return prefix + UUID.randomUUID(); + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/AuthModel.java b/src/main/java/com/microfocus/application/automation/tools/model/AuthModel.java new file mode 100644 index 0000000000..5def9b0c1b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/AuthModel.java @@ -0,0 +1,114 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.mc.AuthType; +import hudson.util.Secret; +import org.apache.commons.lang3.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.Serializable; + +public class AuthModel implements Serializable { + private final String mcUserName; + private final Secret mcPassword; + private final String mcTenantId; + private final Secret mcExecToken; + private final String value; + private AuthType authType; + + @DataBoundConstructor + public AuthModel(String mcUserName, String mcPassword, String mcTenantId, String mcExecToken, String value) { + this.mcUserName = mcUserName; + this.mcPassword = Secret.fromString(mcPassword); + this.mcTenantId = mcTenantId; + this.mcExecToken = Secret.fromString(mcExecToken); + this.value = value; + authType = AuthType.fromString(value); + if (authType == AuthType.UNKNOWN) { + if (StringUtils.isNotBlank(mcExecToken)) { + authType = AuthType.TOKEN; + } else if (StringUtils.isNotBlank(mcUserName) && StringUtils.isNotBlank(mcPassword)) { + authType = AuthType.BASE; + } + } + } + + public String getMcUserName() { + return mcUserName; + } + + public String getMcPassword() { + if (null != mcPassword) { + return mcPassword.getPlainText(); + } else { + return null; + } + } + + public String getMcTenantId() { + return mcTenantId; + } + + public String getMcExecToken() { + if (null != mcExecToken) { + return mcExecToken.getPlainText(); + } else { + return null; + } + } + + public String getValue() { + return value; + } + + public String getMcEncryptedExecToken() { + if (null != mcExecToken) { + return mcExecToken.getEncryptedValue(); + } else { + return null; + } + } + + public String getMcEncryptedPassword() { + if (null != mcPassword) { + return mcPassword.getEncryptedValue(); + } else { + return null; + } + } + + public AuthType getAuthType() { + return authType; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/CdaDetails.java b/src/main/java/com/microfocus/application/automation/tools/model/CdaDetails.java new file mode 100644 index 0000000000..e4da7ebdc3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/CdaDetails.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.util.Arrays; +import java.util.List; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +public class CdaDetails { + + private final String _deploymentAction; + private final String _deployedEnvironmentName; + private final String _deprovisioningAction; + + private final static EnumDescription _deploymentActionUseDeployed = new EnumDescription( + "", + "Use Deployed"); + private final static EnumDescription _deploymentActionProvisionDeploy = new EnumDescription( + "Provision;Deploy", + "Provision and Deploy"); + private final static EnumDescription _deploymentActionRedeploy = new EnumDescription( + "Deploy", + "Redeploy"); + private final static List _deploymentActions = Arrays.asList( + _deploymentActionUseDeployed, + _deploymentActionProvisionDeploy, + _deploymentActionRedeploy); + + private final static EnumDescription _deprovisioningActionLeaveDeployed = new EnumDescription( + "", + "Leave environment deployed"); + private final static EnumDescription _deprovisioningActionDeprovision = new EnumDescription( + "Deprovision", + "Deprovision at end"); + private final static List _deprovisioningActions = Arrays.asList( + _deprovisioningActionLeaveDeployed, + _deprovisioningActionDeprovision); + + @DataBoundConstructor + public CdaDetails( + String deploymentAction, + String deployedEnvironmentName, + String deprovisioningAction) { + + _deploymentAction = deploymentAction; + _deployedEnvironmentName = deployedEnvironmentName; + _deprovisioningAction = deprovisioningAction; + } + + public static List getDeploymentActions() { + + return _deploymentActions; + } + + public static List getDeprovisioningActions() { + + return _deprovisioningActions; + } + + public String getTopologyAction() { + + String ret = _deploymentAction; + if (!StringUtils.isNullOrEmpty(_deprovisioningAction)) { + ret = String.format("%s;%s", ret, _deprovisioningAction); + } + + return ret; + } + + public String getDeploymentAction() { + + return _deploymentAction; + } + + public String getDeployedEnvironmentName() { + + return _deployedEnvironmentName; + } + + public String getDeprovisioningAction() { + + return _deprovisioningAction; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/CloudBrowserModel.java b/src/main/java/com/microfocus/application/automation/tools/model/CloudBrowserModel.java new file mode 100644 index 0000000000..45af7dc747 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/CloudBrowserModel.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.Serializable; + +public class CloudBrowserModel implements Serializable { + private String url; + private String version; + private String type; + private String region; + private String os; + + @DataBoundConstructor + public CloudBrowserModel(String cloudBrowserUrl, String cloudBrowserType, String cloudBrowserVersion, String cloudBrowserRegion, String cloudBrowserOs) { + this.url = cloudBrowserUrl; + this.type = cloudBrowserType; + this.version = cloudBrowserVersion; + this.os = cloudBrowserOs; + this.region = cloudBrowserRegion; + } + + public String getVersion() { + return version; + } + + public String getType() { + return type; + } + + public String getRegion() { + return region; + } + + public String getOs() { + return os; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/CredentialsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/CredentialsModel.java new file mode 100644 index 0000000000..b544fcda77 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/CredentialsModel.java @@ -0,0 +1,73 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.Secret; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.Serializable; + + +public class CredentialsModel extends AbstractDescribableImpl implements Serializable { + private String almUsername; + private Secret almPassword; + + @DataBoundConstructor + public CredentialsModel(String almUsername, String almPassword) { + this.almUsername = almUsername; + this.almPassword = Secret.fromString(almPassword); + } + + public String getAlmUsername(){ + return almUsername; + } + + public Secret getAlmPassword(){ + return almPassword; + } + public String getAlmPasswordPlainText(){ + return almPassword.getPlainText(); + } + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "Credentials Model"; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/CredentialsScope.java b/src/main/java/com/microfocus/application/automation/tools/model/CredentialsScope.java new file mode 100644 index 0000000000..fad3cc4795 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/CredentialsScope.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public enum CredentialsScope { + JOB("Job (local) credentials"), + SYSTEM("System (global) credentials"); + + private final String description; + CredentialsScope(String description) { + this.description = description; + } + + public String getValue(){ + return this.toString(); + } + public String getDescription(){ + return this.description; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/EnumDescription.java b/src/main/java/com/microfocus/application/automation/tools/model/EnumDescription.java new file mode 100644 index 0000000000..4f2c79a790 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/EnumDescription.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public class EnumDescription { + + public EnumDescription(String value, String description) { + this.value = value; + this.description = description; + } + + private String description; + private String value; + + public String getDescription() { + return description; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestModel.java b/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestModel.java new file mode 100644 index 0000000000..34a70ebd6b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestModel.java @@ -0,0 +1,130 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Represents the tests that ParallelRunner should run and the environments on which to run them. + */ +public class FileSystemTestModel extends AbstractDescribableImpl { + private String tests; // tests to run + private List parallelRunnerEnvironments; // the environments to run on + + /** + * Constructs a new FileSystemTestModel + * @param tests the tests to be run + * @param parallelRunnerEnvironments the environments on which to run the tests on + */ + @DataBoundConstructor + public FileSystemTestModel(String tests,List parallelRunnerEnvironments) { + this.tests = tests; + this.parallelRunnerEnvironments = parallelRunnerEnvironments; + } + + /** + * Returns the tests. + * @return the tests + */ + public String getTests() { + if(this.tests == null) { + this.tests = "\n"; + } + else if(!this.tests.contains("\n")) { + this.tests+="\n"; + } + + return tests; + } + + /** + * Adds a new line to the tests string if not present (keep the expandableTextBox expanded). + * @param tests the tests + */ + private void setTestsWithNewLine(String tests) { + this.tests = tests.trim(); + + if (!this.tests.contains("\n")) { + this.tests += "\n"; + } + } + + /** + * Returns the environments on which the tests will run. + * @return the parallel runner environments + */ + public List getParallelRunnerEnvironments() { + return parallelRunnerEnvironments; + } + + + /** + * Expand the tests based on the environment variables. + * @param envVars the environment variables + * @return the parsed list of tests + */ + public List parseTests(EnvVars envVars) { + String expandedFsTests = envVars.expand(this.tests); + + List result = new ArrayList<>(); + + if(StringUtils.isNullOrEmpty(this.tests)) + return result; + + if (UftToolUtils.isMtbxContent(expandedFsTests)) { + result.add(expandedFsTests); + } else { + result = Arrays.asList(expandedFsTests.replaceAll("\r", "").split("\n")); + } + + return result; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() {return "File system test model";} + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestSetModel.java b/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestSetModel.java new file mode 100644 index 0000000000..dcb93be475 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/FileSystemTestSetModel.java @@ -0,0 +1,131 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Properties; + +/** + * Represents the list of tests and environments which ParallelRunner will execute. + */ +public class FileSystemTestSetModel extends AbstractDescribableImpl { + private List fileSystemTestSet; + + /** + * Construct a new FileSystemTestSetModel. + * @param fileSystemTestSet the list of tests and environments + */ + @DataBoundConstructor + public FileSystemTestSetModel(List fileSystemTestSet) { + this.fileSystemTestSet = fileSystemTestSet; + } + + /** + * Returns the list of tests and environments + * @return the list of tests and environments + */ + public List getFileSystemTestSet() { + return fileSystemTestSet; + } + + /** + * Remove the fsTests as ParallelRunner won't run those. + * @param props the properties + */ + private void removeFsTests(Properties props) { + int current = 1; + String key = "Test"; + + while(props.containsKey(key + current)) { + props.remove(key + current); + current+=1; + } + } + + /** + * Add the parallel runner tests and environments to the properties. + * @param props the properties + * @param envVars the environment variables + */ + public void addTestSetProperties(Properties props,EnvVars envVars) { + // enabled parallel runner for build + props.put("parallelRunnerMode","true"); + + // remove the tests set by fs + removeFsTests(props); + + int testNumber = 1; + + for(FileSystemTestModel testModel : this.fileSystemTestSet) { + List tests = testModel.parseTests(envVars); + + // these are the environments for each test + // from the tests list + List environmentModels = testModel.getParallelRunnerEnvironments(); + + for(String test: tests) { + test = test.trim(); + + // first add the test + props.put("Test" + testNumber,test); + + int envNumber = 1; + + // each parallel test environment will be of the form + // ParallelTest1Env1, ParallelTest1Env2,..., ParallelTest1EnvN + for(ParallelRunnerEnvironmentModel environment : environmentModels) { + // add the environment for each test + props.put("ParallelTest" + testNumber+ "Env" + envNumber,environment.getEnvironment()); + envNumber++; + } + + // increment the number of available tests + testNumber++; + } + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() {return "File System test set model";} + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/MCServerSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/MCServerSettingsModel.java new file mode 100644 index 0000000000..ebc1b0185a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/MCServerSettingsModel.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.Properties; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 10/13/15 + * Time: 11:06 AM + * To change this template use File | Settings | File Templates. + */ +public class MCServerSettingsModel { + + private final String _mcServerName; + private final String _mcServerUrl; + + @DataBoundConstructor + public MCServerSettingsModel(String mcServerName, String mcServerUrl) { + + _mcServerName = mcServerName; + _mcServerUrl = mcServerUrl; + } + + /** + * @return the mcServerName + */ + public String getMcServerName() { + + return _mcServerName; + } + + /** + * @return the mcServerUrl + */ + public String getMcServerUrl() { + + return _mcServerUrl; + } + + public Properties getProperties() { + + Properties prop = new Properties(); + if (!StringUtils.isEmpty(_mcServerUrl)) { + prop.put("MobileHostAddress", _mcServerUrl); + } else { + prop.put("MobileHostAddress", ""); + } + + return prop; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/OctaneServerSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/OctaneServerSettingsModel.java new file mode 100644 index 0000000000..27e261b9b0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/OctaneServerSettingsModel.java @@ -0,0 +1,312 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.octane.exceptions.AggregatedMessagesException; +import hudson.util.Secret; +import org.apache.commons.lang.StringUtils; +import org.apache.http.annotation.Obsolete; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import java.io.Serializable; +import java.util.*; + +/* + * Model for sorting the Octane configuration + */ +public class OctaneServerSettingsModel implements Serializable { + private String internalId = UUID.randomUUID().toString(); + + private String identity; + private Long identityFrom; + + private String uiLocation; + private String username; + private Secret password; + private String impersonatedUser; + private boolean suspend; + private String sscBaseToken; + private boolean fortifyParamsConverted; + + // inferred from uiLocation + private String location; + private String sharedSpace; + + + private String workspace2ImpersonatedUserConf; + private Map workspace2ImpersonatedUserMap; + + private String parameters; + + public OctaneServerSettingsModel() { + } + + @DataBoundConstructor + public OctaneServerSettingsModel(String uiLocation, String username, Secret password, String impersonatedUser) { + this.uiLocation = StringUtils.trim(uiLocation); + this.username = StringUtils.trim(username); + this.password = password; + this.impersonatedUser = StringUtils.trim(impersonatedUser); + } + + public String getInternalId() { + return internalId; + } + + public boolean isSuspend() { + return this.suspend; + } + + @DataBoundSetter + public void setSuspend(boolean suspend) { + this.suspend = suspend; + } + + @Obsolete + public String getSscBaseToken() { + return this.sscBaseToken; + } + + @Obsolete + @DataBoundSetter + public void setSscBaseToken(String sscBaseToken) { + this.sscBaseToken = sscBaseToken; + } + + public String getUiLocation() { + return uiLocation; + } + + public String getUsername() { + return username; + } + + public Secret getPassword() { + return password; + } + + public String getImpersonatedUser() { + return impersonatedUser; + } + + public String getIdentity() { + return identity; + } + + @DataBoundSetter + public void setIdentity(String identity) { + this.identity = StringUtils.trim(identity); + this.setIdentityFrom(new Date().getTime()); + } + + public Long getIdentityFrom() { + return identityFrom; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = StringUtils.trim(location); + } + + public String getSharedSpace() { + return sharedSpace; + } + + public void setSharedSpace(String sharedSpace) { + this.sharedSpace = StringUtils.trim(sharedSpace); + } + + public void setIdentityFrom(Long identityFrom) { + this.identityFrom = identityFrom; + } + + public boolean isValid() { + return identity != null && !identity.isEmpty() && + location != null && !location.isEmpty() && + internalId != null && !internalId.isEmpty() && + sharedSpace != null && !sharedSpace.isEmpty(); + } + + public void setInternalId(String internalId) { + this.internalId = internalId; + } + + public String getCaption() { + return getLocation() + "?p=" + getSharedSpace(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OctaneServerSettingsModel that = (OctaneServerSettingsModel) o; + return suspend == that.suspend && + Objects.equals(identity, that.identity) && + Objects.equals(username, that.username) && + Objects.equals(password, that.password) && + Objects.equals(impersonatedUser, that.impersonatedUser) && + Objects.equals(location, that.location) && + Objects.equals(workspace2ImpersonatedUserConf, that.workspace2ImpersonatedUserConf) && + Objects.equals(parameters, that.parameters) && + Objects.equals(sharedSpace, that.sharedSpace); + } + + @Override + public int hashCode() { + return Objects.hash(identity, username, password, impersonatedUser, suspend, location, sharedSpace, internalId, getWorkspace2ImpersonatedUserConf()); + } + + public String getWorkspace2ImpersonatedUserConf() { + return workspace2ImpersonatedUserConf; + } + + @DataBoundSetter + public void setWorkspace2ImpersonatedUserConf(String workspace2ImpersonatedUserConf) { + this.workspace2ImpersonatedUserConf = workspace2ImpersonatedUserConf; + workspace2ImpersonatedUserMap = parseWorkspace2ImpersonatedUserConf(workspace2ImpersonatedUserConf, true); + } + + public Map getWorkspace2ImpersonatedUserMap() { + if (workspace2ImpersonatedUserMap == null) { + workspace2ImpersonatedUserMap = Collections.emptyMap(); + } + return workspace2ImpersonatedUserMap; + } + + public static Map parseWorkspace2ImpersonatedUserConf(String workspace2ImpersonatedUserConf, boolean ignoreErrors) { + Map workspace2ImpersonatedUserMap = new HashMap<>(); + List errorsFound = new ArrayList<>(); + if (workspace2ImpersonatedUserConf != null) { + String[] parts = workspace2ImpersonatedUserConf.split("\\n"); + for (String workspaceConfiguration : parts) { + try { + parseWorkspaceConfiguration(workspace2ImpersonatedUserMap, workspaceConfiguration); + } catch (IllegalArgumentException e) { + errorsFound.add((e.getMessage())); + } + } + } + if (!ignoreErrors && !errorsFound.isEmpty()) { + throw new AggregatedMessagesException(errorsFound); + } + return workspace2ImpersonatedUserMap; + } + + private static void parseWorkspaceConfiguration(Map workspace2ImpersonatedUserMap, String workspaceConfiguration) { + String workspaceConfigurationTrimmed = workspaceConfiguration.trim(); + if (workspaceConfigurationTrimmed.isEmpty() || workspaceConfigurationTrimmed.startsWith("#")) { + return; + } + + int splitterIndex = workspaceConfiguration.indexOf(':'); + if (splitterIndex == -1) { + throw new IllegalArgumentException("Workspace configuration is not valid, valid format is 'Workspace ID:jenkins user': " + workspaceConfigurationTrimmed); + } + + Long workspaceId = getLongOrNull(workspaceConfiguration.substring(0, splitterIndex)); + if (workspaceId == null) { + throw new IllegalArgumentException("Workspace configuration is not valid, workspace ID must be numeric: " + workspaceConfigurationTrimmed); + } + + String user = workspaceConfiguration.substring(splitterIndex + 1).trim(); + if (user.isEmpty()) { + throw new IllegalArgumentException("Workspace configuration is not valid, user value is empty: " + workspaceConfigurationTrimmed); + } + + if (workspace2ImpersonatedUserMap.containsKey(workspaceId)) { + throw new IllegalArgumentException("Duplicated workspace configuration: " + workspaceConfigurationTrimmed); + } + + workspace2ImpersonatedUserMap.put(workspaceId, user); + } + + private static Long getLongOrNull(String str) { + try { + return Long.parseLong(str.trim()); + } catch (NumberFormatException e) { + return null; + } + } + + public String getParameters() { + return parameters; + } + + public Map getParametersAsMap() { + return parseParameters(parameters); + } + + + public static Map parseParameters(String rawParameters) { + Map map = new HashMap<>(); + if (rawParameters == null) { + return map; + } + String[] parts = rawParameters.split("\\n"); + for (String part : parts) { + String trimmedPart = part.trim(); + if (trimmedPart.isEmpty() || trimmedPart.startsWith("#")) { + continue; + } + String key; + String value = null; + int separation = trimmedPart.indexOf(':'); + if (separation > 0) { + key = trimmedPart.substring(0, separation).trim(); + value = trimmedPart.substring(separation + 1).trim(); + } else { + key = trimmedPart; + } + map.put(key, value); + } + + return map; + } + + @DataBoundSetter + public void setParameters(String parameters) { + this.parameters = parameters; + } + + public boolean isFortifyParamsConverted() { + return fortifyParamsConverted; + } + + public void setFortifyParamsConverted(boolean fortifyParamsConverted) { + this.fortifyParamsConverted = fortifyParamsConverted; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/ParallelRunnerEnvironmentModel.java b/src/main/java/com/microfocus/application/automation/tools/model/ParallelRunnerEnvironmentModel.java new file mode 100644 index 0000000000..41f727f26d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/ParallelRunnerEnvironmentModel.java @@ -0,0 +1,261 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.util.*; + +/** + * Represents the environment that Parallel Runner uses to execute a test. + */ +public class ParallelRunnerEnvironmentModel extends AbstractDescribableImpl { + private static class EnvironmentValidationException extends Exception { + public EnvironmentValidationException(String message) { + super(message); + } + } + + private String environment; + private String environmentType; // 'Web', 'Mobile' + + @DataBoundConstructor + public ParallelRunnerEnvironmentModel(String environment,String environmentType) { + this.environment = environment; + this.environmentType = environmentType; + } + + /** + * Returns the parallel runner environment string. + * @return the environment string + */ + public String getEnvironment() { + return environment; + } + + /** + * Returns the environment type + * @return the environment type + */ + public String getEnvironmentType() { return environmentType; } + + @Extension + public static class DescriptorImpl extends Descriptor { + private static final String DeviceIdKey = "deviceid"; + private static final String OsTypeKey = "ostype"; + private static final String OsVersionKey = "osversion"; + private static final String ManufacturerAndModelKey = "manufacturerandmodel"; + private static final String BrowserKey = "browser"; + + // the list of browsers that ParallelRunner supports + private static final List SupportedBrowsers = new ArrayList() { + { + add("IE"); + add("IE64"); + add("CHROME"); + add("FIREFOX"); + add("FIREFOX64"); + } + }; + + private static final List KnownProperties = new ArrayList() { + { + add(DeviceIdKey); + add(OsTypeKey); + add(OsVersionKey); + add(ManufacturerAndModelKey); + add(BrowserKey); + } + }; + + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { load(); } + + + /** + * Returns the display name. + */ + @Nonnull + public String getDisplayName() {return "Parallel Runner Environment model.";} + + /** + * Return the key value pairs from an environment string. + * @param environment the environment string + * @return a map containing the key value pairs + */ + private Map getEnvironmentKeyValuePairs(String environment) { + // environment string example: osType : Android,osVersion : 4.4.2,manufacturerAndModel : "samsung GT-I9515" + // or : browser : Chrome + Map pairs = new HashMap<>(); + + String [] tokens = environment.toLowerCase().split(","); + + for (String token : tokens) { + String [] keyValue = token.split(":"); + + // invalid key/value pair + if(keyValue.length < 2) { + continue; + } + + // we will treat the first value as the key + String key = keyValue[0].trim(); + + if(key.isEmpty()) + continue; + + // the rest of the list represents the value + String value = StringUtils. + join(Arrays.asList(keyValue).subList(1, keyValue.length),"") + .trim(); + + // we will always use the last provided key + pairs.put(key,value); + } + + // as result we will have + // { osType : Android} + // { osVersion : 4.4.2 } + // { manufacturerAndModel : "samsung GT-I9515" } + + return pairs; + } + + /** + * Checks if the provided browser is supported by ParallelRunner. + * @param browserName the name of the browser + * @return true if the browser is supported, false otherwise + */ + private boolean isSupportedBrowser(String browserName) { + for(String browser : SupportedBrowsers) { + if(browser.equalsIgnoreCase(browserName)){ + return true; + } + } + + return false; + } + + /** + * Check if the given property is known(valid). + * @param property the property + * @return true if the property is known, false otherwise + */ + private boolean isKnownProperty(String property) { + for(String knownProperty : KnownProperties) { + if(knownProperty.equalsIgnoreCase(property)){ + return true; + } + } + + return false; + } + + private void checkKeyValueValidity(String key,Map pairs,String message) throws EnvironmentValidationException { + // if the key is present the value must be present too + if(pairs.containsKey(key) && pairs.get(key).trim().isEmpty()) { + throw new EnvironmentValidationException(message); + } + } + + /** + * Validate the environment string. + * @param environment the environment string + */ + private void validateEnvironmentString(String environment) throws EnvironmentValidationException { + Map pairs = this.getEnvironmentKeyValuePairs(environment); + + // check if any property was provided + if(pairs.isEmpty()) { + throw new EnvironmentValidationException("No property provided. Enter properties using the following syntax: :"); + } + + // check if there are any invalid property names + for(String key : pairs.keySet()) { + if(!isKnownProperty(key)) { + throw new EnvironmentValidationException("Invalid property name: " + key); + } + } + + checkKeyValueValidity(DeviceIdKey,pairs,"DeviceId value must not be empty!"); + checkKeyValueValidity(OsVersionKey,pairs,"OsVersion value must not be empty!"); + checkKeyValueValidity(OsTypeKey,pairs,"OsType value must not be empty!"); + checkKeyValueValidity(ManufacturerAndModelKey,pairs,"ManufacturerAndModel value must not be empty!"); + + // if it's a browser environment + if(pairs.containsKey(BrowserKey)) { + String browserName = pairs.get(BrowserKey).trim(); + + // check if the value is present + if(browserName.isEmpty()) { + throw new EnvironmentValidationException("Browser value must not be empty!"); + } + + // check if ParallelRunner supports the given browser + if(!isSupportedBrowser(browserName)) { + throw new EnvironmentValidationException(String.format("Invalid browser. %s is not supported!", browserName.toUpperCase())); + } + } + } + + /** + * Sanity check for the environment string. + * @param value the environment string + * @return the result of the sanity check + */ + @SuppressWarnings("unused") + public FormValidation doCheckEnvironment(@QueryParameter String value) { + if(StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + try{ + this.validateEnvironmentString(value); + }catch (EnvironmentValidationException e) { + return FormValidation.error(e.getMessage()); + } + + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/ProxySettings.java b/src/main/java/com/microfocus/application/automation/tools/model/ProxySettings.java new file mode 100644 index 0000000000..de23ef0270 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/ProxySettings.java @@ -0,0 +1,81 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.util.Secret; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 3/30/16 + * Time: 1:37 PM + * To change this template use File | Settings | File Templates. + */ +public class ProxySettings { + private boolean fsUseAuthentication; + private String fsProxyAddress; + private String fsProxyUserName; + private Secret fsProxyPassword; + + public ProxySettings() { + } + + @DataBoundConstructor + public ProxySettings(boolean fsUseAuthentication, String fsProxyAddress, String fsProxyUserName, String fsProxyPassword) { + this.fsUseAuthentication = fsUseAuthentication; + this.fsProxyAddress = fsProxyAddress; + this.fsProxyUserName = fsProxyUserName; + this.fsProxyPassword = Secret.fromString(fsProxyPassword); + } + + public boolean isFsUseAuthentication() { + return fsUseAuthentication; + } + + public String getFsProxyAddress() { + return fsProxyAddress; + } + + public String getFsProxyUserName() { + return fsProxyUserName; + } + + public String getFsProxyPassword() { + if (null != fsProxyPassword) { + return fsProxyPassword.getPlainText(); + } else { + return null; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/ResultsPublisherModel.java b/src/main/java/com/microfocus/application/automation/tools/model/ResultsPublisherModel.java new file mode 100644 index 0000000000..1e786727b0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/ResultsPublisherModel.java @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +import org.kohsuke.stapler.DataBoundConstructor; + +public class ResultsPublisherModel implements Serializable { + + private static final long serialVersionUID = 1L; + + public final static EnumDescription dontArchiveResults = new EnumDescription("DONT_ARCHIVE_TEST_REPORT", "Do not archive test reports"); + public final static EnumDescription alwaysArchiveResults = new EnumDescription("ALWAYS_ARCHIVE_TEST_REPORT", "Always archive test reports"); + public final static EnumDescription ArchiveFailedTestsResults = new EnumDescription("ONLY_ARCHIVE_FAILED_TESTS_REPORT", "Archive test report for failed tests "); + public final static EnumDescription CreateHtmlReportResults = new EnumDescription("PUBLISH_HTML_REPORT", "Always archive and publish test reports (LRP only)"); + public final static List archiveModes = + Arrays.asList(ArchiveFailedTestsResults, alwaysArchiveResults, + CreateHtmlReportResults, dontArchiveResults); + + private String archiveTestResultsMode; + + @DataBoundConstructor + public ResultsPublisherModel(String archiveTestResultsMode) { + + this.archiveTestResultsMode=archiveTestResultsMode; + + if (this.archiveTestResultsMode.isEmpty()){ + this.archiveTestResultsMode=dontArchiveResults.getValue(); + } + } + + public String getArchiveTestResultsMode() { + return archiveTestResultsMode; + } + +} + + + diff --git a/src/main/java/com/microfocus/application/automation/tools/model/RunFromAlmModel.java b/src/main/java/com/microfocus/application/automation/tools/model/RunFromAlmModel.java new file mode 100644 index 0000000000..53032f4108 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/RunFromAlmModel.java @@ -0,0 +1,251 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.EnvVars; +import hudson.Extension; +import hudson.Util; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; + +import hudson.util.VariableResolver; + +import java.util.Arrays; +import java.util.List; + +import hudson.util.Secret; + +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + + +import javax.annotation.Nonnull; + +public class RunFromAlmModel extends AbstractDescribableImpl { + + public final static EnumDescription runModeLocal = new EnumDescription( + "RUN_LOCAL", "Run locally"); + public final static EnumDescription runModePlannedHost = new EnumDescription( + "RUN_PLANNED_HOST", "Run on planned host"); + public final static EnumDescription runModeRemote = new EnumDescription( + "RUN_REMOTE", "Run remotely"); + public final static List runModes = Arrays.asList( + runModeLocal, runModePlannedHost, runModeRemote); + + public final static int DEFAULT_TIMEOUT = 36000; // 10 hrs + public final static String ALM_PASSWORD_KEY = "almPassword"; + public final static String ALM_API_KEY_SECRET = "almApiKeySecret"; + + private String almServerName; + private String almUserName; + private Secret almPassword; + private String almDomain; + private String almProject; + private String almTestSets; + private String almRunResultsMode; + private String almTimeout; + private String almRunMode; + private String almRunHost; + private Boolean isSSOEnabled; + private String almClientID; + private Secret almApiKey; + private CredentialsScope credentialsScope; + + @DataBoundConstructor + public RunFromAlmModel(String almServerName, String almUserName, String almPassword, String almDomain, String almProject, + String almTestSets, String almRunResultsMode, String almTimeout, + String almRunMode, String almRunHost, Boolean isSSOEnabled, + String almClientID, String almApiKey, CredentialsScope credentialsScope) { + + this.almServerName = almServerName; + this.credentialsScope = credentialsScope; + + this.almUserName = StringUtils.defaultString(almUserName); + this.almPassword = StringUtils.isBlank(almUserName) ? null : Secret.fromString(almPassword); + this.almDomain = almDomain; + this.almProject = almProject; + this.almTestSets = almTestSets; + + if (!this.almTestSets.contains("\n")) { + this.almTestSets += "\n"; + } + + this.almRunResultsMode = almRunResultsMode; + this.almTimeout = almTimeout; + this.almRunMode = almRunMode; + this.almRunHost = almRunHost; + + this.isSSOEnabled = isSSOEnabled; + this.almClientID = StringUtils.defaultString(almClientID); + this.almApiKey = StringUtils.isBlank(almClientID) ? null : Secret.fromString(almApiKey); + } + + public String getAlmUserName() { + return almUserName; + } + + public String getAlmDomain() { + return almDomain; + } + + public Secret getAlmPassword() { + return almPassword; + } + + public String getAlmProject() { + return almProject; + } + + public String getAlmTestSets() { + return almTestSets; + } + + public String getAlmRunResultsMode() { + return almRunResultsMode; + } + + public String getAlmTimeout() { + return almTimeout; + } + + public String getAlmRunHost() { + return almRunHost; + } + + public String getAlmRunMode() { + return almRunMode; + } + + public String getAlmServerName() { + return almServerName; + } + + public CredentialsScope getCredentialsScope() { + return credentialsScope; + } + + public Boolean isSSOEnabled() { + return isSSOEnabled; + } + + public void setIsSSOEnabled(Boolean isSSOEnabled){ + this.isSSOEnabled = isSSOEnabled; + } + + public String getAlmClientID() { return almClientID; } + + public Secret getAlmApiKey() { return almApiKey; } + + public Properties getProperties(EnvVars envVars, VariableResolver varResolver) { + return CreateProperties(envVars, varResolver); + } + + public String getCredentialsScopeValue() { return credentialsScope == null ? "" : credentialsScope.getValue(); } + public String getPasswordEncryptedValue() { return almPassword == null ? "" : almPassword.getEncryptedValue(); } + public String getApiKeyEncryptedValue() { return almApiKey == null || StringUtils.isBlank(almApiKey.getPlainText()) ? "" : almApiKey.getEncryptedValue(); } + public String getPasswordPlainText() { return almPassword == null ? "" : almPassword.getPlainText(); } + public String getApiKeyPlainText() { return almApiKey == null ? "" : almApiKey.getPlainText(); } + + public Properties getProperties() { + return CreateProperties(null, null); + } + + private Properties CreateProperties(EnvVars envVars, VariableResolver varResolver) { + Properties props = new Properties(); + + if(isSSOEnabled != null){ + props.put("SSOEnabled", Boolean.toString(isSSOEnabled)); + }else{ + props.put("SSOEnabled", Boolean.toString(false)); + } + + if (envVars == null) { + props.put("almUsername", almUserName); + props.put("almDomain", almDomain); + props.put("almProject", almProject); + } else { + props.put("almUsername", + Util.replaceMacro(envVars.expand(almUserName), varResolver)); + props.put("almDomain", + Util.replaceMacro(envVars.expand(almDomain), varResolver)); + props.put("almProject", + Util.replaceMacro(envVars.expand(almProject), varResolver)); + } + + if (!StringUtils.isEmpty(this.almTestSets)) { + + String[] testSetsArr = this.almTestSets.replaceAll("\r", "").split( + "\n"); + + int i = 1; + + for (String testSet : testSetsArr) { + if (!StringUtils.isBlank(testSet)) { + props.put("TestSet" + i, + Util.replaceMacro(envVars.expand(testSet), varResolver)); + i++; + } + } + + props.put("numOfTests", String.valueOf(i - 1)); + } else { + props.put("almTestSets", ""); + } + + if (StringUtils.isEmpty(almTimeout)) { + props.put("almTimeout", "-1"); + } else { + props.put("almTimeout", almTimeout); + } + + props.put("almRunMode", almRunMode); + props.put("almRunHost", almRunHost); + + return props; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "UFT ALM Model"; + } + + public List getAlmRunModes() { + return runModes; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/RunFromFileSystemModel.java b/src/main/java/com/microfocus/application/automation/tools/model/RunFromFileSystemModel.java new file mode 100644 index 0000000000..2ac0502dd7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/RunFromFileSystemModel.java @@ -0,0 +1,790 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.EncryptionUtils; +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import com.microfocus.application.automation.tools.mc.JobConfigurationProxy; +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.model.Node; +import net.minidev.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +/** + * Holds the data for RunFromFile build type. + */ +public class RunFromFileSystemModel extends AbstractDescribableImpl { + + public static final String MOBILE_PROXY_SETTING_PASSWORD_FIELD = "MobileProxySetting_Password"; + public static final String MOBILE_PROXY_SETTING_USER_NAME = "MobileProxySetting_UserName"; + public static final String MOBILE_PROXY_SETTING_AUTHENTICATION = "MobileProxySetting_Authentication"; + public static final String MOBILE_USE_SSL = "MobileUseSSL"; + + public final static EnumDescription FAST_RUN_MODE = new EnumDescription("Fast", "Fast"); + public final static EnumDescription NORMAL_RUN_MODE = new EnumDescription("Normal", "Normal"); + + public final static List fsUftRunModes = Arrays.asList(FAST_RUN_MODE, NORMAL_RUN_MODE); + public final static List encodings = Arrays.asList("", "ASCII", "UTF-7", "UTF-8", "UTF-16"); + + private String fsTests; + private String fsTimeout; + private String outEncoding; + private String fsUftRunMode; + private String controllerPollingInterval; + private String perScenarioTimeOut; + private String ignoreErrorStrings; + private String analysisTemplate; + private String displayController; + private String mcServerName; + private String fsReportPath; + + private String fsDeviceId; + private String fsOs; + private String fsManufacturerAndModel; + private String fsTargetLab; + private String fsAutActions; + private String fsLaunchAppName; + private String fsInstrumented; + private String fsDevicesMetrics; + private String fsExtraApps; + private String fsJobId; + private ProxySettings proxySettings; + private boolean useSSL; + private AuthModel authModel; + private CloudBrowserModel cloudBrowserModel; + + /** + * Instantiates a new Run from file system model. + * + * @param fsTests the fs tests path + * @param fsTimeout the fs timeout in minutes for tests in seconds + * @param controllerPollingInterval the controller polling interval in minutes + * @param perScenarioTimeOut the per scenario time out in minutes + * @param ignoreErrorStrings the ignore error strings + * @param analysisTemplate the analysis template + * @param displayController the display controller + * @param mcServerName the mc server name + * @param fsDeviceId the fs device id + * @param fsTargetLab the fs target lab + * @param fsManufacturerAndModel the fs manufacturer and model + * @param fsOs the fs os + * @param fsAutActions the fs aut actions + * @param fsLaunchAppName the fs launch app name + * @param fsDevicesMetrics the fs devices metrics + * @param fsInstrumented the fs instrumented + * @param fsExtraApps the fs extra apps + * @param fsJobId the fs job id + * @param proxySettings the proxy settings + * @param useSSL the use ssl + */ + @SuppressWarnings("squid:S00107") + public RunFromFileSystemModel(String fsTests, String fsTimeout, String fsUftRunMode, String controllerPollingInterval, String perScenarioTimeOut, + String ignoreErrorStrings, String analysisTemplate, String displayController, String mcServerName, AuthModel authModel, + String fsDeviceId, String fsTargetLab, String fsManufacturerAndModel, String fsOs, + String fsAutActions, String fsLaunchAppName, String fsDevicesMetrics, String fsInstrumented, + String fsExtraApps, String fsJobId, ProxySettings proxySettings, boolean useSSL, String fsReportPath, CloudBrowserModel cloudBrowserModel) { + this.setFsTests(fsTests); + + this.fsTimeout = fsTimeout; + this.fsReportPath = fsReportPath; + this.fsUftRunMode = fsUftRunMode; + + this.perScenarioTimeOut = perScenarioTimeOut; + this.controllerPollingInterval = controllerPollingInterval; + this.ignoreErrorStrings = ignoreErrorStrings; + this.analysisTemplate = analysisTemplate; + this.displayController = displayController; + + this.mcServerName = mcServerName; + + this.fsDeviceId = fsDeviceId; + this.fsOs = fsOs; + this.fsManufacturerAndModel = fsManufacturerAndModel; + this.fsTargetLab = fsTargetLab; + this.fsAutActions = fsAutActions; + this.fsLaunchAppName = fsLaunchAppName; + this.fsAutActions = fsAutActions; + this.fsDevicesMetrics = fsDevicesMetrics; + this.fsInstrumented = fsInstrumented; + this.fsExtraApps = fsExtraApps; + this.fsJobId = fsJobId; + this.proxySettings = proxySettings; + this.useSSL = useSSL; + this.authModel = authModel; + this.cloudBrowserModel = cloudBrowserModel; + } + + /** + * Instantiates a new file system model. + * + * @param fsTests the fs tests + */ + @DataBoundConstructor + public RunFromFileSystemModel(String fsTests) { + this.setFsTests(fsTests); + this.outEncoding = StringUtils.defaultString(outEncoding); + + //Init default vals + this.fsTimeout = ""; + this.fsUftRunMode = fsUftRunModes.get(0).getValue(); + this.controllerPollingInterval = "30"; + this.perScenarioTimeOut = "10"; + this.ignoreErrorStrings = ""; + this.displayController = "false"; + this.analysisTemplate = ""; + this.fsReportPath = ""; // no custom report path by default + this.outEncoding = ""; + } + + /** + * Sets fs tests. + * + * @param fsTests the fs tests + */ + public void setFsTests(String fsTests) { + this.fsTests = fsTests.trim(); + + if (!this.fsTests.contains("\n")) { + this.fsTests += "\n"; + } + } + + /** + * Sets fs timeout. + * + * @param fsTimeout the fs timeout + */ + public void setFsTimeout(String fsTimeout) { + this.fsTimeout = fsTimeout; + } + + public void setOutEncoding(String encoding) { + this.outEncoding = encoding; + } + + public String getOutEncoding() { return outEncoding; } + + + /** + * Sets fs runMode. + * + * @param fsUftRunMode the fs runMode + */ + public void setFsUftRunMode(String fsUftRunMode) { + this.fsUftRunMode = fsUftRunMode; + } + + /** + * Sets mc server name. + * + * @param mcServerName the mc server name + */ + public void setMcServerName(String mcServerName) { + this.mcServerName = mcServerName; + } + + + /** + * Sets fs device id. + * + * @param fsDeviceId the fs device id + */ + public void setFsDeviceId(String fsDeviceId) { + this.fsDeviceId = fsDeviceId; + } + + /** + * Sets fs os. + * + * @param fsOs the fs os + */ + public void setFsOs(String fsOs) { + this.fsOs = fsOs; + } + + /** + * Sets fs manufacturer and model. + * + * @param fsManufacturerAndModel the fs manufacturer and model + */ + public void setFsManufacturerAndModel(String fsManufacturerAndModel) { + this.fsManufacturerAndModel = fsManufacturerAndModel; + } + + /** + * Sets fs target lab. + * + * @param fsTargetLab the fs target lab + */ + public void setFsTargetLab(String fsTargetLab) { + this.fsTargetLab = fsTargetLab; + } + + /** + * Sets fs aut actions. + * + * @param fsAutActions the fs aut actions + */ + public void setFsAutActions(String fsAutActions) { + this.fsAutActions = fsAutActions; + } + + /** + * Sets fs launch app name. + * + * @param fsLaunchAppName the fs launch app name + */ + public void setFsLaunchAppName(String fsLaunchAppName) { + this.fsLaunchAppName = fsLaunchAppName; + } + + /** + * Sets fs instrumented. + * + * @param fsInstrumented the fs instrumented + */ + public void setFsInstrumented(String fsInstrumented) { + this.fsInstrumented = fsInstrumented; + } + + /** + * Sets fs devices metrics. + * + * @param fsDevicesMetrics the fs devices metrics + */ + public void setFsDevicesMetrics(String fsDevicesMetrics) { + this.fsDevicesMetrics = fsDevicesMetrics; + } + + /** + * Sets fs extra apps. + * + * @param fsExtraApps the fs extra apps + */ + public void setFsExtraApps(String fsExtraApps) { + this.fsExtraApps = fsExtraApps; + } + + /** + * Sets fs job id. + * + * @param fsJobId the fs job id + */ + public void setFsJobId(String fsJobId) { + this.fsJobId = fsJobId; + } + + /** + * Sets proxy settings. + * + * @param proxySettings the proxy settings + */ + public void setProxySettings(ProxySettings proxySettings) { + this.proxySettings = proxySettings; + } + + /** + * Sets use ssl. + * + * @param useSSL the use ssl + */ + public void setUseSSL(boolean useSSL) { + this.useSSL = useSSL; + } + + /** + * Gets fs tests. + * + * @return the fs tests + */ + public String getFsTests() { + return fsTests; + } + + /** + * Gets fs timeout. + * + * @return the fs timeout + */ + public String getFsTimeout() { + return fsTimeout; + } + + /** + * Gets fs runMode. + * + * @return the fs runMode + */ + public String getFsUftRunMode() { + return fsUftRunMode; + } + + /** + * Gets fs runModes + * + * @return the fs runModes + */ + public List getFsUftRunModes() { + return fsUftRunModes; + } + + /** + * Gets mc server name. + * + * @return the mc server name + */ + public String getMcServerName() { + return mcServerName; + } + + /** + * Sets the report path for the given tests. + */ + public void setFsReportPath(String fsReportPath) { + this.fsReportPath = fsReportPath; + } + + public CloudBrowserModel getCloudBrowserModel() { + return cloudBrowserModel; + } + + public void setCloudBrowserModel(CloudBrowserModel cloudBrowserModel) { this.cloudBrowserModel = cloudBrowserModel; } + + public String getMcPassword() { + //Temp fix till supported in pipeline module in LR + if (authModel == null || authModel.getMcPassword() == null) { + return null; + } + return authModel.getMcEncryptedPassword(); + } + + public String getMcExecToken() { + //Temp fix till supported in pipeline module in LR + if (authModel == null || authModel.getMcExecToken() == null) { + return null; + } + return authModel.getMcEncryptedExecToken(); + } + + /** + * Gets fs device id. + * + * @return the fs device id + */ + public String getFsDeviceId() { + return fsDeviceId; + } + + /** + * Gets fs os. + * + * @return the fs os + */ + public String getFsOs() { + return fsOs; + } + + /** + * Gets fs manufacturer and model. + * + * @return the fs manufacturer and model + */ + public String getFsManufacturerAndModel() { + return fsManufacturerAndModel; + } + + /** + * Gets fs target lab. + * + * @return the fs target lab + */ + public String getFsTargetLab() { + return fsTargetLab; + } + + /** + * Gets fs aut actions. + * + * @return the fs aut actions + */ + public String getFsAutActions() { + return fsAutActions; + } + + /** + * Gets fs launch app name. + * + * @return the fs launch app name + */ + public String getFsLaunchAppName() { + return fsLaunchAppName; + } + + /** + * Gets fs instrumented. + * + * @return the fs instrumented + */ + public String getFsInstrumented() { + return fsInstrumented; + } + + /** + * Gets fs devices metrics. + * + * @return the fs devices metrics + */ + public String getFsDevicesMetrics() { + return fsDevicesMetrics; + } + + /** + * Gets fs extra apps. + * + * @return the fs extra apps + */ + public String getFsExtraApps() { + return fsExtraApps; + } + + /** + * Gets fs job id. + * + * @return the fs job id + */ + public String getFsJobId() { + return fsJobId; + } + + /** + * Is use proxy boolean. + * + * @return the boolean + */ + public boolean isUseProxy() { + return proxySettings != null; + } + + /** + * Is use authentication boolean. + * + * @return the boolean + */ + public boolean isUseProxyAuth() { + return proxySettings != null && proxySettings.isFsUseAuthentication(); + } + + /** + * Gets proxy settings. + * + * @return the proxy settings + */ + public ProxySettings getProxySettings() { + return proxySettings; + } + + /** + * Is use ssl boolean. + * + * @return the boolean + */ + public boolean isUseSSL() { + return useSSL; + } + + + /** + * Gets controller polling interval. + * + * @return the controllerPollingInterval + */ + public String getControllerPollingInterval() { + return controllerPollingInterval; + } + + /** + * Gets the test report path. + */ + public String getFsReportPath() { + return fsReportPath; + } + + /** + * Sets controller polling interval. + * + * @param controllerPollingInterval the controllerPollingInterval to set + */ + public void setControllerPollingInterval(String controllerPollingInterval) { + this.controllerPollingInterval = controllerPollingInterval; + } + + /** + * Gets analysis template. + * + * @return the analysis template + */ + public String getAnalysisTemplate() { + return analysisTemplate; + } + + /** + * Sets analysis template. + * + * @param analysisTemplate the analysis template + */ + public void setAnalysisTemplate(String analysisTemplate) { + this.analysisTemplate = analysisTemplate; + } + + /** + * Gets display controller. + * + * @return the displayController + */ + public String getDisplayController() { + return displayController; + } + + /** + * Sets display controller. + * + * @param displayController the displayController to set + */ + public void setDisplayController(String displayController) { + this.displayController = displayController; + } + + /** + * Gets ignore error strings. + * + * @return the ignoreErrorStrings + */ + public String getIgnoreErrorStrings() { + return ignoreErrorStrings; + } + + + /** + * Sets ignore error strings. + * + * @param ignoreErrorStrings the ignoreErrorStrings to set + */ + public void setIgnoreErrorStrings(String ignoreErrorStrings) { + this.ignoreErrorStrings = ignoreErrorStrings; + } + + + /** + * Gets per scenario time out. + * + * @return the perScenarioTimeOut + */ + public String getPerScenarioTimeOut() { + return perScenarioTimeOut; + } + + /** + * Sets per scenario time out. + * + * @param perScenarioTimeOut the perScenarioTimeOut to set + */ + public void setPerScenarioTimeOut(String perScenarioTimeOut) { + this.perScenarioTimeOut = perScenarioTimeOut; + } + + public AuthModel getAuthModel() { + return authModel; + } + + public void setAuthModel(AuthModel authModel) { + this.authModel = authModel; + } + public String getAuthType() { + return authModel == null ? "base" : authModel.getValue(); + } + /** + * Gets properties. + * + * @param envVars the env vars + * @return the properties + */ + @Nullable + public Properties getProperties(EnvVars envVars, Node currNode) { + return createProperties(envVars, currNode); + } + + private Properties createProperties(EnvVars envVars, Node currNode) { + Properties props = new Properties(); + + addTestsToProps(envVars, props); + + addUFTSpecificSettingsToProps(envVars, props); + + if (addMobileSpecificSettingsToProps(currNode, props)) return null; // cannot continue without proper config + + return props; + } + + private boolean addMobileSpecificSettingsToProps(Node currNode, Properties props) { + if (isUseProxy()){ + props.put("MobileUseProxy", "1"); + props.put("MobileProxyType", "2"); + props.put("MobileProxySetting_Address", proxySettings.getFsProxyAddress()); + + if (isUseProxyAuth() && StringUtils.isNotBlank(proxySettings.getFsProxyUserName())){ + props.put(MOBILE_PROXY_SETTING_AUTHENTICATION, "1"); + props.put(MOBILE_PROXY_SETTING_USER_NAME,proxySettings.getFsProxyUserName()); + String encryptedPassword; + + try { + encryptedPassword = EncryptionUtils.encrypt(proxySettings.getFsProxyPassword(), currNode); + } catch (Exception ex) { + return true; + } + + props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD, encryptedPassword); + } else { + props.put(MOBILE_PROXY_SETTING_AUTHENTICATION, "0"); + props.put(MOBILE_PROXY_SETTING_USER_NAME, ""); + props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD, ""); + } + } else { + props.put("MobileUseProxy", "0"); + props.put("MobileProxyType", "0"); + props.put(MOBILE_PROXY_SETTING_AUTHENTICATION, "0"); + props.put("MobileProxySetting_Address", ""); + props.put(MOBILE_PROXY_SETTING_USER_NAME, ""); + props.put(MOBILE_PROXY_SETTING_PASSWORD_FIELD, ""); + } + + if (useSSL) { + props.put(MOBILE_USE_SSL, "1"); + } else { + props.put(MOBILE_USE_SSL, "0"); + } + + if (authModel != null && authModel.getValue().equals("base")) { + if (StringUtils.isNotBlank(authModel.getMcUserName())) { + props.put("MobileUserName", authModel.getMcUserName()); + } + if (StringUtils.isNotBlank(authModel.getMcTenantId())) { + props.put("MobileTenantId", authModel.getMcTenantId()); + } + } + + return false; + } + + private void addUFTSpecificSettingsToProps(EnvVars envVars, Properties props) { + String fsTimeoutVal = StringUtils.isEmpty(fsTimeout) ? "-1" : envVars.expand(fsTimeout); + props.put("fsTimeout", fsTimeoutVal); + + String fsUFTRunModeVal = StringUtils.isEmpty(fsUftRunMode) ? "Fast" : "" + fsUftRunMode; + props.put("fsUftRunMode", fsUFTRunModeVal); + + String controllerPollingIntervalValue = StringUtils.isEmpty(controllerPollingInterval) ? "30" : controllerPollingInterval; + props.put("controllerPollingInterval", controllerPollingIntervalValue); + + String analysisTemplateVal = StringUtils.isEmpty(analysisTemplate) ? "" : analysisTemplate; + props.put("analysisTemplate", analysisTemplateVal); + + String displayControllerVal = (StringUtils.isEmpty(displayController) || displayController.equals("false")) ? "0" : "1"; + props.put("displayController", displayControllerVal); + + String perScenarioTimeOutVal = StringUtils.isEmpty(perScenarioTimeOut) ? "10" : envVars.expand(perScenarioTimeOut); + props.put("PerScenarioTimeOut", perScenarioTimeOutVal); + + if (!StringUtils.isEmpty(ignoreErrorStrings.replaceAll("\\r|\\n", ""))){ + props.put("ignoreErrorStrings", "" + ignoreErrorStrings.replaceAll("\r", "")); + } + + if (StringUtils.isNotBlank(fsReportPath)) { + props.put("fsReportPath", fsReportPath); + } + } + + private void addTestsToProps(EnvVars envVars, Properties props) { + if (!StringUtils.isEmpty(this.fsTests)) { + String expandedFsTests = envVars.expand(fsTests); + String[] testsArr; + if (UftToolUtils.isMtbxContent(expandedFsTests)) { + testsArr = new String[]{expandedFsTests}; + } else { + testsArr = expandedFsTests.replaceAll("\r", "").split("\n"); + } + + int i = 1; + + for (String test : testsArr) { + test = test.trim(); + props.put("Test" + i, test); + i++; + } + } else { + props.put("fsTests", ""); + } + } + + /** + * Get proxy details json object. + * + * @param mcUrl the mc url + * @return the json object + */ + public JSONObject getJobDetails(String mcUrl) { + return JobConfigurationProxy.getInstance().getJobById(mcUrl, authModel, proxySettings, fsJobId); + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "UFT File System Model"; + } + + public List getFsUftRunModes() { + return fsUftRunModes; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/RunMode.java b/src/main/java/com/microfocus/application/automation/tools/model/RunMode.java new file mode 100644 index 0000000000..0474618522 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/RunMode.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public class RunMode { + + public RunMode(String value, String description) { + this.value = value; + this.description = description; + } + + private String description; + private String value; + + public String getDescription() { + return description; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SSOCredentialsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SSOCredentialsModel.java new file mode 100644 index 0000000000..1a9ef4f48c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SSOCredentialsModel.java @@ -0,0 +1,73 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.Secret; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.Serializable; + +public class SSOCredentialsModel extends AbstractDescribableImpl implements Serializable { + private String almClientID; + private Secret almApiKeySecret; + + @DataBoundConstructor + public SSOCredentialsModel(String almClientID, String almApiKeySecret) { + this.almClientID = almClientID; + this.almApiKeySecret = Secret.fromString(almApiKeySecret); + } + + public String getAlmClientID(){ + return almClientID; + } + + public Secret getAlmApiKeySecret(){ + return almApiKeySecret; + } + + public String getAlmApiKeySecretPlainText(){ + return almApiKeySecret.getPlainText(); + } + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "SSO Credentials Model"; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SecretContainer.java b/src/main/java/com/microfocus/application/automation/tools/model/SecretContainer.java new file mode 100644 index 0000000000..d5c027fe47 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SecretContainer.java @@ -0,0 +1,38 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public interface SecretContainer { + + void initialize(String secret); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SecretContainerImpl.java b/src/main/java/com/microfocus/application/automation/tools/model/SecretContainerImpl.java new file mode 100644 index 0000000000..999bcc6dcf --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SecretContainerImpl.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.util.Secret; + +public class SecretContainerImpl implements SecretContainer { + + private Secret _secret; + + public void initialize(String secret) { + + _secret = Secret.fromString(secret); + } + + @Override + public String toString() { + + return _secret.getPlainText(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SseModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SseModel.java new file mode 100644 index 0000000000..3a32821253 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SseModel.java @@ -0,0 +1,216 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.util.Arrays; +import java.util.List; + +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class SseModel { + + public static final String TEST_SET = "TEST_SET"; + public static final String BVS = "BVS"; + public static final String PC = "PC"; + + public static final String COLLATE = "Collate"; + public static final String COLLATE_ANALYZE = "CollateAndAnalyze"; + public static final String DO_NOTHING = "DoNothing"; + + private final String _almServerName; + private String _almServerUrl; + private final String _almUserName; + private final SecretContainer _almPassword; + private final String _almDomain; + private final String _clientType; + private final String _almProject; + private final String _timeslotDuration; + private final String _description; + private final String _runType; + private final String _almEntityId; + private final String _postRunAction; + private final String _environmentConfigurationId; + private final CdaDetails _cdaDetails; + + private final static EnumDescription _runTypeTestSet = + new EnumDescription(TEST_SET, "Test Set"); + private final static EnumDescription _runTypeBVS = new EnumDescription( + BVS, + "Build Verification Suite"); + private final static List _runTypes = Arrays.asList( + _runTypeTestSet, + _runTypeBVS); + + private final static EnumDescription _postRunActionCollate = new EnumDescription( + COLLATE, + "Collate"); + private final static EnumDescription _postRunActionCollateAnalyze = new EnumDescription( + COLLATE_ANALYZE, + "CollateAndAnalyze"); + private final static EnumDescription _postRunActionDoNothing = new EnumDescription( + DO_NOTHING, + "DoNothing"); + private final static List _postRunActions = Arrays.asList( + _postRunActionCollate, + _postRunActionCollateAnalyze, + _postRunActionDoNothing); + + @DataBoundConstructor + public SseModel( + String almServerName, + String almUserName, + String almPassword, + String almDomain, + String clientType, + String almProject, + String runType, + String almEntityId, + String timeslotDuration, + String description, + String postRunAction, + String environmentConfigurationId, + CdaDetails cdaDetails) { + + _almServerName = almServerName; + _almDomain = almDomain; + _clientType = clientType; + _almProject = almProject; + _timeslotDuration = timeslotDuration; + _almEntityId = almEntityId; + _almUserName = almUserName; + _almPassword = setPassword(almPassword); + _runType = runType; + _description = description; + _postRunAction = postRunAction; + _environmentConfigurationId = environmentConfigurationId; + _cdaDetails = cdaDetails; + + } + + protected SecretContainer setPassword(String almPassword) { + + SecretContainer secretContainer = new SecretContainerImpl(); + secretContainer.initialize(almPassword); + + return secretContainer; + } + + public String getAlmServerName() { + + return _almServerName; + } + + public String getAlmServerUrl() { + + return _almServerUrl; + } + + public void setAlmServerUrl(String almServerUrl) { + + _almServerUrl = almServerUrl; + } + + public String getAlmUserName() { + + return _almUserName; + } + + public String getAlmPassword() { + + return _almPassword.toString(); + } + + public String getAlmDomain() { + + return _almDomain; + } + + public String getClientType() { + return _clientType; + } + + public String getAlmProject() { + + return _almProject; + } + + public String getTimeslotDuration() { + + return _timeslotDuration; + } + + public String getAlmEntityId() { + + return _almEntityId; + } + + public String getRunType() { + return _runType; + } + + public String getDescription() { + + return _description; + } + + public String getEnvironmentConfigurationId() { + + return _environmentConfigurationId; + } + + public static List getRunTypes() { + + return _runTypes; + } + + public static List getPostRunActions() { + + return _postRunActions; + } + + public CdaDetails getCdaDetails() { + + return _cdaDetails; + } + + public String getPostRunAction() { + + return _postRunAction; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SseProxySettings.java b/src/main/java/com/microfocus/application/automation/tools/model/SseProxySettings.java new file mode 100644 index 0000000000..828137dcd6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SseProxySettings.java @@ -0,0 +1,94 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import org.kohsuke.stapler.DataBoundConstructor; + +import hudson.util.Secret; + +/** + * This model is for sse build step's proxy setting. + * It's different from the class ProxySettings. Here we use credentials instead of name/password. + * @author llu4 + * + */ +public class SseProxySettings { + private String fsProxyAddress; + private String fsProxyCredentialsId; + + /** + * To store the user name which get from the credentials. + * Is set in sseBuilder while performing. + */ + private String fsProxyUserName; + + /** + * To store the password which get from the credentials. + * Is set in sseBuilder while performing. + */ + private Secret fsProxyPassword; + + /** + * These two variables are set directly by the jelly form. + */ + @DataBoundConstructor + public SseProxySettings(String fsProxyAddress, String fsProxyCredentialsId) { + this.fsProxyAddress = fsProxyAddress; + this.fsProxyCredentialsId = fsProxyCredentialsId; + } + + public String getFsProxyAddress() { + return fsProxyAddress; + } + + public String getFsProxyCredentialsId() { + return fsProxyCredentialsId; + } + + public String getFsProxyUserName() { + return fsProxyUserName; + } + + public void setFsProxyUserName(String fsProxyUserName) { + this.fsProxyUserName = fsProxyUserName; + } + + public Secret getFsProxyPassword() { + return fsProxyPassword; + } + + public void setFsProxyPassword(Secret fsProxyPassword) { + this.fsProxyPassword = fsProxyPassword; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvChangeModeModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvChangeModeModel.java new file mode 100644 index 0000000000..85a41af746 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvChangeModeModel.java @@ -0,0 +1,67 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvChangeModeModel extends AbstractSvRunModel { + + private static final SvDataModelSelection NONE_DATA_MODEL = new SvDataModelSelection(SvDataModelSelection.SelectionType.NONE, null); + private static final SvPerformanceModelSelection NONE_PERFORMANCE_MODEL = new SvPerformanceModelSelection(SvPerformanceModelSelection.SelectionType.NONE, null); + private final ServiceRuntimeConfiguration.RuntimeMode mode; + private final SvDataModelSelection dataModel; + private final SvPerformanceModelSelection performanceModel; + + @DataBoundConstructor + public SvChangeModeModel(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, + SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { + super(serverName, force, serviceSelection); + this.mode = mode; + this.dataModel = dataModel; + this.performanceModel = performanceModel; + } + + public ServiceRuntimeConfiguration.RuntimeMode getMode() { + return mode; + } + + public SvDataModelSelection getDataModel() { + return (mode == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY) ? NONE_DATA_MODEL : dataModel; + } + + public SvPerformanceModelSelection getPerformanceModel() { + return (mode == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY) ? NONE_PERFORMANCE_MODEL : performanceModel; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvDataModelSelection.java b/src/main/java/com/microfocus/application/automation/tools/model/SvDataModelSelection.java new file mode 100644 index 0000000000..f0f2c811f5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvDataModelSelection.java @@ -0,0 +1,138 @@ +/* + * 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. + * ___________________________________________________________________ + */ +package com.microfocus.application.automation.tools.model; + +import javax.annotation.Nonnull; + +import java.io.Serializable; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvDataModelSelection extends AbstractDescribableImpl implements Serializable { + + protected final SelectionType selectionType; + protected final String dataModel; + + @DataBoundConstructor + public SvDataModelSelection(SelectionType selectionType, String dataModel) { + this.selectionType = selectionType; + this.dataModel = StringUtils.trim(dataModel); + } + + public static void validateField(FormValidation result) { + if (!result.equals(FormValidation.ok())) { + throw new IllegalArgumentException(StringEscapeUtils.unescapeXml(result.getMessage())); + } + } + + @SuppressWarnings("unused") + public SelectionType getSelectionType() { + return selectionType; + } + + public String getDataModel() { + return (StringUtils.isNotBlank(dataModel)) ? dataModel : null; + } + + @SuppressWarnings("unused") + public boolean isSelected(String type) { + return SelectionType.valueOf(type) == this.selectionType; + } + + public boolean isNoneSelected() { + return selectionType == SelectionType.NONE; + } + + public boolean isDefaultSelected() { + return selectionType == SelectionType.DEFAULT; + } + + @Override + public String toString() { + switch (selectionType) { + case BY_NAME: + return dataModel; + case NONE: + return ""; + case DEFAULT: + default: + return ""; + } + } + + public String getSelectedModelName() { + switch (selectionType) { + case BY_NAME: + validateField(DescriptorImpl.doCheckDataModelImpl(dataModel)); + return dataModel; + default: + return null; + } + } + + public enum SelectionType implements Serializable { + BY_NAME, + NONE, + /** + * Default means first model in alphabetical order by model name + */ + DEFAULT, + } + + @Extension + public static class DescriptorImpl extends Descriptor { + + @Nonnull + public String getDisplayName() { + return "Data model Selection"; + } + + @SuppressWarnings("unused") + public FormValidation doCheckDataModel(@QueryParameter String dataModel) { + return doCheckDataModelImpl(dataModel); + } + + private static FormValidation doCheckDataModelImpl(@QueryParameter String dataModel) { + if (StringUtils.isBlank(dataModel)) { + return FormValidation.error("Data model cannot be empty if 'Specific' model is selected"); + } + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvDeployModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvDeployModel.java new file mode 100644 index 0000000000..7539198b77 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvDeployModel.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvDeployModel extends AbstractSvRunModel { + + protected final boolean firstAgentFallback; + + @DataBoundConstructor + public SvDeployModel(String serverName, boolean force, String service, String projectPath, String projectPassword, boolean firstAgentFallback) { + super(serverName, force, new SvServiceSelectionModel(SvServiceSelectionModel.SelectionType.DEPLOY, service, projectPath, projectPassword)); + this.firstAgentFallback = firstAgentFallback; + } + + public String getService() { + return (serviceSelection != null) ? serviceSelection.getService() : null; + } + + public String getProjectPath() { + return (serviceSelection != null) ? serviceSelection.getProjectPath() : null; + } + + public String getProjectPassword() { + return (serviceSelection != null) ? serviceSelection.getProjectPassword() : null; + } + + public boolean isFirstAgentFallback() { + return firstAgentFallback; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvExportModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvExportModel.java new file mode 100644 index 0000000000..5f671c6418 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvExportModel.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvExportModel extends AbstractSvRunModel { + + private final String targetDirectory; + private final boolean cleanTargetDirectory; + private final boolean switchToStandByFirst; + private final boolean archive; + + @DataBoundConstructor + public SvExportModel(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, + SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst, boolean archive) { + super(serverName, force, serviceSelection); + this.targetDirectory = StringUtils.trim(targetDirectory); + this.cleanTargetDirectory = cleanTargetDirectory; + this.switchToStandByFirst = switchToStandByFirst; + this.archive = archive; + } + + public String getTargetDirectory() { + return (StringUtils.isNotBlank(targetDirectory)) ? targetDirectory : null; + } + + public boolean isCleanTargetDirectory() { + return cleanTargetDirectory; + } + + public boolean isSwitchToStandByFirst() { + return switchToStandByFirst; + } + + public boolean isArchive() { + return archive; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvPerformanceModelSelection.java b/src/main/java/com/microfocus/application/automation/tools/model/SvPerformanceModelSelection.java new file mode 100644 index 0000000000..570db55870 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvPerformanceModelSelection.java @@ -0,0 +1,137 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import javax.annotation.Nonnull; + +import java.io.Serializable; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvPerformanceModelSelection extends AbstractDescribableImpl implements Serializable { + + protected final SelectionType selectionType; + protected final String performanceModel; + + @DataBoundConstructor + public SvPerformanceModelSelection(SelectionType selectionType, String performanceModel) { + this.selectionType = selectionType; + this.performanceModel = StringUtils.trim(performanceModel); + } + + @SuppressWarnings("unused") + public SelectionType getSelectionType() { + return selectionType; + } + + @SuppressWarnings("unused") + public String getPerformanceModel() { + return (StringUtils.isNotBlank(performanceModel)) ? performanceModel : null; + } + + @SuppressWarnings("unused") + public boolean isSelected(String type) { + return SelectionType.valueOf(type) == this.selectionType; + } + + public boolean isNoneSelected() { + return selectionType == SelectionType.NONE; + } + + public boolean isDefaultSelected() { + return selectionType == SelectionType.DEFAULT; + } + + @Override + public String toString() { + switch (selectionType) { + case BY_NAME: + return performanceModel; + case NONE: + return ""; + case OFFLINE: + return ""; + default: + return ""; + } + } + + public String getSelectedModelName() { + switch (selectionType) { + case BY_NAME: + SvDataModelSelection.validateField(DescriptorImpl.doCheckPerformanceModelImpl(performanceModel)); + return performanceModel; + case OFFLINE: + return "Offline"; + default: + return null; + } + } + + public enum SelectionType { + BY_NAME, + NONE, + OFFLINE, + /** + * Default means first model in alphabetical order by model name + */ + DEFAULT, + } + + @Extension + public static class DescriptorImpl extends Descriptor { + + @Nonnull + public String getDisplayName() { + return "Performance Model Selection"; + } + + @SuppressWarnings("unused") + public FormValidation doCheckPerformanceModel(@QueryParameter String performanceModel) { + return doCheckPerformanceModelImpl(performanceModel); + } + + private static FormValidation doCheckPerformanceModelImpl(@QueryParameter String performanceModel) { + if (StringUtils.isBlank(performanceModel)) { + return FormValidation.error("Performance model cannot be empty if 'Specific' model is selected"); + } + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvServerSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvServerSettingsModel.java new file mode 100644 index 0000000000..4ae151e837 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvServerSettingsModel.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; + +import com.microfocus.sv.svconfigurator.core.impl.processor.Credentials; +import hudson.util.Secret; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvServerSettingsModel implements Serializable{ + + private final String name; + private final String url; + private final boolean trustEveryone; + private final String username; + private final Secret password; + + @DataBoundConstructor + public SvServerSettingsModel(String name, String url, boolean trustEveryone, String username, Secret password) { + this.name = StringUtils.trim(name); + this.url = StringUtils.trim(url); + this.trustEveryone = trustEveryone; + this.username = username; + this.password = password; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + + public URL getUrlObject() throws MalformedURLException { + return new URL(url); + } + + public boolean isTrustEveryone() { + return trustEveryone; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password.getPlainText(); + } + + public Credentials getCredentials() { + if (StringUtils.isBlank(username) || password == null) { + return null; + } + return new Credentials(username, password.getPlainText()); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvServiceSelectionModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvServiceSelectionModel.java new file mode 100644 index 0000000000..bd0c2df0f0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvServiceSelectionModel.java @@ -0,0 +1,129 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import javax.annotation.Nonnull; + +import java.io.Serializable; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import hudson.util.Secret; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvServiceSelectionModel extends AbstractDescribableImpl implements Serializable { + + protected final SelectionType selectionType; + protected final String service; + protected final String projectPath; + protected final Secret projectPassword; + + @DataBoundConstructor + public SvServiceSelectionModel(SelectionType selectionType, String service, String projectPath, String projectPassword) { + Validate.notNull(selectionType, "SelectionType must be specified"); + this.selectionType = selectionType; + this.service = StringUtils.trim(service); + this.projectPath = StringUtils.trim(projectPath); + this.projectPassword = Secret.fromString(projectPassword); + } + + public SelectionType getSelectionType() { + return selectionType; + } + + public String getService() { + return (StringUtils.isNotBlank(service)) ? service : null; + } + + public String getProjectPath() { + return (StringUtils.isNotBlank(projectPath)) ? projectPath : null; + } + + public String getProjectPassword() { + return (projectPassword != null) ? projectPassword.getPlainText() : null; + } + + @SuppressWarnings("unused") + public boolean isSelected(String selectionType) { + return SelectionType.valueOf(selectionType) == this.selectionType; + } + + public enum SelectionType { + /** + * Select service by name or id + */ + SERVICE, + /** + * Select all services from project + */ + PROJECT, + /** + * Select all deployed services + */ + ALL_DEPLOYED, + /** + * Specific case for deployment. Uses project & optionally service names. + */ + DEPLOY + } + + @Extension + public static class DescriptorImpl extends Descriptor { + + @Nonnull + public String getDisplayName() { + return "Service Selection"; + } + + @SuppressWarnings("unused") + public FormValidation doCheckService(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Service name or id must be set"); + } + return FormValidation.ok(); + } + + @SuppressWarnings("unused") + public FormValidation doCheckProjectPath(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Project path cannot be empty"); + } + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/SvUndeployModel.java b/src/main/java/com/microfocus/application/automation/tools/model/SvUndeployModel.java new file mode 100644 index 0000000000..6cd4bef0e6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/SvUndeployModel.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvUndeployModel extends AbstractSvRunModel { + + protected final boolean continueIfNotDeployed; + + @DataBoundConstructor + public SvUndeployModel(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { + super(serverName, force, serviceSelection); + this.continueIfNotDeployed = continueIfNotDeployed; + } + + public boolean isContinueIfNotDeployed() { + return continueIfNotDeployed; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/model/TestsFramework.java b/src/main/java/com/microfocus/application/automation/tools/model/TestsFramework.java new file mode 100644 index 0000000000..229d849c33 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/TestsFramework.java @@ -0,0 +1,65 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public class TestsFramework { + + private String description; + private String name; + private String format; + + public TestsFramework() { + this.name = ""; + this.description = ""; + this.format = ""; + } + + public TestsFramework(String name, String description, String format) { + this.name = name; + this.description = description; + this.format = format; + } + + public String getDescription() { + return description; + } + + public String getName() { + return name; + } + + public String getFormat() { + return format; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/UploadAppModel.java b/src/main/java/com/microfocus/application/automation/tools/model/UploadAppModel.java new file mode 100644 index 0000000000..ee7574f95a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/UploadAppModel.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 5/17/16 + * Time: 4:43 PM + * To change this template use File | Settings | File Templates. + */ +public class UploadAppModel { + private String mcServerName; + private AuthModel authModel; + private ProxySettings proxySettings; + private List applicationPaths; + + @DataBoundConstructor + public UploadAppModel(String mcServerName, AuthModel authModel, ProxySettings proxySettings, List applicationPaths) { + this.mcServerName = mcServerName; + this.authModel = authModel; + this.proxySettings = proxySettings; + this.applicationPaths = applicationPaths; + } + + public String getMcServerName() { + return mcServerName; + } + + public ProxySettings getProxySettings() { + return proxySettings; + } + + public boolean isUseProxy() { + return proxySettings != null; + } + + public boolean isUseAuthentication() { + return proxySettings != null && StringUtils.isNotBlank(proxySettings.getFsProxyUserName()); + } + + public List getApplicationPaths() { + return applicationPaths; + } + + public AuthModel getAuthModel() { + return authModel; + } + + public String getAuthType() { + return authModel == null ? "base" : authModel.getValue(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/UploadAppPathModel.java b/src/main/java/com/microfocus/application/automation/tools/model/UploadAppPathModel.java new file mode 100644 index 0000000000..866ff364c0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/UploadAppPathModel.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 5/20/16 + * Time: 2:52 PM + * To change this template use File | Settings | File Templates. + */ +public class UploadAppPathModel extends AbstractDescribableImpl { + private String mcAppPath; + private String mcAppWorkspace; + + @DataBoundConstructor + public UploadAppPathModel(String mcAppPath, String mcAppWorkspace) { + this.mcAppPath = mcAppPath; + this.mcAppWorkspace = mcAppWorkspace; + } + + public String getMcAppPath() { + return mcAppPath; + } + + public String getMcAppWorkspace() { + return mcAppWorkspace; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + public String getDisplayName() { + return ""; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/model/UploadTestResultToAlmModel.java b/src/main/java/com/microfocus/application/automation/tools/model/UploadTestResultToAlmModel.java new file mode 100644 index 0000000000..5096755602 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/model/UploadTestResultToAlmModel.java @@ -0,0 +1,261 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +import hudson.EnvVars; +import hudson.Util; +import hudson.util.Secret; +import hudson.util.VariableResolver; + +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +public class UploadTestResultToAlmModel { + + + public final static int DEFAULT_TIMEOUT = 36000; // 10 hrs + public final static String ALM_PASSWORD_KEY = "almPassword"; + + public final static EnumDescription testingFrameworkJunit = new EnumDescription( + "JUnit", "JUnit"); + public final static EnumDescription testingFrameworkTestNG = new EnumDescription( + "TestNG", "TestNG"); + public final static EnumDescription testingFrameworkNUnit = new EnumDescription( + "NUnit", "NUnit"); + public final static List testingFrameworks = Arrays.asList( + testingFrameworkJunit, testingFrameworkTestNG, testingFrameworkNUnit); + + private String almServerName; + private String almUserName; + private Secret almPassword; + private String almDomain; + private String clientType; + private String almProject; + private String almTimeout; + private String almTestFolder; + private String almTestSetFolder; + private String testingFramework; + private String testingTool; + private String testingResultFile; + private String testingAttachments; + private String jenkinsServerUrl; + + @DataBoundConstructor + public UploadTestResultToAlmModel( + String almServerName, String almUserName, + String almPassword, String almDomain, String clientType, String almProject, + String testingFramework, String testingTool, + String almTestFolder , String almTestSetFolder, String almTimeout, + String testingResultFile, String testingAttachments, + String jenkinsServerUrl) { + + this.almServerName = almServerName; + this.almUserName = almUserName; + this.almPassword = Secret.fromString(almPassword); + this.almDomain = almDomain; + this.clientType = clientType; + this.almProject = almProject; + + this.almTimeout=almTimeout; + this.almTestFolder = almTestFolder; + this.almTestSetFolder = almTestSetFolder; + + this.testingFramework = testingFramework; + this.testingTool = testingTool; + + this.testingResultFile = testingResultFile; + this.testingAttachments = testingAttachments; + this.jenkinsServerUrl = jenkinsServerUrl; + } + + public String getAlmUserName() { + return almUserName; + } + + public String getAlmDomain() { + return almDomain; + } + + public String getClientType() { + return clientType; + } + + public String getAlmPassword() { + return almPassword.getPlainText(); + } + + public String getAlmProject() { + return almProject; + } + + public String getTestingFramework() { + return testingFramework; + } + public String getTestingTool() { + return testingTool; + } + + public String getAlmTimeout() { + return almTimeout; + } + + public String getAlmTestFolder() { + return almTestFolder; + } + + public String getAlmTestSetFolder() { + return almTestSetFolder; + } + + public String getAlmServerName() { + return almServerName; + } + + public String getTestingResultFile() { + return testingResultFile; + } + + public String getTestingAttachments() { return testingAttachments; } + + public String getJenkinsServerUrl() { + return jenkinsServerUrl; + } + + public Properties getProperties(EnvVars envVars, + VariableResolver varResolver) { + return CreateProperties(envVars, varResolver); + } + + public Properties getProperties() { + return CreateProperties(null, null); + } + + private Properties CreateProperties(EnvVars envVars, + VariableResolver varResolver) { + Properties props = new Properties(); + + if (envVars == null) { + props.put("almUserName", almUserName); + props.put(ALM_PASSWORD_KEY, almPassword); + props.put("almDomain", almDomain); + props.put("almProject", almProject); + } else { + props.put("almUserName", + Util.replaceMacro(envVars.expand(almUserName), varResolver)); + props.put(ALM_PASSWORD_KEY, almPassword); + props.put("almDomain", + Util.replaceMacro(envVars.expand(almDomain), varResolver)); + props.put("almProject", + Util.replaceMacro(envVars.expand(almProject), varResolver)); + } + + if (!StringUtils.isEmpty(this.testingFramework)) { + props.put("testingFramework" , testingFramework); + + } else { + props.put("testingFramework", ""); + } + + if (!StringUtils.isEmpty(this.testingTool)) { + props.put("testingTool" , testingTool); + + } else { + props.put("testingTool", ""); + } + + if (!StringUtils.isEmpty(this.almTestFolder)) { + props.put("almTestFolder" , almTestFolder); + + } else { + props.put("almTestFolder", ""); + } + + + if (!StringUtils.isEmpty(this.almTestSetFolder)) { + props.put("almTestSetFolder" , almTestSetFolder); + + } else { + props.put("almTestSetFolder", ""); + } + + if (StringUtils.isEmpty(almTimeout)) { + props.put("almTimeout", "-1"); + } else { + props.put("almTimeout", almTimeout); + } + + if (!StringUtils.isEmpty(this.testingResultFile)) { + props.put("testingResultFile" , testingResultFile); + + } else { + props.put("testingResultFile", ""); + } + + if (!StringUtils.isEmpty(this.testingAttachments)) { + props.put("testingAttachments" , testingAttachments); + + } else { + props.put("testingAttachments", ""); + } + + if (!StringUtils.isEmpty(this.jenkinsServerUrl)) { + props.put("jenkinsServerUrl" , jenkinsServerUrl); + + } else { + props.put("jenkinsServerUrl", ""); + } + + + return props; + } + + public String toString(){ + return almServerName + "," + + almUserName + "," + + almPassword + "," + + almDomain + "," + + clientType + "," + + almProject + "," + + almTimeout + "," + + almTestFolder + "," + + almTestSetFolder + "," + + testingFramework + "," + + testingTool+ "," + + testingResultFile + "," + + jenkinsServerUrl; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/nodes/EncryptionNodeProperty.java b/src/main/java/com/microfocus/application/automation/tools/nodes/EncryptionNodeProperty.java new file mode 100644 index 0000000000..8df6a7f83b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/nodes/EncryptionNodeProperty.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.nodes; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.model.Node; +import hudson.slaves.NodeProperty; +import hudson.slaves.NodePropertyDescriptor; +import hudson.util.Secret; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Each node will have a public-private RSA key pair. + */ +@Extension +public class EncryptionNodeProperty extends NodeProperty { + + private Secret publicKey; + + @DataBoundConstructor + public EncryptionNodeProperty() { + // no need to give value to anything + } + + @CheckForNull + public String getPublicKey() { + if (publicKey == null) return null; + + return publicKey.getEncryptedValue(); + } + + /** + * Sets the RSA public key from encryption, will be stored encrypted with Jenkins master. + * @param publicKey to be set + */ + public void setPublicKey(String publicKey) { + this.publicKey = Secret.fromString(publicKey); + } + + @Extension + public static class DescriptorImpl extends NodePropertyDescriptor { + @NonNull + @Override + public String getDisplayName() { + return "Encryption for UFT sensitive data"; + } + + @Override + public boolean isApplicableAsGlobal() { + return false; + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/AbstractResultQueueImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/AbstractResultQueueImpl.java new file mode 100644 index 0000000000..b855bed0f9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/AbstractResultQueueImpl.java @@ -0,0 +1,205 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.squareup.tape.FileObjectQueue; +import net.sf.json.JSONObject; +import net.sf.json.JSONSerializer; +import org.apache.commons.io.IOUtils; + +import java.io.*; + +/** + * Created by benmeior on 11/21/2016 + * + * Base implementation of ResultQueue: backed up by FileObjectQueue, persisted + */ + +public abstract class AbstractResultQueueImpl implements ResultQueue { + + private static final int RETRIES = 3; + private final int MAX_RETRIES; + + private FileObjectQueue queue; + + private QueueItem currentItem; + + public AbstractResultQueueImpl() { + this.MAX_RETRIES = RETRIES; + } + + public AbstractResultQueueImpl(int maxRetries) { + this.MAX_RETRIES = maxRetries; + } + + protected void init(File queueFile) throws IOException { + queue = new FileObjectQueue<>(queueFile, new JsonConverter()); + } + + @Override + public synchronized QueueItem peekFirst() { + if (currentItem == null) { + currentItem = queue.peek(); + } + return currentItem; + } + + @Override + public synchronized boolean failed() { + if (currentItem != null) { + boolean retry; + if (++currentItem.failCount <= MAX_RETRIES) { + queue.add(currentItem); + retry = true; + } else { + retry = false; + } + + remove(); + + return retry; + } else { + throw new IllegalStateException("no outstanding item"); + } + } + + @Override + public synchronized void remove() { + if (currentItem != null) { + queue.remove(); + currentItem = null; + } else { + throw new IllegalStateException("no outstanding item"); + } + } + + @Override + public synchronized void add(QueueItem item) { + queue.add(item); + } + + @Override + public synchronized void add(String projectName, int buildNumber) { + queue.add(new QueueItem(projectName, buildNumber)); + } + + @Override + public synchronized void add(String projectName, String type, int buildNumber) { + queue.add(new QueueItem(projectName, type, buildNumber)); + } + + @Override + public synchronized void add(String projectName, int buildNumber, String workspace) { + queue.add(new QueueItem(projectName, buildNumber, workspace)); + } + + @Override + public synchronized void add(String instanceId, String projectName, int buildNumber, String workspace) { + QueueItem item = new QueueItem(projectName, buildNumber, workspace); + item.setInstanceId(instanceId); + queue.add(item); + } + + public int size() { + return queue.size(); + } + + @Override + public synchronized void clear() { + while (queue.size() > 0) { + queue.remove(); + } + currentItem = null; + } + + @Override + public void close() { + if (queue != null) { + queue.close(); + } + } + + private static class JsonConverter implements FileObjectQueue.Converter { + + public static final String INSTANCE_ID = "instanceId"; + + @Override + public QueueItem from(byte[] bytes) throws IOException { + JSONObject json = (JSONObject) JSONSerializer.toJSON(IOUtils.toString(new ByteArrayInputStream(bytes))); + return objectFromJson(json); + } + + @Override + public void toStream(QueueItem item, OutputStream bytes) throws IOException { + JSONObject json = jsonFromObject(item); + OutputStreamWriter writer = new OutputStreamWriter(bytes); + writer.append(json.toString()); + writer.close(); + } + + private static QueueItem objectFromJson(JSONObject json) { + QueueItem queueItem = json.containsKey("workspace") ? + new QueueItem( + json.getString("project"), + json.getInt("build"), + json.getInt("count"), + json.getString("workspace")) : + new QueueItem( + json.getString("project"), + json.getInt("build"), + json.getInt("count")); + if (json.containsKey("type")) { + queueItem.setType(json.getString("type")); + } + if (json.containsKey("sendAfter")) { + queueItem.setSendAfter(json.getLong("sendAfter")); + } + if (json.containsKey(INSTANCE_ID)) { + queueItem.setInstanceId(json.getString(INSTANCE_ID)); + } + return queueItem; + } + + private static JSONObject jsonFromObject(QueueItem item) { + JSONObject json = new JSONObject(); + json.put("project", item.projectName); + json.put("build", item.buildNumber); + json.put("count", item.failCount); + json.put("workspace", item.workspace); + json.put("type", item.type); + json.put("sendAfter", item.sendAfter); + json.put(INSTANCE_ID, item.instanceId); + return json; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/CIJenkinsServicesImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/CIJenkinsServicesImpl.java new file mode 100644 index 0000000000..3ae7297e71 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/CIJenkinsServicesImpl.java @@ -0,0 +1,932 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.cloudbees.plugins.credentials.CredentialsNameProvider; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials; +import com.cloudbees.plugins.credentials.domains.DomainRequirement; +import com.hp.octane.integrations.CIPluginServices; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.configuration.CIProxyConfiguration; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.entities.EntityConstants; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.MultiBranchType; +import com.hp.octane.integrations.dto.executor.CredentialsInfo; +import com.hp.octane.integrations.dto.executor.DiscoveryInfo; +import com.hp.octane.integrations.dto.executor.TestConnectivityInfo; +import com.hp.octane.integrations.dto.general.*; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameters; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.scm.Branch; +import com.hp.octane.integrations.dto.securityscans.FodServerConfiguration; +import com.hp.octane.integrations.dto.securityscans.SSCProjectConfiguration; +import com.hp.octane.integrations.dto.snapshots.CIBuildResult; +import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; +import com.hp.octane.integrations.exceptions.ConfigurationException; +import com.hp.octane.integrations.exceptions.PermissionException; +import com.hp.octane.integrations.services.configurationparameters.FortifySSCTokenParameter; +import com.hp.octane.integrations.services.configurationparameters.UftTestRunnerFolderParameter; +import com.hp.octane.integrations.services.configurationparameters.factory.ConfigurationParameterFactory; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.*; +import com.microfocus.application.automation.tools.octane.executor.ExecutorConnectivityService; +import com.microfocus.application.automation.tools.octane.executor.TestExecutionJobCreatorService; +import com.microfocus.application.automation.tools.octane.executor.UftJobRecognizer; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.projects.AbstractProjectProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.model.processors.scm.SCMUtils; +import com.microfocus.application.automation.tools.octane.testrunner.TestsToRunConverterBuilder; +import com.microfocus.application.automation.tools.octane.tests.TestListener; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitExtension; +import com.microfocus.application.automation.tools.settings.RunnerMiscSettingsGlobalConfiguration; +import hudson.ProxyConfiguration; +import hudson.console.PlainTextConsoleOutputStream; +import hudson.matrix.MatrixConfiguration; +import hudson.maven.MavenModule; +import hudson.model.*; +import hudson.security.ACLContext; +import hudson.util.IOUtils; +import jenkins.model.Jenkins; +import org.acegisecurity.AccessDeniedException; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; + +import java.io.*; +import java.net.URL; +import java.nio.file.Files; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Base implementation of SPI(service provider interface) of Octane CI SDK for Jenkins + */ + +public class CIJenkinsServicesImpl extends CIPluginServices { + + //we going to print octaneAllowedStorage to system log, this flag help to avoid multiple prints + private static boolean skipOctaneAllowedStoragePrint = false; + private static Object skipOctaneAllowedStoragePrintLock = new Object();//this must be before SDKBasedLoggerProvider.getLogger + + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + private static final Logger logger = SDKBasedLoggerProvider.getLogger(CIJenkinsServicesImpl.class); + private static final java.util.logging.Logger systemLogger = java.util.logging.Logger.getLogger(CIJenkinsServicesImpl.class.getName()); + + private static final String DEFAULT_BRANCHES_SEPARATOR = " "; + + @Override + public CIServerInfo getServerInfo() { + return getJenkinsServerInfo(); + } + + @Override + public CIPluginInfo getPluginInfo() { + CIPluginInfo result = dtoFactory.newDTO(CIPluginInfo.class); + result.setVersion(ConfigurationService.getPluginVersion()); + return result; + } + + @Override + public void suspendCIEvents(boolean suspend) { + OctaneServerSettingsModel model = ConfigurationService.getSettings(getInstanceId()); + model.setSuspend(suspend); + ConfigurationService.configurePlugin(model); + logger.info("suspend ci event: " + suspend); + } + + @Override + public File getAllowedOctaneStorage() { + return getAllowedStorageFile(); + } + + @Override + public CIProxyConfiguration getProxyConfiguration(URL targetUrl) { + return getProxySupplier(targetUrl); + } + + public static CIProxyConfiguration getProxySupplier(URL targetUrl) { + CIProxyConfiguration result = null; + ProxyConfiguration proxy = Jenkins.get().proxy; + if (proxy != null) { + boolean noProxyHost = false; + for (Pattern pattern : proxy.getNoProxyHostPatterns()) { + if (pattern.matcher(targetUrl.getHost()).matches()) { + noProxyHost = true; + break; + } + } + if (!noProxyHost) { + result = dtoFactory.newDTO(CIProxyConfiguration.class) + .setHost(proxy.name) + .setPort(proxy.port) + .setUsername(proxy.getUserName()) + .setPassword(proxy.getPassword()); + } + } + return result; + } + + @Override + public CIJobsList getJobsList(boolean includeParameters, Long workspaceId) { + ACLContext securityContext = startImpersonation(workspaceId); + CIJobsList result = dtoFactory.newDTO(CIJobsList.class); + Map jobsMap = new HashMap<>(); + + try { + long start = System.currentTimeMillis(); + Collection jobNames = Jenkins.get().getJobNames(); + logger.debug("Get job names took {} ms", System.currentTimeMillis() - start ); + for (String jobName : jobNames) { + String tempJobName = jobName; + try { + long startProcessJob = System.currentTimeMillis(); + Job tmpJob = (Job) Jenkins.get().getItemByFullName(tempJobName); + + if (!isJobIsRelevantForPipelineModule(tmpJob)) { + continue; + } + + PipelineNode tmpConfig; + if (tmpJob != null && JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME.equals(tmpJob.getParent().getClass().getName())) { + tempJobName = tmpJob.getParent().getFullName(); + WorkflowMultiBranchProject parentItem = (WorkflowMultiBranchProject) Jenkins.get().getItem(tempJobName); + if( (parentItem != null && parentItem.isDisabled()) || jobsMap.containsKey(tempJobName)){ + continue; //skip redundant creation config for multibranch job + } + tmpConfig = createPipelineNodeFromJobName(tempJobName); + } else { + tmpConfig = createPipelineNode(tempJobName, tmpJob, includeParameters); + } + jobsMap.put(tempJobName, tmpConfig); + if(System.currentTimeMillis() - startProcessJob > 2000){ + logger.warn("Job {} took {} ms",tempJobName,System.currentTimeMillis() - startProcessJob); + } + } catch (Throwable e) { + logger.error("failed to add job '" + tempJobName + "' to JobList", e); + } + } + logger.info("Get job list took {} ms",System.currentTimeMillis() - start); + + if(jobsMap.isEmpty() && !Jenkins.get().hasPermission(Item.READ)){ + //it is possible that user doesn't have general READ permission + // but has read permission to specific job, so we postponed this check to end + String userName = ImpersonationUtil.getUserNameForImpersonation(getInstanceId(), workspaceId); + if(StringUtils.isEmpty(userName)){ + userName = "anonymous"; + } + String msg = String.format("User %s does not have READ permission",userName); + throw new PermissionException(msg, HttpStatus.SC_FORBIDDEN); + } + + result.setJobs(jobsMap.values().toArray(new PipelineNode[0])); + } catch (AccessDeniedException ade) { + throw new PermissionException(HttpStatus.SC_FORBIDDEN); + } finally { + stopImpersonation(securityContext); + } + + return result; + } + + public static boolean isJobIsRelevantForPipelineModule(Job job){ + return !(job == null || + (job instanceof AbstractProject && ((AbstractProject) job).isDisabled()) || + job instanceof MatrixConfiguration || + job instanceof MavenModule); + } + + @Override + public PipelineNode getPipeline(String rootJobCiId) { + ACLContext securityContext = startImpersonation(); + try { + PipelineNode result; + boolean hasRead = Jenkins.get().hasPermission(Item.READ); + if (!hasRead) { + throw new PermissionException(HttpStatus.SC_FORBIDDEN); + } + + Item item = getItemByRefId(rootJobCiId); + if (item == null) { + logger.warn("Failed to get project from jobRefId: '" + rootJobCiId + "' check plugin user Job Read/Overall Read permissions / project name"); + throw new ConfigurationException(HttpStatus.SC_NOT_FOUND); + } else if (item instanceof Job) { + result = ModelFactory.createStructureItem((Job) item); + } else { + result = createPipelineNodeFromJobName(item.getFullName()); + if (item.getClass().getName().equals(JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME)) { + WorkflowMultiBranchProject parentItem = (WorkflowMultiBranchProject) item; + if(!parentItem.isDisabled()) { + addParametersAndDefaultBranchFromConfig(item, result); + result.setMultiBranchType(MultiBranchType.MULTI_BRANCH_PARENT); + } else result = null; + } + } + return result; + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public void runPipeline(String jobCiId, CIParameters ciParameters) { + ACLContext securityContext = startImpersonation(); + try { + Job job = getJobByRefId(jobCiId); + if (job != null) { + if (job instanceof AbstractProject && ((AbstractProject) job).isDisabled()) { + //disabled job is not runnable and in this context we will handle it as 404 + throw new ConfigurationException(HttpStatus.SC_NOT_FOUND); + } + boolean hasBuildPermission = job.hasPermission(Item.BUILD); + if (!hasBuildPermission) { + stopImpersonation(securityContext); + throw new PermissionException(HttpStatus.SC_FORBIDDEN); + } + if (job instanceof AbstractProject || job.getClass().getName().equals(JobProcessorFactory.WORKFLOW_JOB_NAME)) { + doRunImpl(job, ciParameters); + } + } else { + throw new ConfigurationException(HttpStatus.SC_NOT_FOUND); + } + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public void stopPipelineRun(String jobCiId, CIParameters ciParameters) { + ACLContext securityContext = startImpersonation(); + try { + Job job = getJobByRefId(jobCiId); + if (job != null) { + boolean hasAbortPermissions = job.hasPermission(Item.CANCEL); + if (!hasAbortPermissions) { + stopImpersonation(securityContext); + throw new PermissionException(HttpStatus.SC_FORBIDDEN); + } + if (job instanceof AbstractProject || job.getClass().getName().equals(JobProcessorFactory.WORKFLOW_JOB_NAME)) { + doStopImpl(job, ciParameters); + } + } else { + throw new ConfigurationException(HttpStatus.SC_NOT_FOUND); + } + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public CIBranchesList getBranchesList(String jobCiId, String filterBranchName) { + ACLContext securityContext = startImpersonation(); + List result = new ArrayList<>(); + try { + Item item = Jenkins.get().getItemByFullName(jobCiId); + if (item != null) { + boolean hasRead = Jenkins.get().hasPermission(Item.READ); + if (!hasRead) { + throw new PermissionException("Missing READ permission to job " + jobCiId, HttpStatus.SC_FORBIDDEN); + } + if (item.getClass().getName().equals(JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME)) { + result = doGetListOfBranchesImpl(item, filterBranchName); + } + return dtoFactory.newDTO(CIBranchesList.class) + .setBranches(result); + } else { + throw new ConfigurationException(HttpStatus.SC_NOT_FOUND); + } + } finally { + stopImpersonation(securityContext); + } + } + + private List doGetListOfBranchesImpl(Item item, String filterBranchName) { + Collection allJobs = item.getAllJobs(); + + return allJobs.stream().filter(job -> getDisplayNameFromJob(job).equals(filterBranchName)) + .map(job -> dtoFactory.newDTO(Branch.class) + .setName(job.getDisplayName()) + .setInternalId(job.getName())) + .collect(Collectors.toList()); + } + + @Override + public CIBuildStatusInfo getJobBuildStatus(String jobCiId, String parameterName, String parameterValue) { + ACLContext securityContext = startImpersonation(); + try { + Job job = getJobByRefId(jobCiId); + boolean hasRead = Jenkins.get().hasPermission(Item.READ); + if (!hasRead) { + throw new PermissionException("Missing READ permission to job " + jobCiId, HttpStatus.SC_FORBIDDEN); + } + if(job == null) { + return getUnavailableJobStatus(jobCiId, parameterName, parameterValue); + } else { + AbstractProjectProcessor jobProcessor = JobProcessorFactory.getFlowProcessor(job); + return jobProcessor.getBuildStatus(parameterName, parameterValue); + } + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public InputStream getTestsResult(String jobId, String buildId) { + ACLContext originalContext = startImpersonation(); + try { + InputStream result = null; + Run run = getRunByRefNames(jobId, buildId); + if (run != null) { + try { + result = new FileInputStream(run.getRootDir() + File.separator + TestListener.TEST_RESULT_FILE); + } catch (Exception fnfe) { + logger.error("'" + TestListener.TEST_RESULT_FILE + "' file no longer exists, test results of '" + jobId + " #" + buildId + "' won't be pushed to Octane", fnfe); + } + tryRemoveTempTestResultFile(run); + } else { + logger.error("build '" + jobId + " #" + buildId + "' not found"); + } + return result; + } finally { + stopImpersonation(originalContext); + } + } + + private void tryRemoveTempTestResultFile(Run run) { + try { + File[] matches = run.getRootDir().listFiles((dir, name) -> name.startsWith(JUnitExtension.TEMP_TEST_RESULTS_FILE_NAME_PREFIX)); + if (matches != null) { + for (File f : matches) { + try { + Files.deleteIfExists(f.toPath()); + } catch (Exception e) { + logger.error("Failed to delete the temp test result file at '" + f.getPath() + "'", e); + } + } + } + } catch (Exception e) { + logger.error("Fail to tryRemoveTempTestResultFile : " + e.getMessage()); + } + } + + @Override + public InputStream getBuildLog(String jobId, String buildId) { + ACLContext originalContext = startImpersonation(); + try { + InputStream result = null; + Run run = getRunByRefNames(jobId, buildId); + if (run != null) { + result = getOctaneLogFile(run); + } else { + logger.error("build '" + jobId + " #" + buildId + "' not found"); + } + return result; + } finally { + stopImpersonation(originalContext); + } + } + + @Override + public InputStream getCoverageReport(String jobId, String buildId, String reportFileName) { + ACLContext originalContext = startImpersonation(); + try { + InputStream result = null; + Run run = getRunByRefNames(jobId, buildId); + if (run != null) { + File coverageReport = new File(run.getRootDir(), reportFileName); + if (coverageReport.exists()) { + try { + result = new FileInputStream(coverageReport); + } catch (FileNotFoundException fnfe) { + logger.warn("file not found for '" + reportFileName + "' although just verified its existence, concurrency?"); + } + } + } else { + logger.error("build '" + jobId + " #" + buildId + "' not found"); + } + return result; + } finally { + stopImpersonation(originalContext); + } + } + + @Override + public InputStream getSCMData(String jobId, String buildId) { + ACLContext originalContext = startImpersonation(); + InputStream result = null; + + try { + Run run = getRunByRefNames(jobId, buildId); + if (run != null) { + result = SCMUtils.getSCMData(run); + } else { + logger.error("build '" + jobId + " #" + buildId + "' not found"); + } + } catch (IOException | InterruptedException e) { + logger.error("Failed to load SCMData for jobId " + jobId + " buildId " + buildId, e); + } finally { + stopImpersonation(originalContext); + } + + return result; + } + + @Override + public SSCProjectConfiguration getSSCProjectConfiguration(String jobId, String buildId) { + ACLContext originalContext = startImpersonation(); + try { + SSCProjectConfiguration result = null; + Run run = getRunByRefNames(jobId, buildId); + SSCServerConfigUtil.SSCProjectVersionPair projectVersionPair = null; + + if (run instanceof AbstractBuild) { + projectVersionPair = SSCServerConfigUtil.getProjectConfigurationFromBuild((AbstractBuild) run); + } else if (run instanceof WorkflowRun) { + projectVersionPair = SSCServerConfigUtil.getProjectConfigurationFromWorkflowRun((WorkflowRun) run); + } else { + logger.error("build '" + jobId + " #" + buildId + "' (of specific type AbstractBuild or WorkflowRun) not found"); + return result; + } + + String sscServerUrl = SSCServerConfigUtil.getSSCServer(); + String sscAuthToken = getFortifySSCToken(); + + if (sscServerUrl != null && !sscServerUrl.isEmpty() && projectVersionPair != null) { + result = dtoFactory.newDTO(SSCProjectConfiguration.class) + .setSSCUrl(sscServerUrl) + .setSSCBaseAuthToken(sscAuthToken) + .setProjectName(projectVersionPair.project) + .setProjectVersion(projectVersionPair.version); + } + + return result; + } finally { + stopImpersonation(originalContext); + } + } + + private String getFortifySSCToken(){ + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(getInstanceId()); + FortifySSCTokenParameter parameter = (FortifySSCTokenParameter) octaneClient.getConfigurationService().getConfiguration().getParameter(FortifySSCTokenParameter.KEY); + if (parameter != null) { + return parameter.getToken(); + } + return ""; + } + + @Override + public Long getFodRelease(String jobId, String buildId) { + ACLContext originalContext = startImpersonation(); + try { + Run run = getRunByRefNames(jobId, buildId); + if (run instanceof AbstractBuild) { + return FodConfigUtil.getFODReleaseFromBuild((AbstractBuild) run); + } else { + logger.error("build '" + jobId + " #" + buildId + "' (of specific type AbstractBuild) not found"); + return null; + } + } finally { + stopImpersonation(originalContext); + } + } + + @Override + public FodServerConfiguration getFodServerConfiguration() { + + ACLContext originalContext = startImpersonation(); + try { + + FodConfigUtil.ServerConnectConfig fodServerConfig = FodConfigUtil.getFODServerConfig(); + if (fodServerConfig != null) { + return dtoFactory.newDTO(FodServerConfiguration.class) + .setClientId(fodServerConfig.clientId) + .setClientSecret(fodServerConfig.clientSecret) + .setApiUrl(fodServerConfig.apiUrl) + .setBaseUrl(fodServerConfig.baseUrl); + } + return null; + } finally { + stopImpersonation(originalContext); + } + } + + @Override + public void runTestDiscovery(DiscoveryInfo discoveryInfo) { + ACLContext securityContext = startImpersonation(); + try { + TestExecutionJobCreatorService.runTestDiscovery(discoveryInfo); + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public PipelineNode createExecutor(DiscoveryInfo discoveryInfo) { + if (EntityConstants.Executors.UFT_TEST_RUNNER_SUBTYPE_ENTITY_NAME.equals(discoveryInfo.getExecutorType())) { + ACLContext securityContext = startImpersonation(); + try { + Job project = TestExecutionJobCreatorService.createExecutor(discoveryInfo); + return ModelFactory.createStructureItem(project); + } finally { + stopImpersonation(securityContext); + } + } else { + return null; + } + } + + @Override + public OctaneResponse checkRepositoryConnectivity(TestConnectivityInfo testConnectivityInfo) { + ACLContext securityContext = startImpersonation(); + try { + OctaneResponse response; + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(getInstanceId()); + if (ConfigurationParameterFactory.isUftTestConnectionDisabled(octaneClient.getConfigurationService().getConfiguration())) { + logger.info("checkRepositoryConnectivity : validation disabled"); + response = DTOFactory.getInstance().newDTO(OctaneResponse.class).setStatus(HttpStatus.SC_OK); + } else { + response = ExecutorConnectivityService.checkRepositoryConnectivity(testConnectivityInfo); + } + + //validate UftTestRunnerFolderParameter + if (response.getStatus() == HttpStatus.SC_OK) { + UftTestRunnerFolderParameter uftFolderParameter = (UftTestRunnerFolderParameter) octaneClient.getConfigurationService() + .getConfiguration().getParameter(UftTestRunnerFolderParameter.KEY); + if (uftFolderParameter != null) { + List errors = new ArrayList<>(); + ConfigurationValidator.checkUftFolderParameter(uftFolderParameter, errors); + if (!errors.isEmpty()) { + response.setStatus(HttpStatus.SC_BAD_REQUEST); + response.setBody(errors.get(0)); + } + } + } + return response; + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public void deleteExecutor(String id) { + ACLContext securityContext = startImpersonation(); + try { + UftJobRecognizer.deleteDiscoveryJobByExecutor(id); + UftJobRecognizer.deleteExecutionJobByExecutorIfNeverExecuted(id); + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public OctaneResponse upsertCredentials(CredentialsInfo credentialsInfo) { + ACLContext securityContext = startImpersonation(); + try { + return ExecutorConnectivityService.upsertRepositoryCredentials(credentialsInfo); + } finally { + stopImpersonation(securityContext); + } + } + + @Override + public List getCredentials() { + List list = CredentialsProvider.lookupCredentials(StandardUsernameCredentials.class, (Item) null, null, (DomainRequirement) null); + List output = list.stream() + .map(c -> dtoFactory.newDTO(CredentialsInfo.class).setCredentialsId(c.getId()).setUsername(CredentialsNameProvider.name(c))) + .collect(Collectors.toList()); + return output; + } + + private ACLContext startImpersonation() { + return startImpersonation(null); + } + + private ACLContext startImpersonation(Long workspaceId) { + return ImpersonationUtil.startImpersonation(getInstanceId(), workspaceId); + } + + private void stopImpersonation(ACLContext impersonatedContext) { + ImpersonationUtil.stopImpersonation(impersonatedContext); + } + + private PipelineNode createPipelineNode(String name, Job job, boolean includeParameters) { + PipelineNode tmpConfig = dtoFactory.newDTO(PipelineNode.class) + .setJobCiId(JobProcessorFactory.getFlowProcessor(job).getTranslatedJobName()) + .setName(name); + + if (includeParameters) { + tmpConfig.setParameters(ParameterProcessors.getConfigs(job)); + + //setIsTestRunner + if (tmpConfig.getParameters() != null) { + Optional opt = tmpConfig.getParameters().stream().filter(p -> TestsToRunConverterBuilder.TESTS_TO_RUN_PARAMETER.equals(p.getName())).findFirst(); + tmpConfig.setIsTestRunner(opt.isPresent()); + } + + //setHasUpstream + if (job instanceof AbstractProject) { + List upstreams = Jenkins.get().getDependencyGraph().getUpstream((AbstractProject) job); + tmpConfig.setHasUpstream(upstreams.size() > 0); + } + + } + return tmpConfig; + } + + private PipelineNode createPipelineNodeFromJobName(String name) { + return dtoFactory.newDTO(PipelineNode.class) + .setJobCiId(BuildHandlerUtils.translateFolderJobName(name)) + .setName(name); + } + + private CIBuildStatusInfo getUnavailableJobStatus(String ciJobId, String paramName, String paramValue) { + return DTOFactory.getInstance().newDTO(CIBuildStatusInfo.class) + .setBuildStatus(CIBuildStatus.UNAVAILABLE) + .setJobCiId(ciJobId) + .setParamName(paramName) + .setParamValue(paramValue) + .setResult(CIBuildResult.UNAVAILABLE); + } + + private void addParametersAndDefaultBranchFromConfig(Item item, PipelineNode result) { + String defaultBranchesConfig = RunnerMiscSettingsGlobalConfiguration.getInstance() != null ? RunnerMiscSettingsGlobalConfiguration.getInstance().getDefaultBranches() : null; + if(defaultBranchesConfig != null && !defaultBranchesConfig.isEmpty()) { + String[] defaultBranchesArray = defaultBranchesConfig.split(DEFAULT_BRANCHES_SEPARATOR); + Set defaultBranches = Arrays.stream(defaultBranchesArray) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toSet()); + + Collection allJobs = item.getAllJobs(); + + Job job = allJobs.stream() + .filter(tempJob -> defaultBranches.contains(getDisplayNameFromJob(tempJob))) + .findFirst().orElse(null); + + if (job != null) { + String defaultBranch = getDisplayNameFromJob(job); + result.setParameters(ParameterProcessors.getConfigs(job)) + .setDefaultBranchName(defaultBranch); + } + } + } + + private String getDisplayNameFromJob(Job tempJob) { + return tempJob.getDisplayName() != null ? tempJob.getDisplayName() : tempJob.getName(); + } + + private InputStream getOctaneLogFile(Run run) { + InputStream result = null; + String octaneLogFilePath = run.getRootDir() + File.separator + "octane_log"; + File logFile = new File(octaneLogFilePath); + if (!logFile.exists()) { + try (FileOutputStream fileOutputStream = new FileOutputStream(logFile); + InputStream logStream = run.getLogInputStream(); + PlainTextConsoleOutputStream out = new PlainTextConsoleOutputStream(fileOutputStream)) { + IOUtils.copy(logStream, out); + out.flush(); + } catch (IOException ioe) { + logger.error("failed to transfer native log to Octane's one for " + run); + } + } + try { + result = new FileInputStream(octaneLogFilePath); + } catch (IOException ioe) { + logger.error("failed to obtain log for " + run); + } + return result; + } + + private Run getRunByRefNames(String jobId, String buildId) { + Run result = null; + Job project = getJobByRefId(jobId); + if (project != null) { + result = project.getBuildByNumber(Integer.parseInt(buildId)); + } + return result; + } + + private void doRunImpl(Job job, CIParameters ciParameters) { + AbstractProjectProcessor jobProcessor = JobProcessorFactory.getFlowProcessor(job); + doRunStopImpl(jobProcessor::scheduleBuild, "execution", job, ciParameters); + } + + private void doStopImpl(Job job, CIParameters ciParameters) { + AbstractProjectProcessor jobProcessor = JobProcessorFactory.getFlowProcessor(job); + doRunStopImpl(jobProcessor::cancelBuild, "stop", job, ciParameters); + } + + // TODO: the below flow should go via JobProcessor, once scheduleBuild will be implemented for all of them + private void doRunStopImpl(BiConsumer method, String methodName, Job job, CIParameters ciParameters) { + ParametersAction parametersAction = new ParametersAction(); + if (ciParameters != null) { + parametersAction = new ParametersAction(createParameters(job, ciParameters)); + } + + Cause cause = new Cause.RemoteCause(ConfigurationService.getSettings(getInstanceId()) == null ? "non available URL" : + ConfigurationService.getSettings(getInstanceId()).getLocation(), "octane driven " + methodName); + method.accept(cause, parametersAction); + } + + public static List createParameters(Job project, CIParameters ciParameters) { + List result = new ArrayList<>(); + boolean parameterHandled; + ParameterValue tmpValue; + ParametersDefinitionProperty paramsDefProperty = (ParametersDefinitionProperty) project.getProperty(ParametersDefinitionProperty.class); + + if (paramsDefProperty == null) { + paramsDefProperty = new ParametersDefinitionProperty(); + } + + Map ciParametersMap = ciParameters.getParameters().stream().collect(Collectors.toMap(CIParameter::getName, Function.identity())); + for (ParameterDefinition paramDef : paramsDefProperty.getParameterDefinitions()) { + parameterHandled = false; + CIParameter ciParameter = ciParametersMap.remove(paramDef.getName()); + if (ciParameter != null) { + tmpValue = null; + switch (ciParameter.getType()) { + case NUMBER: + case STRING: + tmpValue = new StringParameterValue(ciParameter.getName(), ciParameter.getValue().toString()); + break; + case BOOLEAN: + tmpValue = new BooleanParameterValue(ciParameter.getName(), Boolean.parseBoolean(ciParameter.getValue().toString())); + break; + case PASSWORD: + tmpValue = new PasswordParameterValue(ciParameter.getName(), ciParameter.getValue().toString()); + break; + default: + break; + } + if (tmpValue != null) { + result.add(tmpValue); + parameterHandled = true; + } + } + if (!parameterHandled) { + if (paramDef instanceof FileParameterDefinition) { + FileItemFactory fif = new DiskFileItemFactory(); + FileItem fi = fif.createItem(paramDef.getName(), "text/plain", false, ""); + try { + fi.getOutputStream().write(new byte[0]); + } catch (IOException ioe) { + logger.error("failed to create default value for file parameter '" + paramDef.getName() + "'", ioe); + } + tmpValue = new FileParameterValue(paramDef.getName(), fi); + result.add(tmpValue); + } else { + result.add(paramDef.getDefaultParameterValue()); + } + } + } + + //add parameters that are not defined in job + for (CIParameter notDefinedParameter : ciParametersMap.values()) { + tmpValue = new StringParameterValue(notDefinedParameter.getName(), notDefinedParameter.getValue().toString()); + result.add(tmpValue); + } + return result; + } + + private Job getJobByRefId(String jobName) { + Item item = getItemByRefId(jobName); + return item instanceof Job ? (Job) item : null; + } + + private Item getItemByRefId(String jobName) { + String myJobName = BuildHandlerUtils.revertTranslateFolderJobName(jobName); + Item item = Jenkins.get().getItemByFullName(myJobName); + if (item == null) { + // defect #875099 : two jobs with the same name in folder - are not treated correctly + // PATCH UNTIL OCTANE SEND jobRefId correctly (fix in octane : pipeline-management-add-dialog-controller.js) + //bug in octane : duplicating parent prefix, for example job f1/f2/jobA , appear as f1/f2/f1/f2/jobA + //try to reduce duplication and find job + + int jobNameIndex = myJobName.lastIndexOf('/'); + if (jobNameIndex > 0) { + String parentPrefix = myJobName.substring(0, jobNameIndex); + String notDuplicatedParentPrefix1 = myJobName.substring(0, parentPrefix.length() / 2); + String notDuplicatedParentPrefix2 = myJobName.substring((parentPrefix.length() / 2) + 1, jobNameIndex); + if (StringUtils.equals(notDuplicatedParentPrefix1, notDuplicatedParentPrefix2)) { + String alternativeJobName = notDuplicatedParentPrefix1 + myJobName.substring(jobNameIndex); + item = Jenkins.get().getItemByFullName(alternativeJobName); + } + } + } + + return item; + } + + public static File getAllowedStorageFile() { + Jenkins jenkins = Jenkins.getInstanceOrNull(); + File folder; + if (jenkins != null) { + folder = getAllowedStorageFileForMasterJenkins(jenkins); + } else {/*is slave*/ + folder = new File("octanePluginContent"); + } + return folder; + } + + private static File getAllowedStorageFileForMasterJenkins(Jenkins jenkins) { + boolean allowPrint; + synchronized (skipOctaneAllowedStoragePrintLock) { + //do allowPrint only once + allowPrint = !skipOctaneAllowedStoragePrint; + skipOctaneAllowedStoragePrint = true; + } + + File folder; + // jenkins.xml + // -Xrs -Xmx256m -octaneAllowedStorage=userContentTemp -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" + String prop = System.getProperty("octaneAllowedStorage"); + if (StringUtils.isNotEmpty(prop)) { + folder = new File(prop); + if (!folder.isAbsolute()) { + folder = new File(jenkins.getRootDir(), prop); + } + if (allowPrint) { + systemLogger.info("octaneAllowedStorage : " + folder.getAbsolutePath()); + //validate that folder exist + if (!folder.exists() && !folder.mkdirs()) { + systemLogger.warning("Failed to create octaneAllowedStorage : " + folder.getAbsolutePath() + ". Create this folder and restart Jenkins."); + } + } + } else { + folder = new File(jenkins.getRootDir(), "userContent"); + } + return folder; + } + + public static CIServerInfo getJenkinsServerInfo() { + CIServerInfo result = dtoFactory.newDTO(CIServerInfo.class); + String serverUrl = Jenkins.get().getRootUrl(); + if (serverUrl != null && serverUrl.endsWith("/")) { + serverUrl = serverUrl.substring(0, serverUrl.length() - 1); + } + result.setType(CIServerTypes.JENKINS.value()) + .setVersion(Jenkins.VERSION) + .setUrl(serverUrl) + .setSendingTime(System.currentTimeMillis()); + return result; + } + + public static void publishEventToRelevantClients(CIEvent event) { + OctaneSDK.getClients().forEach(c->c.getEventsService().publishEvent(event)); + } + + @Override + public String getParentJobName(String jobId) { + if (jobId != null && jobId.contains(BuildHandlerUtils.JOB_LEVEL_SEPARATOR)) { + int index = jobId.lastIndexOf(BuildHandlerUtils.JOB_LEVEL_SEPARATOR); + String parent = jobId.substring(0, index); + return parent; + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/GitFetchUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/GitFetchUtils.java new file mode 100644 index 0000000000..fb5ec1352c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/GitFetchUtils.java @@ -0,0 +1,148 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.hp.octane.integrations.services.pullrequestsandbranches.PullRequestAndBranchService; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.FetchHandler; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.RepoTemplates; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.AuthenticationStrategy; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.BasicAuthenticationStrategy; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.NoCredentialsStrategy; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.PATStrategy; +import hudson.model.Run; +import hudson.model.User; +import hudson.util.Secret; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; + +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.TimeZone; +import java.util.function.Consumer; + +public class GitFetchUtils { + + private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm"; + + private GitFetchUtils() { + //codacy recommendation : Add a private constructor to hide the implicit public one. + } + + /** + * Generate date format for template : yyyy-MM-dd HH:mm + * + * @return + */ + public static SimpleDateFormat generateDateFormat() { + SimpleDateFormat temp = new SimpleDateFormat(DATE_TIME_FORMAT); + TimeZone utc = TimeZone.getTimeZone("UTC"); + temp.setTimeZone(utc); + return temp; + } + + /** + * Get user id by email and login. This method is used to return the same user Id for commits/pull request/branches + * + * @param email + * @param login + * @return + */ + public static String getUserIdForCommit(String email, String login) { + if (login != null) { + User user = User.get(login, false, Collections.emptyMap()); + if (user != null) { + return user.getId(); + } + } + if (email != null && email.contains("@")) { + String[] emailParts = email.split("@"); + return emailParts[0]; + + } + return login; + } + + /** + * Get user name password credentials by id. + */ + public static StandardCredentials getCredentialsById(String credentialsId, Run run, PrintStream logger) { + + StandardCredentials credentials = null; + if (!StringUtils.isEmpty(credentialsId)) { + credentials = CredentialsProvider.findCredentialById(credentialsId, + StandardCredentials.class, + run, + URIRequirementBuilder.create().build()); + if (credentials == null) { + logger.println("Can not find credentials with the credentialsId:" + credentialsId); + } + } + + return credentials; + } + + public static AuthenticationStrategy getAuthenticationStrategy(StandardCredentials credentials) { + AuthenticationStrategy authenticationStrategy; + if (credentials == null) { + authenticationStrategy = new NoCredentialsStrategy(); + } else if (credentials instanceof StringCredentials) { + Secret secret = ((StringCredentials) credentials).getSecret(); + authenticationStrategy = new PATStrategy(secret.getPlainText()); + } else if (credentials instanceof StandardUsernamePasswordCredentials) { + StandardUsernamePasswordCredentials cr = (StandardUsernamePasswordCredentials) credentials; + authenticationStrategy = new BasicAuthenticationStrategy(cr.getUsername(), cr.getPassword().getPlainText()); + } else { + throw new IllegalArgumentException("Credentials type is not supported : " + credentials.getClass().getCanonicalName()); + } + + return authenticationStrategy; + } + + public static void updateRepoTemplates(PullRequestAndBranchService pullRequestAndBranchService, FetchHandler fetcherHandler, String repoHttpUrlForTemplates, String repoUrlForOctane, Long workspaceId, Consumer logConsumer) { + //update repo templates + try { + RepoTemplates repoTemplates = fetcherHandler.buildRepoTemplates(repoHttpUrlForTemplates); + if (pullRequestAndBranchService.updateRepoTemplates(repoUrlForOctane, workspaceId, repoTemplates)) { + logConsumer.accept("Repo template are updated successfully in ALM Octane"); + } + } catch (Exception e) { + logConsumer.accept("Failed to update repo templates : " + e.getMessage()); + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/ImpersonationUtil.java b/src/main/java/com/microfocus/application/automation/tools/octane/ImpersonationUtil.java new file mode 100644 index 0000000000..3efd4c6629 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/ImpersonationUtil.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.hp.octane.integrations.exceptions.PermissionException; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.User; +import hudson.security.ACL; +import hudson.security.ACLContext; +import jenkins.model.Jenkins; +import org.acegisecurity.Authentication; +import org.acegisecurity.GrantedAuthority; +import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; + +import java.util.Collections; + +/** + * * + * util class for user impersonation, to allow internal access on behalf of the Jenkins user associated with an instance of ALM Octane server. + */ + +public class ImpersonationUtil { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ImpersonationUtil.class); + + public static String getUserNameForImpersonation(String instanceId, Long workspaceId) { + OctaneServerSettingsModel settings = ConfigurationService.getSettings(instanceId); + if (settings == null) { + throw new IllegalStateException("failed to retrieve configuration settings by instance ID " + instanceId); + } + + String userName; + if (workspaceId != null && settings.getWorkspace2ImpersonatedUserMap().containsKey(workspaceId)) { + userName = settings.getWorkspace2ImpersonatedUserMap().get(workspaceId); + logger.info(String.format("Using workspace jenkins user '%s' for workspace '%s'", userName, workspaceId)); + } else { + userName = settings.getImpersonatedUser(); + } + return userName; + } + + public static ACLContext startImpersonation(String instanceId, Long workspaceId) { + + String userName = getUserNameForImpersonation(instanceId, workspaceId); + User jenkinsUser = null; + if (!StringUtils.isEmpty(userName)) { + jenkinsUser = User.get(userName, false, Collections.emptyMap()); + if (jenkinsUser == null) { + throw new PermissionException(HttpStatus.SC_UNAUTHORIZED); + } + } + return startImpersonation(jenkinsUser); + } + + public static ACLContext startImpersonation(User jenkinsUser) { + + ACLContext impersonatedContext; + try { + impersonatedContext = ACL.as(jenkinsUser); + } catch (UsernameNotFoundException e) { + logger.debug("Failed to get impersonatedContext from user. Trial to get impersonatedContext by manual auth creation."); + //defect#921010 : User impersonation is failing as customer is using custom UserDetailsService that does not have implementation of loadUserByUsername + Authentication auth = (jenkinsUser == null ? Jenkins.ANONYMOUS : new UsernamePasswordAuthenticationToken(jenkinsUser.getId(), "", new GrantedAuthority[0])); + impersonatedContext = ACL.as(auth); + } + + return impersonatedContext; + } + + public static void stopImpersonation(ACLContext impersonatedContext) { + if (impersonatedContext != null) { + impersonatedContext.close(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/JellyUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/JellyUtils.java new file mode 100644 index 0000000000..80f863bec7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/JellyUtils.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.entities.Entity; +import com.hp.octane.integrations.services.entities.EntitiesService; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import hudson.model.Item; +import hudson.model.Queue; +import hudson.model.queue.Tasks; +import hudson.security.ACL; +import hudson.util.ListBoxModel; +import org.apache.commons.lang.StringUtils; + +import java.util.List; + +public class JellyUtils { + + public static final String NONE = "none"; + public static final String NONE_DISPLAY = "- none - "; + + private JellyUtils(){ + //for code climate + } + + public static ListBoxModel createComboModelWithNoneValue() { + ListBoxModel m = new ListBoxModel(); + m.add(NONE_DISPLAY, NONE); + return m; + } + + public static ListBoxModel fillWorkspaceModel(String configurationId, String workspaceId) { + ListBoxModel m = createComboModelWithNoneValue(); + if (StringUtils.isNotEmpty(configurationId) && !NONE.equals(configurationId)) { + try { + EntitiesService entitiesService = OctaneSDK.getClientByInstanceId(configurationId).getEntitiesService(); + List workspaces = entitiesService.getEntities(null, "workspaces", null, null); + for (Entity workspace : workspaces) { + m.add(workspace.getId() + " " + workspace.getName(), String.valueOf(workspace.getId())); + } + } catch (Exception e) { + //octane configuration not found + m.add(workspaceId, workspaceId); + return m; + } + } + return m; + } + + public static ListBoxModel fillConfigurationIdModel() { + ListBoxModel m = createComboModelWithNoneValue(); + + for (OctaneClient octaneClient : OctaneSDK.getClients()) { + OctaneServerSettingsModel model = ConfigurationService.getSettings(octaneClient.getInstanceId()); + m.add(model.getCaption(), model.getIdentity()); + } + return m; + } + + + public static ListBoxModel fillCredentialsIdItems(Item project, String credentialsId, CredentialsMatcher credentialsMatcher) { + + if (project == null || !project.hasPermission(Item.CONFIGURE)) { + return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); + } + + return new StandardListBoxModel() + .includeEmptyValue() + .includeMatchingAs( + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + project, + StandardCredentials.class, + URIRequirementBuilder.create().build(), + credentialsMatcher) + .includeCurrentValue(credentialsId); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/ResultQueue.java b/src/main/java/com/microfocus/application/automation/tools/octane/ResultQueue.java new file mode 100644 index 0000000000..6999e0cd37 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/ResultQueue.java @@ -0,0 +1,141 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import java.io.Serializable; + +@SuppressWarnings("squid:S2039") +public interface ResultQueue { + + ResultQueue.QueueItem peekFirst(); + + boolean failed(); + + void remove(); + + void add(QueueItem item); + + void add(String projectName, int buildNumber); + + void add(String projectName, String type, int buildNumber); + + void add(String projectName, int buildNumber, String workspace); + + void add(String instanceId, String projectName, int buildNumber, String workspace); + + void clear(); + + void close(); + + class QueueItem implements Serializable { + private static final long serialVersionUID = 1; + String instanceId; + public String type; + String projectName; + int buildNumber; + String workspace; + int failCount; + long sendAfter; + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public void setType(String type) { + this.type = type; + } + + public QueueItem(String projectName, int buildNumber) { + this(projectName, buildNumber, 0); + } + + public QueueItem(String projectName, String type, int buildNumber) { + this(projectName, buildNumber, 0); + this.type = type; + } + + public QueueItem(String projectName, int buildNumber, String workspace) { + this(projectName, buildNumber, 0); + this.workspace = workspace; + } + + QueueItem(String projectName, int buildNumber, int failCount) { + this.projectName = projectName; + this.buildNumber = buildNumber; + this.failCount = failCount; + } + + QueueItem(String projectName, int buildNumber, int failCount, String workspace) { + this.projectName = projectName; + this.buildNumber = buildNumber; + this.failCount = failCount; + this.workspace = workspace; + } + + public String getInstanceId() { + return instanceId; + } + + public String getType() { + return type; + } + + public int incrementFailCount() { + return this.failCount++; + } + + public int getFailCount() { + return failCount; + } + + public String getProjectName() { + return projectName; + } + + public int getBuildNumber() { + return buildNumber; + } + + public String getWorkspace() { + return workspace; + } + + public long getSendAfter() { + return sendAfter; + } + + public void setSendAfter(long sendAfter) { + this.sendAfter = sendAfter; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/BuildActions.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/BuildActions.java new file mode 100644 index 0000000000..7621621f30 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/BuildActions.java @@ -0,0 +1,105 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.microfocus.application.automation.tools.octane.tests.TestApi; +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.Action; +import hudson.model.Run; +import jenkins.model.RunAction2; +import jenkins.model.TransientActionFactory; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 12/08/14 + * Time: 10:45 + * To change this template use File | Settings | File Templates. + */ + +@Extension +public class BuildActions extends TransientActionFactory { + + static final public class OctaneBuildActions implements RunAction2 { + private AbstractBuild build; + + OctaneBuildActions(AbstractBuild b) { + build = b; + } + + @Override + public void onAttached(Run run) { + } + + @Override + public void onLoad(Run run) { + } + + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return "nga"; + } + + public TestApi getTests() { + return new TestApi(build); + } + } + + @Override + public Class type() { + return AbstractBuild.class; + } + + @Override + @Nonnull + public Collection createFor(@Nonnull AbstractBuild build) { + ArrayList actions = new ArrayList<>(); + actions.add(new OctaneBuildActions(build)); + return actions; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/CoveragePublisher.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/CoveragePublisher.java new file mode 100644 index 0000000000..4a52d5d3ee --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/CoveragePublisher.java @@ -0,0 +1,220 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.coverage.CoverageReportType; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.actions.coverage.CoveragePublisherAction; +import com.microfocus.application.automation.tools.octane.actions.coverage.CoverageService; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.FormValidation; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.List; + +/** + * Post-build action that collects the coverage reports from workspace + * the reports that matches a specified regular expression path, are copied to + * the build folder for future upload. + */ +public class CoveragePublisher extends Recorder implements SimpleBuildStep { + private final String jacocoPathPattern; + private final String lcovPathPattern; + + /** + * this ctor is being called from configuration page. + * the jacocoPathPattern is being injected from the web page text box + * + * @param jacocoPathPattern regular expression path for coverage reports + */ + @DataBoundConstructor + public CoveragePublisher(String jacocoPathPattern, String lcovPathPattern) { + // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" + this.jacocoPathPattern = jacocoPathPattern == null || jacocoPathPattern.isEmpty() ? CoverageService.Jacoco.JACOCO_DEFAULT_PATH : jacocoPathPattern; + this.lcovPathPattern = lcovPathPattern == null || lcovPathPattern.isEmpty() ? CoverageService.Lcov.LCOV_DEFAULT_PATH : lcovPathPattern; + } + + /** + * this method used for serialization & deserialization of path + * + * @return jacoco path + */ + public String getJacocoPathPattern() { + return jacocoPathPattern; + } + + /** + * this method used for serialization & deserialization of path + * + * @return lcov path + */ + public String getLcovPathPattern() { + return lcovPathPattern; + } + + /** + * this is where we build the project. this method is being called when we run the build + * + * @param run instance + * @param filePath instance + * @param launcher for action attachment + * @param taskListener for action attachment + */ + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) throws InterruptedException, IOException { + boolean isSuccessful = perform(run, taskListener); + if (!isSuccessful) { + run.setResult(Result.FAILURE); + } + } + + /** + * this is where we build the project. this method is being called when we run the build + * + * @param build instance + * @param launcher instance + * @param listener for action attachment + * @return status + */ + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { + return perform(build, listener); + } + + public boolean perform(Run build, TaskListener listener) { + CoveragePublisherAction action = new CoveragePublisherAction(build, listener); + build.addAction(action); + + List jacocoReportFileNames = action.copyCoverageReportsToBuildFolder(jacocoPathPattern, CoverageService.Jacoco.JACOCO_DEFAULT_FILE_NAME); + List lcovReportFileNames = action.copyCoverageReportsToBuildFolder(lcovPathPattern, CoverageService.Lcov.LCOV_DEFAULT_FILE_NAME); + boolean copyReportsToBuildFolderStatus = enqueueReports(build, jacocoReportFileNames, CoverageReportType.JACOCOXML) || + enqueueReports(build, lcovReportFileNames, CoverageReportType.LCOV); + + return copyReportsToBuildFolderStatus; + } + + private boolean enqueueReports(Run build, List reportFileNames, CoverageReportType coverageReportType){ + if (!reportFileNames.isEmpty()) { + String parents = BuildHandlerUtils.getRootJobCiIds(build); + OctaneSDK.getClients().forEach(octaneClient-> { + for (String reportFileName : reportFileNames) { + octaneClient.getCoverageService() + .enqueuePushCoverage(BuildHandlerUtils.getJobCiId(build), String.valueOf(build.getNumber()), coverageReportType, reportFileName, parents); + } + }); + return true; + } + return false; + } + + /** + * bound between descriptor to publisher + * + * @return descriptor + */ + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + /** + * Returns BuildStepMonitor.NONE by default, as Builders normally don't depend on its previous result + * + * @return monitor + */ + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + /** + * The Publisher object or Recorder is the base. + * It needs a BuildStepDescriptor to provide certain information to Jenkins + */ + @Symbol("publishCodeCoverage") + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + load(); + } + + /** + * Indicates that this builder can be used with all kinds of project types + * + * @param aClass that describe the job + * @return always true, indicate that this post build action suitable for all jenkins jobs + */ + public boolean isApplicable(Class aClass) { + return true; // so that it will also be available for maven & other projects + } + + public String getDisplayName() { + return "ALM Octane code coverage publisher"; + } + + public FormValidation doCheckJacocoPathPattern(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException { + if (value == null || value.isEmpty()) { + return FormValidation.warning(Messages.CoverageResultsActionEmptyConfigurationWarning(), CoverageService.Jacoco.JACOCO_DEFAULT_PATH); + } else if (project == null) { + return FormValidation.ok(); + } + return FilePath.validateFileMask(project.getSomeWorkspace(), value); + } + + public FormValidation doCheckLcovPathPattern(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException, ServletException { + if (value == null || value.isEmpty()) { + return FormValidation.warning(Messages.CoverageResultsActionEmptyConfigurationWarning(), CoverageService.Lcov.LCOV_DEFAULT_PATH); + } else if (project == null) { + return FormValidation.ok(); + } + return FilePath.validateFileMask(project.getSomeWorkspace(), value); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/PluginActions.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/PluginActions.java new file mode 100644 index 0000000000..5f5f6b59e1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/PluginActions.java @@ -0,0 +1,229 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.general.CIServerInfo; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import hudson.Extension; +import hudson.model.RootAction; +import jenkins.model.Jenkins; +import net.sf.json.JSONObject; +import org.apache.http.entity.ContentType; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 8/10/14 + * Time: 12:47 PM + * To change this template use File | Settings | File Templates. + */ + +@Extension +public class PluginActions implements RootAction { + + private static final String CONTENT_TYPE = "Content-Type"; + private static final String API = "/nga/api/v1"; + private static final String STATUS_REQUEST = API + "/status"; + private static final String REENQUEUE_EVENT_REQUEST = API + "/reenqueue"; + private static final String CLEAR_JOB_LIST_CACHE = API + "/clear-job-list-cache"; + private static final String CLEAR_OCTANE_ROOTS_CACHE = API + "/clear-octane-roots-cache"; + private static final String OCTANE_ROOTS_CACHE = API + "/octane-roots-cache"; + + private static final String INSTANCE_ID_PARAM = "instanceId"; + + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + public String getIconFileName() { + return null; + } + + public String getDisplayName() { + return null; + } + + public String getUrlName() { + return "nga"; + } + + + public void doDynamic(StaplerRequest req, StaplerResponse res) throws IOException { + + Jenkins.get().checkPermission(Jenkins.READ); + res.setHeader(CONTENT_TYPE, ContentType.TEXT_PLAIN.getMimeType()); + res.setStatus(200); + if (req.getRequestURI().toLowerCase().contains(STATUS_REQUEST)) { + JSONObject result = getStatusResult(req.getParameterMap()); + res.setHeader(CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType()); + res.getWriter().write(result.toString()); + } else if (req.getRequestURI().toLowerCase().contains(REENQUEUE_EVENT_REQUEST)) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + reEnqueueEvent(req.getParameterMap()); + res.getWriter().write("resent"); + } else if (req.getRequestURI().toLowerCase().contains(CLEAR_JOB_LIST_CACHE)) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + resetJobListCache(); + res.getWriter().write("done"); + } else if (req.getRequestURI().toLowerCase().contains(CLEAR_OCTANE_ROOTS_CACHE)) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + resetOctaneRootsCache(); + res.getWriter().write("done"); + } else if (req.getRequestURI().toLowerCase().contains(OCTANE_ROOTS_CACHE)) { + JSONObject result = readOctaneRootsCache(); + res.getWriter().write(result.toString()); + } else { + res.setStatus(404); + res.getWriter().write(""); + } + } + + private JSONObject getStatusResult(Map parameterMap) { + JSONObject sdkJson = new JSONObject(); + sdkJson.put("sdkVersion", OctaneSDK.SDK_VERSION); + JSONObject pluginJson = new JSONObject(); + pluginJson.put("version", ConfigurationService.getPluginVersion()); + JSONObject serverInfoJson = new JSONObject(); + CIServerInfo serverInfo = CIJenkinsServicesImpl.getJenkinsServerInfo(); + serverInfoJson.put("type", serverInfo.getType()); + serverInfoJson.put("version", serverInfo.getVersion()); + serverInfoJson.put("url", serverInfo.getUrl()); + serverInfoJson.put("currentTime", format.format(new Date())); + + JSONObject result = new JSONObject(); + result.put("sdk", sdkJson); + result.put("plugin", pluginJson); + result.put("server", serverInfoJson); + + if (parameterMap.containsKey("metrics")) { + JSONObject allMetricsJson = new JSONObject(); + OctaneSDK.getClients().forEach( + + client -> { + JSONObject confJson = new JSONObject(); + addMetrics(client.getMetrics(), "client", confJson); + addMetrics(client.getBridgeService().getMetrics(), "taskPollingService", confJson); + addMetrics(client.getEventsService().getMetrics(), "eventsService", confJson); + addMetrics(client.getTestsService().getMetrics(), "testsService", confJson); + addMetrics(client.getLogsService().getMetrics(), "buildLogsService", confJson); + addMetrics(client.getVulnerabilitiesService().getMetrics(), "vulnerabilitiesService", confJson); + addMetrics(client.getSonarService().getMetrics(), "sonarService", confJson); + addMetrics(client.getCoverageService().getMetrics(), "coverageService", confJson); + addMetrics(client.getSCMDataService().getMetrics(), "scmDataService", confJson); + addMetrics(client.getTasksProcessor().getMetrics(), "tasksProcessor", confJson); + addMetrics(client.getConfigurationService().getMetrics(), "configurationService", confJson); + addMetrics(client.getRestService().obtainOctaneRestClient().getMetrics(), "restClient", confJson); + + + allMetricsJson.put(client.getConfigurationService().getConfiguration().getLocationForLog(), confJson); + } + ); + result.put("metrics", allMetricsJson); + } + + return result; + } + + private void addMetrics(Map metrics, String metricsGroup, JSONObject confJson) { + JSONObject metricsJson = new JSONObject(); + metrics.entrySet().forEach(e -> { + String value = e.getValue() instanceof Date ? format.format(e.getValue()) : e.getValue().toString(); + metricsJson.put(e.getKey(), value); + }); + confJson.put(metricsGroup, metricsJson); + } + + private void resetJobListCache() { + OctaneSDK.getClients().stream().forEach(oc -> { + oc.getTasksProcessor().resetJobListCache(); + }); + } + + private void resetOctaneRootsCache() { + OctaneSDK.getClients().stream().forEach(oc -> { + oc.getConfigurationService().resetOctaneRootsCache(); + }); + } + + private JSONObject readOctaneRootsCache() { + JSONObject result = new JSONObject(); + OctaneSDK.getClients().forEach( + client -> { + com.hp.octane.integrations.services.configuration.ConfigurationService cs = client.getConfigurationService(); + result.put(cs.getConfiguration().getLocationForLog(), cs.getOctaneRootsCacheCollection()); + } + ); + + return result; + } + + private void reEnqueueEvent(Map parameterMap) { + if (!parameterMap.containsKey(INSTANCE_ID_PARAM)) { + throw new IllegalArgumentException("instanceId parameter is missing"); + } + if (!parameterMap.containsKey("eventType")) { + throw new IllegalArgumentException("eventType parameter is missing"); + } + if (!parameterMap.containsKey("jobId")) { + throw new IllegalArgumentException("jobId parameter is missing"); + } + if (!parameterMap.containsKey("buildId")) { + throw new IllegalArgumentException("buildId parameter is missing"); + } + + String instanceId = parameterMap.get(INSTANCE_ID_PARAM)[0]; + String eventType = parameterMap.get("eventType")[0]; + String jobId = parameterMap.get("jobId")[0]; + String buildId = parameterMap.get("buildId")[0]; + String rootId = null; + if (parameterMap.containsKey("rootId")) { + rootId = parameterMap.get("rootId")[0]; + } + + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + if ("tests".equals(eventType.toLowerCase())) { + octaneClient.getTestsService().enqueuePushTestsResult(jobId, buildId, rootId); + } else if ("commits".equals(eventType.toLowerCase())) { + octaneClient.getSCMDataService().enqueueSCMData(jobId, buildId, null, null); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/SonarQubeWebHookCrumbExclusion.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/SonarQubeWebHookCrumbExclusion.java new file mode 100644 index 0000000000..6bf9595ae3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/SonarQubeWebHookCrumbExclusion.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import hudson.Extension; +import hudson.security.csrf.CrumbExclusion; + +import java.io.IOException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * this class allows webhook resource to be excluded from CSRF validations + * in case jenkins configured to have this kind of validation + */ + +@Extension +public class SonarQubeWebHookCrumbExclusion extends CrumbExclusion { + + @Override + public boolean process(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { + String pathInfo = req.getPathInfo(); + if (pathInfo == null || pathInfo.isEmpty()) { + return false; + } + if (!pathInfo.equals(getExclusionPath())) { + return false; + } + chain.doFilter(req, resp); + return true; + } + + private String getExclusionPath() { + return "/" + Webhooks.WEBHOOK_PATH + Webhooks.NOTIFY_METHOD; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTActionDetectionBuildAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTActionDetectionBuildAction.java new file mode 100644 index 0000000000..4bf6deba70 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTActionDetectionBuildAction.java @@ -0,0 +1,235 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.uft.items.*; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.executor.UFTTestDetectionService; +import hudson.model.AbstractBuild; +import hudson.model.Action; +import hudson.model.Run; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Class responsible to show report of {@link UFTTestDetectionService} for MBT + */ +public class UFTActionDetectionBuildAction implements Action { + + private AbstractBuild build; + + private UftTestDiscoveryResult results; + + private List actions; + + private Map> actionToParametersMap; + + private List parameters; + + public UFTActionDetectionBuildAction(final AbstractBuild build, UftTestDiscoveryResult results) { + this.build = build; + + setResults(results); + } + + private List getItemsWithStatus(List entities, OctaneStatus status) { + return entities.stream() + .filter(item -> status.equals(item.getOctaneStatus())) + .collect(Collectors.toList()); + } + + private List flattenActions(UftTestDiscoveryResult results) { + return results.getAllTests().stream() + .map(AutomatedTest::getActions) + .flatMap(Collection::stream) + .filter(action -> !action.getOctaneStatus().equals(OctaneStatus.NONE)) + .collect(Collectors.toList()); + } + + private List flattenParameters(List actions) { + return actions.stream() + .map(UftTestAction::getParameters) + .flatMap(Collection::stream) + .filter(parameter -> !parameter.getOctaneStatus().equals(OctaneStatus.NONE)) + .collect(Collectors.toList()); + } + + private Map> setActionToParametersMap() { + return actions.stream() + .filter(action -> CollectionUtils.isNotEmpty(action.getParameters())) + .collect(Collectors.toMap(UftTestAction::getRepositoryPath, UftTestAction::getParameters)); + } + + @Override + public String getIconFileName() { + return "notepad.png"; + } + + @Override + public String getDisplayName() { + return Messages.UFTActionDetectionBuildActionConfigurationLabel(); + } + + @Override + public String getUrlName() { + return "uft_report"; + } + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + public UftTestDiscoveryResult getResults() { + return results; + } + + public void setResults(UftTestDiscoveryResult results) { + this.results = results; + init(results); + } + + public List getActions() { + return actions; + } + + public void setActions(List actions) { + this.actions = actions; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasNewActions() { + return getNewActions().size() > 0; + } + + public List getNewActions() { + return (List) getItemsWithStatus(actions, OctaneStatus.NEW); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasDeletedActions() { + return getDeletedActions().size() > 0; + } + + public List getDeletedActions() { + return (List) getItemsWithStatus(actions, OctaneStatus.DELETED); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasUpdatedActions() { + return getUpdatedActions().size() > 0; + } + + public List getUpdatedActions() { + return (List) getItemsWithStatus(actions, OctaneStatus.MODIFIED); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasNewParameters() { + return getNewParameters().size() > 0; + } + + public List getNewParameters() { + return (List) getItemsWithStatus(parameters, OctaneStatus.NEW); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasDeletedParameters() { + return getDeletedParameters().size() > 0; + } + + public List getDeletedParameters() { + return (List) getItemsWithStatus(parameters, OctaneStatus.DELETED); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTActionDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasUpdatedParameters() { + return getUpdatedParameters().size() > 0; + } + + public List getUpdatedParameters() { + return (List) getItemsWithStatus(parameters, OctaneStatus.MODIFIED); + } + + public boolean getHasQuotedPaths() { + return results.isHasQuotedPaths(); + } + + public Map> getActionToParametersMap() { + return actionToParametersMap; + } + + private void init(UftTestDiscoveryResult results) { + boolean isEmptyResults = results == null; + if (isEmptyResults) { + this.results = new UftTestDiscoveryResult(); + this.actions = Collections.emptyList(); + this.actionToParametersMap = Collections.emptyMap(); + this.parameters = Collections.emptyList(); + } else { + this.actions = flattenActions(results); + this.actionToParametersMap = setActionToParametersMap(); + this.parameters = flattenParameters(actions); + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java new file mode 100644 index 0000000000..3ca8b2827e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionBuildAction.java @@ -0,0 +1,166 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.uft.items.OctaneStatus; +import com.hp.octane.integrations.uft.items.SupportsOctaneStatus; +import com.hp.octane.integrations.uft.items.UftTestDiscoveryResult; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.executor.UFTTestDetectionService; +import hudson.model.AbstractBuild; +import hudson.model.Action; +import hudson.model.Run; + +import java.util.List; + +/** + * Class responsible to show report of {@link UFTTestDetectionService} + */ +public class UFTTestDetectionBuildAction implements Action { + private AbstractBuild build; + + + private UftTestDiscoveryResult results; + + @Override + public String getIconFileName() { + return "notepad.png"; + } + + @Override + public String getDisplayName() { + return Messages.UFTTestDetectionBuildActionConfigurationLabel(); + } + + @Override + public String getUrlName() { + return "uft_report"; + } + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + public UFTTestDetectionBuildAction(final AbstractBuild build, UftTestDiscoveryResult results) { + this.build = build; + this.results = results == null ? new UftTestDiscoveryResult() : results; + } + + public UftTestDiscoveryResult getResults() { + return results; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasNewTests() { + return countItemsWithStatus(OctaneStatus.NEW, results.getAllTests()) > 0; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasDeletedTests() { + return countItemsWithStatus(OctaneStatus.DELETED, results.getAllTests()) > 0; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasUpdatedTests() { + return countItemsWithStatus(OctaneStatus.MODIFIED, results.getAllTests()) > 0; + } + + public boolean getHasQuotedPaths() { + return results.isHasQuotedPaths(); + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasNewScmResources() { + return countItemsWithStatus(OctaneStatus.NEW, results.getAllScmResourceFiles()) > 0; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasDeletedScmResources() { + return countItemsWithStatus(OctaneStatus.DELETED, results.getAllScmResourceFiles()) > 0; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasUpdatedScmResources() { + return countItemsWithStatus(OctaneStatus.MODIFIED, results.getAllScmResourceFiles()) > 0; + } + + /** + * used by ~\src\main\resources\com\hp\application\automation\tools\octane\actions\UFTTestDetectionBuildAction\index.jelly + * + * @return + */ + public boolean getHasDeletedFolders() { + return results.getDeletedFolders().size() > 0; + } + + + public void setResults(UftTestDiscoveryResult results) { + this.results = results; + } + + private static int countItemsWithStatus(OctaneStatus status, List items) { + + int count = 0; + for (SupportsOctaneStatus item : items) { + if (item.getOctaneStatus().equals(status)) { + count++; + } + } + return count; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java new file mode 100644 index 0000000000..54ada4c8b4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/UFTTestDetectionPublisher.java @@ -0,0 +1,345 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.entities.Entity; +import com.hp.octane.integrations.dto.entities.EntityConstants; +import com.hp.octane.integrations.dto.entities.impl.EntityImpl; +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.hp.octane.integrations.services.configuration.ConfigurationService; +import com.hp.octane.integrations.services.entities.EntitiesService; +import com.hp.octane.integrations.services.entities.QueryHelper; +import com.hp.octane.integrations.uft.items.UftTestDiscoveryResult; +import com.microfocus.application.automation.tools.octane.JellyUtils; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.executor.*; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginFactory; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginHandler; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.Launcher; +import hudson.model.*; +import hudson.scm.NullSCM; +import hudson.scm.SCM; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.ListBoxModel; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Post-build action of Uft test detection + */ + +public class UFTTestDetectionPublisher extends Recorder { + private String configurationId; + private String workspaceName; + private String scmRepositoryId; + private TestingToolType testingToolType; + + public String getWorkspaceName() { + return workspaceName; + } + + public String getScmRepositoryId() { + return scmRepositoryId; + } + + // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" + @DataBoundConstructor + public UFTTestDetectionPublisher(String configurationId, String workspaceName, String scmRepositoryId) { + this.configurationId = configurationId; + this.workspaceName = workspaceName; + this.scmRepositoryId = scmRepositoryId; + this.testingToolType = TestingToolType.UFT; + } + + public void setTestingToolType(TestingToolType testingToolType) { + this.testingToolType = testingToolType; + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { + UFTTestDetectionService.printToConsole(listener, "UFTTestDetectionPublisher is started."); + + try { + //validate configuration id + if (configurationId == null || JellyUtils.NONE.equals(configurationId)) { + throw new IllegalArgumentException("ALM Octane configuration is missing."); + } + + if (workspaceName == null || JellyUtils.NONE.equals(workspaceName)) { + throw new IllegalArgumentException("ALM Octane workspace is missing."); + } + + //validate scm repository id + if (StringUtils.isEmpty(scmRepositoryId)) { + generateScmRepository(build, listener); + } + } catch (IllegalArgumentException e) { + UFTTestDetectionService.printToConsole(listener, e.getMessage()); + build.setResult(Result.FAILURE); + return false; + } + + try { + // backward compatibility + if(testingToolType == null || TestingToolType.UNKNOWN.equals(testingToolType)) { + testingToolType = TestingToolType.UFT; + } + + UftTestDiscoveryResult results = build.getWorkspace().act(new UFTTestDetectionCallable(build, configurationId, workspaceName, getScmRepositoryId(), listener, testingToolType)); + Action buildAction = getBuildAction(testingToolType, build, results); + build.addAction(buildAction); + + if (results.hasChanges()) { + UFTTestDetectionService.publishDetectionResults(build, listener, results); + UftTestDiscoveryDispatcher dispatcher = getExtension(UftTestDiscoveryDispatcher.class); + dispatcher.enqueueResult(configurationId, build.getProject().getFullName(), build.getNumber(), workspaceName); + + } + if (!results.getDeletedFolders().isEmpty()) { + UFTTestDetectionService.printToConsole(listener, String.format("Found %s deleted folders", results.getDeletedFolders().size())); + UFTTestDetectionService.printToConsole(listener, "To sync deleted items - full sync required. Triggering job with full sync parameter."); + handleDeletedFolders(build); + } + } catch (Exception e) { + UFTTestDetectionService.printToConsole(listener, "UFTTestDetectionPublisher.perform is failed : " + e.getMessage()); + build.setResult(Result.FAILURE); + } + + return true; + } + + private static Action getBuildAction(TestingToolType testingToolType, final AbstractBuild build, UftTestDiscoveryResult results) { + if(TestingToolType.MBT.equals(testingToolType)) { + return new UFTActionDetectionBuildAction(build, results); + } else { + return new UFTTestDetectionBuildAction(build, results); + } + } + + private void generateScmRepository(AbstractBuild build, BuildListener listener) { + SCM scm = build.getProject().getScm(); + if (scm instanceof NullSCM) { + throw new IllegalArgumentException("SCM definition is missing in the job"); + } + ScmPluginHandler scmPluginHandler = ScmPluginFactory.getScmHandlerByScmPluginName(scm.getType()); + String url = ScmPluginFactory.getScmHandlerByScmPluginName(scm.getType()).getScmRepositoryUrl(scm); + if (StringUtils.isEmpty(url)) { + throw new IllegalArgumentException("SCM url is not defined in the job"); + } + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(configurationId); + EntitiesService entitiesService = octaneClient.getEntitiesService(); + ConfigurationService configurationService = octaneClient.getConfigurationService(); + long workspaceId = Long.parseLong(workspaceName); + + if (configurationService.isOctaneVersionGreaterOrEqual("15.1.28")) { + scmRepositoryId = getScmRepositoriesWithRoots(listener, scmPluginHandler, url, entitiesService, workspaceId); + } else { + scmRepositoryId = getScmRepositoriesLegacy(listener, scmPluginHandler, url, entitiesService, workspaceId); + } + + try { + build.getProject().save(); + } catch (IOException e) { + throw new IllegalArgumentException("Failed to save job with updated SCM repository. Update manually SCM repository to " + scmRepositoryId + ". Error message : " + e.getMessage()); + } + + UFTTestDetectionService.printToConsole(listener, "SCM repository field value is updated to " + scmRepositoryId); + } + + + private static String getScmRepositoriesLegacy(BuildListener listener, ScmPluginHandler scmPluginHandler, String url, EntitiesService entitiesService, long workspaceId) { + String scmRepoId; + String collectionName = "scm_repositories"; + List conditions = Collections.singletonList(QueryHelper.condition("url", url)); + List foundEntities = entitiesService.getEntities(workspaceId, collectionName, conditions, Collections.singletonList(EntityConstants.Base.ID_FIELD)); + if (!foundEntities.isEmpty()) { + scmRepoId = foundEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, "SCM repository " + url + " is already exist in ALM Octane with id=" + scmRepoId); + } else { + //create a new scm repository + Entity newScmRepository = buildNewRepoEntity(scmPluginHandler, url, "scm_repository"); + String name = scmPluginHandler.tryExtractUrlShortName(url) + (SCMType.GIT.equals(scmPluginHandler.getScmType()) ? ":master" : ""); + newScmRepository.setName(name); + + List createEntities = entitiesService.postEntities(workspaceId, collectionName, Collections.singletonList(newScmRepository)); + scmRepoId = createEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, "SCM repository " + url + " is created in ALM Octane with id=" + scmRepoId); + } + return scmRepoId; + } + + private static String getScmRepositoriesWithRoots(BuildListener listener, ScmPluginHandler scmPluginHandler, String url, EntitiesService entitiesService, long workspaceId) { + String scmBranchId; + String scmRootId; + String branchCollectionName = EntityConstants.ScmRepository.COLLECTION_NAME; + String rootCollectionName = EntityConstants.ScmRepositoryRoot.COLLECTION_NAME; + + boolean isGit = SCMType.GIT.equals(scmPluginHandler.getScmType()); + + //find repository root + List conditions = Collections.singletonList(QueryHelper.condition("url", url)); + List foundEntities = entitiesService.getEntities(workspaceId, rootCollectionName, conditions, Collections.singletonList(EntityConstants.Base.ID_FIELD)); + if (!foundEntities.isEmpty()) { + scmRootId = foundEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, String.format("SCM repository root %s is already exist in ALM Octane with id=%s", url, scmRootId)); + } else { + //create a new scm repository root + Entity newScmRepositoryRoot = buildNewRepoEntity(scmPluginHandler, url, EntityConstants.ScmRepositoryRoot.ENTITY_NAME); + List createEntities = entitiesService.postEntities(workspaceId, rootCollectionName, Collections.singletonList(newScmRepositoryRoot)); + scmRootId = createEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, String.format("SCM repository root %s is created in ALM Octane with id=%s", url, scmRootId)); + } + + //find branch + String name = scmPluginHandler.tryExtractUrlShortName(url) + (isGit ? ":master" : ""); + String branchCondition = QueryHelper.orConditions(QueryHelper.condition(EntityConstants.ScmRepository.BRANCH_FIELD, "master"), + QueryHelper.conditionEmpty(EntityConstants.ScmRepository.BRANCH_FIELD)); + conditions = Collections.singletonList(branchCondition); + foundEntities = entitiesService.getEntities(workspaceId, branchCollectionName, conditions, + Arrays.asList(EntityConstants.ScmRepository.ID_FIELD, EntityConstants.ScmRepository.BRANCH_FIELD)); + if (!foundEntities.isEmpty()) { + scmBranchId = foundEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, String.format("SCM branch %s is already exist in ALM Octane with id=%s", name, scmBranchId)); + } else { + //create a new branch + Entity newBranch = buildNewRepoEntity(scmPluginHandler, url, "scm_repository"); + newBranch.setName(name); + + if (isGit) { + newBranch.setField(EntityConstants.ScmRepository.BRANCH_FIELD, "master"); + } + + + Entity scmRoot = new EntityImpl().setType(EntityConstants.ScmRepositoryRoot.ENTITY_NAME).setId(scmRootId); + newBranch.setField(EntityConstants.ScmRepository.PARENT_FIELD, scmRoot); + List createEntities = entitiesService.postEntities(workspaceId, branchCollectionName, Collections.singletonList(newBranch)); + scmBranchId = createEntities.get(0).getId(); + UFTTestDetectionService.printToConsole(listener, String.format("SCM branch %s is created in ALM Octane with id=%s", name, scmBranchId)); + } + + return scmBranchId; + } + + private static Entity buildNewRepoEntity(ScmPluginHandler scmPluginHandler, String url, String entityType) { + Entity newScmRepositoryRoot = new EntityImpl(); + newScmRepositoryRoot.setType(entityType); + String name = scmPluginHandler.tryExtractUrlShortName(url); + newScmRepositoryRoot.setName(name); + newScmRepositoryRoot.setField("url", url); + newScmRepositoryRoot.setField("scm_type", scmPluginHandler.getScmType().getOctaneId()); + return newScmRepositoryRoot; + } + + private void handleDeletedFolders(AbstractBuild build) { + //This situation is relevant for SVN only. + //Deleting folder - SCM event doesn't supply information about deleted items in deleted folder - only top-level directory. + //In this case need to do for each deleted folder - need to check with Octane what tests and data tables were under this folder. + //so for each deleted folder - need to do at least 2 requests. In this situation - decided to activate full sync as it already tested scenario. + //Full sync wil be triggered with delay of 60 secs to give the dispatcher possibility to sync other found changes + + //triggering full sync + + + FreeStyleProject proj = (FreeStyleProject) build.getParent(); + List newParameters = new ArrayList<>(); + for (ParameterValue param : build.getAction(ParametersAction.class).getParameters()) { + ParameterValue paramForSet; + if (param.getName().equals(UftConstants.FULL_SCAN_PARAMETER_NAME)) { + paramForSet = new BooleanParameterValue(UftConstants.FULL_SCAN_PARAMETER_NAME, true); + } else { + paramForSet = param; + } + newParameters.add(paramForSet); + } + + ParametersAction parameters = new ParametersAction(newParameters); + CauseAction causeAction = new CauseAction(new FullSyncRequiredCause(build.getId())); + proj.scheduleBuild2(60, parameters, causeAction); + + } + + private static T getExtension(Class clazz) { + ExtensionList items = Jenkins.get().getExtensionList(clazz); + return items.get(0); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + public String getConfigurationId() { + return configurationId; + } + + @Extension // This indicates to Jenkins that this is an implementation of an extension point. + public static final class DescriptorImpl extends BuildStepDescriptor { + + public ListBoxModel doFillConfigurationIdItems() { + return JellyUtils.fillConfigurationIdModel(); + } + + public ListBoxModel doFillWorkspaceNameItems(@QueryParameter String configurationId, @QueryParameter(value = "workspaceName") String workspaceName) { + return JellyUtils.fillWorkspaceModel(configurationId, workspaceName); + } + + public boolean isApplicable(Class aClass) { + return aClass.equals(FreeStyleProject.class); + } + + public String getDisplayName() { + return Messages.UFTTestDetectionPublisherConfigurationLabel(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/WebhookAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/WebhookAction.java new file mode 100644 index 0000000000..1206905bcb --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/WebhookAction.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.microfocus.application.automation.tools.octane.model.SonarHelper; +import hudson.model.Action; + +import javax.annotation.CheckForNull; +import java.util.Set; + +/* + Class for handling webhook exception + */ + +public class WebhookAction implements Action { + private Boolean isExpectingToGetWebhookCall; + private String serverUrl; + private Set dataTypeSet; + + public WebhookAction(Boolean isExpectingToGetWebhookCall, String serverUrl, Set dataTypeSet) { + this.isExpectingToGetWebhookCall = isExpectingToGetWebhookCall; + this.serverUrl = serverUrl; + this.dataTypeSet = dataTypeSet; + } + + public String getServerUrl() { + + return serverUrl; + } + + public Boolean getExpectingToGetWebhookCall() { + return isExpectingToGetWebhookCall; + } + + public Set getDataTypeSet() { + return dataTypeSet; + } + + @CheckForNull + @Override + public String getIconFileName() { + return null; + } + + @CheckForNull + @Override + public String getDisplayName() { + return null; + } + + @CheckForNull + @Override + public String getUrlName() { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/Webhooks.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/Webhooks.java new file mode 100644 index 0000000000..fb563da6b4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/Webhooks.java @@ -0,0 +1,253 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.services.vulnerabilities.ToolType; +import com.microfocus.application.automation.tools.octane.ImpersonationUtil; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.SonarHelper; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.octane.vulnerabilities.VulnerabilitiesUtils; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.model.Item; +import hudson.model.Job; +import hudson.model.Run; +import hudson.model.UnprotectedRootAction; +import hudson.security.ACLContext; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 8/10/14 + * Time: 12:47 PM + * To change this template use File | Settings | File Templates. + */ + +@Extension +public class Webhooks implements UnprotectedRootAction { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(Webhooks.class); + // url details + public static final String WEBHOOK_PATH = "webhooks"; + public static final String NOTIFY_METHOD = "/notify"; + + private String PROJECT_KEY_KEY = "PROJECT_KEY"; + private String SONAR_URL_KEY = "SONAR_URL"; + private String SONAR_TOKEN_KEY = "SONAR_TOKEN"; + private String REMOTE_TAG_KEY = "REMOTE_TAG"; + + // json parameter names + private final String PROJECT = "project"; + private final String SONAR_PROJECT_KEY_NAME = "key"; + private final String IS_EXPECTING_FILE_NAME = "is_expecting.txt"; + private final String JOB_NAME_PARAM_NAME = "sonar.analysis.jobName"; + private final String BUILD_NUMBER_PARAM_NAME = "sonar.analysis.buildNumber"; + private static final String PROJECT_KEY_HEADER = "X-SonarQube-Project"; + + public String getIconFileName() { + return null; + } + + public String getDisplayName() { + return null; + } + + public String getUrlName() { + return WEBHOOK_PATH; + } + + @RequirePOST + public void doNotify(StaplerRequest req, StaplerResponse res) throws IOException { + logger.info("Received POST from " + req.getRemoteHost()); + // legal user, handle request + JSONObject inputNotification = (JSONObject) JSONValue.parse(req.getInputStream()); + Object properties = inputNotification.get("properties"); + + ExtensionList allConfigurations = GlobalConfiguration.all(); + GlobalConfiguration sonarConfiguration = allConfigurations.getDynamic(SonarHelper.SONAR_GLOBAL_CONFIG); + + // without build context, could not send octane relevant data + if (sonarConfiguration != null && !req.getHeader(PROJECT_KEY_HEADER).isEmpty() && properties instanceof Map) { + // get relevant parameters + Map sonarAttachedProperties = (Map) properties; + // filter notifications from sonar projects, who haven't configured listener parameters + if (sonarAttachedProperties.containsKey(BUILD_NUMBER_PARAM_NAME) && sonarAttachedProperties.containsKey(JOB_NAME_PARAM_NAME)) { + String jobName = (String) sonarAttachedProperties.get(JOB_NAME_PARAM_NAME); + String buildIdStr = (String) (sonarAttachedProperties.get(BUILD_NUMBER_PARAM_NAME)); + int buildId; + try { + buildId = Integer.parseInt(buildIdStr); + } catch (NumberFormatException e) { + logger.warn("Got request from sonarqube webhook listener, but buildIdStr is illegal : " + buildIdStr); + res.setStatus(HttpStatus.SC_NOT_ACCEPTABLE); + return; + } + logger.warn(String.format("Got sonarqube webhook for : %s #%s", jobName, buildIdStr)); + + Run run = null; + for (OctaneClient octaneClient : OctaneSDK.getClients()) { + try { + if (octaneClient.getConfigurationService().getConfiguration().isDisabled()) { + continue; + } + Job jenkinsJob = getJob(octaneClient, jobName); + if (jenkinsJob == null) { + continue; + } + run = jenkinsJob.getBuildByNumber(buildId); + if (run == null) { + logger.warn("Got request from sonarqube webhook listener, but build " + buildIdStr + " context could not be resolved"); + res.setStatus(HttpStatus.SC_NOT_ACCEPTABLE); + return; + } + if (!isRunExpectingToGetWebhookCall(run) || isRunAlreadyGotWebhookCall(run)) { + return; + } + + //enqueue coverage and vulnerabilities + WebhookAction action = run.getAction(WebhookAction.class); + String parents = BuildHandlerUtils.getRootJobCiIds(run); + String sonarToken = SonarHelper.getSonarInstallationTokenByUrl(sonarConfiguration, action.getServerUrl(), run); + HashMap project = (HashMap) inputNotification.get(PROJECT); + String sonarProjectKey = (String) project.get(SONAR_PROJECT_KEY_NAME); + String ciJobId = BuildHandlerUtils.translateFolderJobName(jobName); + + if (action.getDataTypeSet().contains(SonarHelper.DataType.COVERAGE)) { + // use SDK to fetch and push data + octaneClient.getSonarService().enqueueFetchAndPushSonarCoverage(ciJobId, buildIdStr, sonarProjectKey, action.getServerUrl(), sonarToken, parents); + } + if (action.getDataTypeSet().contains(SonarHelper.DataType.VULNERABILITIES)) { + Map additionalProperties = new HashMap<>(); + additionalProperties.put(PROJECT_KEY_KEY, sonarProjectKey); + additionalProperties.put(SONAR_URL_KEY, action.getServerUrl()); + additionalProperties.put(SONAR_TOKEN_KEY, sonarToken); + additionalProperties.put(REMOTE_TAG_KEY, sonarProjectKey); + octaneClient.getVulnerabilitiesService().enqueueRetrieveAndPushVulnerabilities(ciJobId, buildIdStr, ToolType.SONAR, run.getStartTimeInMillis(), + VulnerabilitiesUtils.getFortifyTimeoutHours(octaneClient.getInstanceId()), additionalProperties, parents); + + } + res.setStatus(HttpStatus.SC_OK); // sonar should get positive feedback for webhook + } catch (Exception e) { + logger.error("exception occurred while trying to enqueue fetchAndPush task to octane, clientId: " + octaneClient.getInstanceId() + "" + + ", jobName: " + jobName + ", build: " + buildIdStr + ",", e); + } + } + if (run != null) { + markBuildAsReceivedWebhookCall(run); + } + } + } + } + + private Job getJob(OctaneClient octaneClient, String jobName) { + ACLContext aclContext = null; + try { + aclContext = ImpersonationUtil.startImpersonation(octaneClient.getInstanceId(), null); + Item topLevelItem = Jenkins.get().getItemByFullName(jobName); + if (topLevelItem != null && topLevelItem instanceof Job) { + Job jenkinsJob = ((Job) topLevelItem); + return jenkinsJob; + } else { + return null; + } + } finally { + if (aclContext != null) { + ImpersonationUtil.stopImpersonation(aclContext); + } + } + } + + /** + * this method checks if run already got webhook call. + * we are only handling the first call, laters call for the same run + * will be rejected + * + * @param run run + * @return result + */ + private Boolean isRunAlreadyGotWebhookCall(Run run) { + try { + // run is promised to be exist at this point + File rootDir = run.getRootDir(); + File isExpectingFile = new File(rootDir, IS_EXPECTING_FILE_NAME); + FileInputStream fis = new FileInputStream(isExpectingFile); + ObjectInputStream ois = new ObjectInputStream(fis); + return (Boolean) ois.readObject(); + } catch (Exception e) { + return Boolean.FALSE; + } + } + + /** + * use build action to decide whether we need to get a webhook call from sonarqube + * + * @param run build + * @return true or false + */ + private Boolean isRunExpectingToGetWebhookCall(Run run) { + WebhookAction action = run.getAction(WebhookAction.class); + return action != null && action.getExpectingToGetWebhookCall(); + } + + /** + * this method persist the fact a specific run got webhook call. + * + * @param run run + * @throws IOException exception + */ + private void markBuildAsReceivedWebhookCall(Run run) throws IOException { + if (run == null) { + return; + } + File buildBaseFolder = run.getRootDir(); + File isExpectingFile = new File(buildBaseFolder, IS_EXPECTING_FILE_NAME); + FileOutputStream fos = new FileOutputStream(isExpectingFile); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(true); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoveragePublisherAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoveragePublisherAction.java new file mode 100644 index 0000000000..1313c83b8f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoveragePublisherAction.java @@ -0,0 +1,120 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.coverage; + +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.FilePath; +import hudson.model.*; + +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * this action initiate a copy of all coverage reports from workspace to build folder. + * the files are calculated by a pattern that the user enters in job configuration page + */ +public class CoveragePublisherAction implements Action { + private final Run build; + + public CoveragePublisherAction(Run build, TaskListener listener) { + this.build = build; + CoverageService.setListener(listener); + } + + /** + * this method copy all reports from specified path pattern + * + * @return list of file names that were copied; NEVER NULL; if an empty list returned - no coverage reports found + */ + public List copyCoverageReportsToBuildFolder(String filePattern, String defaultFileName) { + List result = new LinkedList<>(); + FilePath workspace = BuildHandlerUtils.getWorkspace(build); + if (workspace != null) { + try { + CoverageService.log("start copying coverage report to build folder, using file patten of " + filePattern); + String[] files = CoverageService.getCoverageFiles(workspace, filePattern); + List matchingReportFiles = filterFilesByFileExtension(files); + int index = 0; + + for (String fileName : matchingReportFiles) { + File resultFile = new File(workspace.child(fileName).toURI()); + String nextOutputFilename = CoverageService.getCoverageReportFileName(index++, defaultFileName); + result.add(nextOutputFilename); + File targetReportFile = new File(build.getRootDir(), nextOutputFilename); + CoverageService.copyCoverageFile(resultFile, targetReportFile, workspace); + } + + if (result.isEmpty()) { + // most likely a configuration error in the job - e.g. false pattern to match the cucumber result files + CoverageService.log("No coverage file that matched the specified pattern was found in workspace"); + } + } catch (Exception e) { + CoverageService.log("Copying coverage files to build folder failed because of " + e.toString()); + } + } + return result; + } + + /** + * pre validation of coverage files by file extension. + * + * @param files to validate + * @return filtered list of files + */ + private ArrayList filterFilesByFileExtension(String[] files) { + ArrayList filteredList = new ArrayList<>(); + for (String fileFullPath : files) { + if (fileFullPath.endsWith(CoverageService.Lcov.LCOV_FILE_EXTENSION) || fileFullPath.endsWith(CoverageService.Jacoco.JACOCO_FILE_EXTENSION)) { + filteredList.add(fileFullPath); + } + } + return filteredList; + } + + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoverageService.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoverageService.java new file mode 100644 index 0000000000..1577ab5219 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/coverage/CoverageService.java @@ -0,0 +1,147 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.coverage; + +import hudson.FilePath; +import hudson.Util; +import hudson.model.TaskListener; +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.types.FileSet; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; + +/** + * Helper Service for coverage publisher + */ +public class CoverageService { + private static final String COVERAGE_REPORT_FILE_NAME_PREFIX = "coverage_report"; + private static TaskListener listener; + + public static class Jacoco { + public static final String JACOCO_TYPE = "JACOCOXML"; + public static final String JACOCO_FILE_EXTENSION = ".xml"; + public static final String JACOCO_DEFAULT_FILE_NAME = "jacoco" + JACOCO_FILE_EXTENSION; + public static final String JACOCO_DEFAULT_PATH = "**/target/site/*/" + JACOCO_DEFAULT_FILE_NAME; + + } + public static class Lcov { + public static final String LCOV_TYPE = "LCOV"; + public static final String LCOV_FILE_EXTENSION = ".info"; + public static final String LCOV_DEFAULT_FILE_NAME = "lcov" + LCOV_FILE_EXTENSION; + public static final String LCOV_DEFAULT_PATH = "**/coverage/" + LCOV_DEFAULT_FILE_NAME; + + } + + public static String getCoverageReportFileName(int index, String fileSuffix) { + return COVERAGE_REPORT_FILE_NAME_PREFIX + index + "-" + fileSuffix; + } + + public static String[] getCoverageFiles(final FilePath workspace, String glob) throws IOException, InterruptedException { + log(String.format("Looking for files that match the pattern %s in root directory %s", glob, workspace.getName())); + return workspace.act(new ResultFilesCallable(glob)); + } + + public static void copyCoverageFile(File resultFile, File targetReportFile, final FilePath workspace) throws IOException, InterruptedException { + log(String.format("Copying %s to %s", resultFile.getPath(), targetReportFile)); + + byte[] content = workspace.act(new FileContentCallable(resultFile)); + + if (validateContent(content)) { + log("Got coverage file content"); + + try (FileOutputStream os = new FileOutputStream(targetReportFile)) { + os.write(content); + } + log(String.format("coverage file copied successfully to %s", targetReportFile.getPath())); + } else { + log("coverage file content corrupted, failed to copy the file to target destination"); + } + } + + /** + * most of the validations will be done in octane side + * this is a place holder to do more validations if needed + * @param content of the file + * @return status + */ + private static boolean validateContent(byte[] content) { + return content.length > 0; + } + + public static void log(final String message) { + if(listener != null) { + listener.getLogger().println(message); + } + } + + public static void setListener(TaskListener l) { + listener = l; + } + + /** + * this class searched for files that match specific pattern + */ + private static final class ResultFilesCallable extends MasterToSlaveFileCallable { + private final String glob; + + private ResultFilesCallable(String glob) { + this.glob = glob; + } + + @Override + public String[] invoke(File rootDir, VirtualChannel channel) throws IOException { + FileSet fs = Util.createFileSet(rootDir, glob); + DirectoryScanner ds = fs.getDirectoryScanner(); + return ds.getIncludedFiles(); + } + } + + private static final class FileContentCallable extends MasterToSlaveFileCallable { + private final File file; + + private FileContentCallable(File file) { + this.file = file; + } + + @Override + public byte[] invoke(File rootDir, VirtualChannel channel) throws IOException { + return Files.readAllBytes(file.toPath()); + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java new file mode 100644 index 0000000000..098dc068f3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberResultsService.java @@ -0,0 +1,144 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.cucumber; + +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.FilePath; +import hudson.Util; +import hudson.model.TaskListener; +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.types.FileSet; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; + +/** + * Helper Service for Gherkin results + */ +public class CucumberResultsService { + + public static final String GHERKIN_NGA_RESULTS_XML = "OctaneGherkinResults.xml"; + public static final String GHERKIN_NGA_RESULTS = "OctaneGherkinResults"; + public static final String DEFAULT_GLOB = "**/*" + GHERKIN_NGA_RESULTS_XML; + + private static TaskListener listener; + + public static String getGherkinResultFileName(int index) { + return GHERKIN_NGA_RESULTS + index + ".xml"; + } + + public static String[] getCucumberResultFiles(final FilePath workspace, String glob) throws IOException, InterruptedException { + if (glob == null || glob.isEmpty()) { + glob = DEFAULT_GLOB; + log(Messages.CucumberResultsActionEmptyConfiguration(), glob); + } + + log("Looking for files that match the pattern %s in root directory %s", glob, workspace.getName()); + return workspace.act(new ResultFilesCallable(glob)); + } + + public static void copyResultFile(File resultFile, File destinationFolder, final FilePath workspace) throws IOException, InterruptedException { + File existingReportFile; + int existingResultIndex = -1; + + log("Copying %s to %s", resultFile.getPath(), destinationFolder.getPath()); + + do { + existingReportFile = new File(destinationFolder, getGherkinResultFileName(++existingResultIndex)); + } while (existingReportFile.exists()); + log("New file name on destination will be %s", existingReportFile.getPath()); + + byte[] content = workspace.act(new FileContentCallable(resultFile)); + log("Got result file content"); + + validateContent(content); + + File target = existingReportFile; + try (FileOutputStream os = new FileOutputStream(target)) { + os.write(content); + } + log("Result file copied to %s", target.getPath()); + } + + private static void validateContent(byte[] content) { + String contentStr = new String(content, 0, Math.min(content.length , 2000)); + //Heuristic validation. we don't check the whole file structure here - we should be quick. + if(!contentStr.contains(" { + private final String glob; + + private ResultFilesCallable(String glob) { + this.glob = glob; + } + + @Override + public String[] invoke(File rootDir, VirtualChannel channel) throws IOException { + FileSet fs = Util.createFileSet(rootDir, glob); + DirectoryScanner ds = fs.getDirectoryScanner(); + return ds.getIncludedFiles(); + } + } + + private static final class FileContentCallable extends MasterToSlaveFileCallable { + private final File file; + + private FileContentCallable(File file) { + this.file = file; + } + + @Override + public byte[] invoke(File rootDir, VirtualChannel channel) throws IOException { + return Files.readAllBytes(file.toPath()); + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java new file mode 100644 index 0000000000..4dda6dbf63 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsAction.java @@ -0,0 +1,107 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.cucumber; + +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.FilePath; +import hudson.model.Action; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by franksha on 07/12/2016. + */ +public class CucumberTestResultsAction implements Action { + private final String glob; + private final Run build; + + CucumberTestResultsAction(Run run, String glob, TaskListener listener) { + this.build = run; + this.glob = glob; + CucumberResultsService.setListener(listener); + } + + public boolean copyResultsToBuildFolder(Run run, FilePath workspace) { + try { + CucumberResultsService.log(Messages.CucumberResultsActionCollecting()); + String[] files = CucumberResultsService.getCucumberResultFiles(workspace, glob); + boolean found = files.length > 0; + + for (String fileName : files) { + File resultFile = new File(workspace.child(fileName).toURI()); + if (resultFile.lastModified() == 0 || run.getStartTimeInMillis() < resultFile.lastModified()) { + // for some reason , on some linux machines last modified time for newly create gherkin result file is 0 - lets consider it as valid + CucumberResultsService.copyResultFile(resultFile, build.getRootDir(), workspace); + } else { + String pattern = "yyyy-MM-dd HH:mm:ss"; + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); + + CucumberResultsService.log("Found outdated file %s, build started at %s (%s), while file last update time is %s (%s) ", + resultFile.getPath(), dateFormat.format(new Date(run.getStartTimeInMillis())), String.valueOf(run.getStartTimeInMillis()), + dateFormat.format(new Date(resultFile.lastModified())), String.valueOf(resultFile.lastModified())); + } + } + + if (!found && build.getResult() != Result.FAILURE) { + // most likely a configuration error in the job - e.g. false pattern to match the cucumber result files + CucumberResultsService.log(Messages.CucumberResultsActionNotFound()); + } // else , if results weren't found but build result is failure - most likely a build failed before us. don't report confusing error message. + + return found; + + } catch (Exception e) { + CucumberResultsService.log(Messages.CucumberResultsActionError(), e.toString()); + return false; + } + } + + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java new file mode 100644 index 0000000000..1133652aec --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/actions/cucumber/CucumberTestResultsActionPublisher.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.cucumber; + +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.FormValidation; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Created by franksha on 07/12/2016. + */ +public class CucumberTestResultsActionPublisher extends Recorder implements SimpleBuildStep { + + private final String glob; + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + @DataBoundConstructor + public CucumberTestResultsActionPublisher(String cucumberResultsGlob) { + this.glob = cucumberResultsGlob; + } + + public String getCucumberResultsGlob() { + return glob; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) throws InterruptedException, IOException { + CucumberTestResultsAction action = new CucumberTestResultsAction(run, glob, taskListener); + run.addAction(action); + boolean isSuccessful = action.copyResultsToBuildFolder(run, workspace); + if (!isSuccessful) { + run.setResult(Result.FAILURE); + } + } + + @Override + public CucumberTestResultsActionPublisher.Descriptor getDescriptor() { + return (CucumberTestResultsActionPublisher.Descriptor) super.getDescriptor(); + } + + + @Symbol("publishGherkinResults") + @Extension + public static final class Descriptor extends BuildStepDescriptor { + + public boolean isApplicable(Class aClass) { + return true; + } + + public String getDisplayName() { + return Messages.CucumberReporterName(); + } + + public FormValidation doCheckCucumberResultsGlob(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException, ServletException { + if (value == null || value.isEmpty()) { + return FormValidation.warning(Messages.CucumberResultsActionEmptyConfigurationWarning(), CucumberResultsService.DEFAULT_GLOB); + } else if (project == null) { + return FormValidation.ok(); + } + return FilePath.validateFileMask(project.getSomeWorkspace(), value); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesBuildAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesBuildAction.java new file mode 100644 index 0000000000..5f92ad3bd4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesBuildAction.java @@ -0,0 +1,105 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.branches; + +import com.hp.octane.integrations.services.pullrequestsandbranches.BranchSyncResult; +import com.microfocus.application.automation.tools.octane.GitFetchUtils; +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.model.Action; +import hudson.model.Run; + +import javax.annotation.CheckForNull; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class BranchesBuildAction implements Action { + + private final Run build; + + private final BranchSyncResult branchSyncResult; + private final String filter; + private final String repositoryUrl; + private final Long index; + + private SimpleDateFormat dateFormat = null; + + @CheckForNull + @Override + public String getIconFileName() { + return "notepad.png"; + } + + public BranchesBuildAction(final Run build, BranchSyncResult branchSyncResult, String repositoryUrl, String filter, long index) { + this.index = index; + this.build = build; + this.branchSyncResult = branchSyncResult; + this.filter = filter; + this.repositoryUrl = repositoryUrl; + } + + @CheckForNull + @Override + public String getDisplayName() { + return Messages.BranchActionConfigurationLabel(); + } + + @CheckForNull + @Override + public String getUrlName() { + return "branch-report" + (index == null || index.equals(0l) ? "" : "-" + index); + } + + public BranchSyncResult getBranchSyncResult() { + return branchSyncResult; + } + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + public String getFormattedDate(long longTime) { + if (dateFormat == null) { + dateFormat = GitFetchUtils.generateDateFormat(); + } + return dateFormat.format(new Date(longTime)); + } + + public String getFilter() { + return filter; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesPublisher.java b/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesPublisher.java new file mode 100644 index 0000000000..f5f58b4288 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/branches/BranchesPublisher.java @@ -0,0 +1,324 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.branches; + +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.exceptions.OctaneBulkException; +import com.hp.octane.integrations.exceptions.OctaneValidationException; +import com.hp.octane.integrations.services.pullrequestsandbranches.BranchSyncResult; +import com.hp.octane.integrations.services.pullrequestsandbranches.PullRequestAndBranchService; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.BranchFetchParameters; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.FetchFactory; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.FetchHandler; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.ScmTool; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.AuthenticationStrategy; +import com.microfocus.application.automation.tools.octane.GitFetchUtils; +import com.microfocus.application.automation.tools.octane.JellyUtils; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.ListBoxModel; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.PrintStream; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Post-build action of Uft test detection + */ + +public class BranchesPublisher extends Recorder implements SimpleBuildStep { + private String configurationId; + private String workspaceId; + private String repositoryUrl; + private String credentialsId; + private String filter; + private String scmTool; + private String useSSHFormat; + + // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" + @DataBoundConstructor + public BranchesPublisher(String configurationId, String workspaceId, String scmTool, String repositoryUrl, String credentialsId, String filter) { + this.configurationId = JellyUtils.NONE.equalsIgnoreCase(configurationId) ? null : configurationId; + this.workspaceId = JellyUtils.NONE.equalsIgnoreCase(workspaceId) ? null : workspaceId; + this.repositoryUrl = repositoryUrl; + this.credentialsId = credentialsId; + this.filter = filter; + this.scmTool = JellyUtils.NONE.equalsIgnoreCase(scmTool) ? null : scmTool; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) throws InterruptedException, IOException { + performInternal(run, taskListener); + } + + @Override + public boolean perform(AbstractBuild build, @Nonnull Launcher launcher, BuildListener listener) { + performInternal(build, listener); + return build.getResult() == Result.SUCCESS; + } + + public void performInternal(@Nonnull Run run, @Nonnull TaskListener taskListener) { + LogConsumer logConsumer = new LogConsumer(taskListener.getLogger()); + logConsumer.printLog("BranchPublisher is started ***********************************************************************"); + if (configurationId == null) { + throw new IllegalArgumentException("ALM Octane configuration is not defined."); + } + if (workspaceId == null) { + throw new IllegalArgumentException("ALM Octane workspace is not defined."); + } + if (scmTool == null) { + throw new IllegalArgumentException("SCM Tool is not defined."); + } + + String myCredentialsId = credentialsId; + String myConfigurationId = configurationId; + String myWorkspaceId = workspaceId; + String myScmTool = scmTool; + String myUseSshFormat = useSSHFormat; + try { + EnvVars env = run.getEnvironment(taskListener); + myCredentialsId = env.expand(credentialsId); + myConfigurationId = env.expand(configurationId); + myWorkspaceId = env.expand(workspaceId); + myScmTool = env.expand(scmTool); + myUseSshFormat = env.expand(useSSHFormat); + } catch (IOException | InterruptedException e) { + taskListener.error("Failed loading build environment " + e); + } + + BranchFetchParameters fp = createFetchParameters(run, taskListener, myUseSshFormat, logConsumer::printLog); + + StandardCredentials credentials = GitFetchUtils.getCredentialsById(myCredentialsId, run, taskListener.getLogger()); + AuthenticationStrategy authenticationStrategy = GitFetchUtils.getAuthenticationStrategy(credentials); + + try { + //GET BRANCHES FROM CI SERVER + FetchHandler fetchHandler = FetchFactory.getHandler(ScmTool.fromValue(myScmTool), authenticationStrategy); + + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(myConfigurationId); + logConsumer.printLog("ALM Octane " + octaneClient.getConfigurationService().getConfiguration().getLocationForLog() + ", workspace - " + myWorkspaceId); + octaneClient.validateOctaneIsActiveAndSupportVersion(PullRequestAndBranchService.BRANCH_COLLECTION_SUPPORTED_VERSION); + PullRequestAndBranchService service = OctaneSDK.getClientByInstanceId(myConfigurationId).getPullRequestAndBranchService(); + BranchSyncResult result = service.syncBranchesToOctane(fetchHandler, fp, Long.parseLong(myWorkspaceId), GitFetchUtils::getUserIdForCommit, logConsumer::printLog); + + String repoUrlForOctane = fp.isUseSSHFormat() ? fp.getRepoUrlSsh() : fp.getRepoUrl(); + GitFetchUtils.updateRepoTemplates(service, fetchHandler, fp.getRepoUrl(), repoUrlForOctane, Long.parseLong(myWorkspaceId), logConsumer::printLog); + + synchronized (BranchesBuildAction.class) { + long index = run.getActions(BranchesBuildAction.class).size(); + BranchesBuildAction buildAction = new BranchesBuildAction(run, result, fp.getRepoUrl(), fp.getFilter(), index); + run.addAction(buildAction); + } + + } catch (OctaneValidationException e) { + logConsumer.printLog("ALM Octane branch collector failed on validation : " + e.getMessage()); + run.setResult(Result.FAILURE); + } catch (OctaneBulkException e) { + //grouping error messages in format : "exception message (count) + String exceptions = e.getData().getErrors().stream().map(m -> m.getDescriptionTranslated()).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) + .entrySet().stream().map(entry -> entry.getKey() + "(" + entry.getValue() + ")") + .collect(Collectors.joining(System.lineSeparator() + " - ", " Exceptions are : " + System.lineSeparator() + " - ", "")); + logConsumer.printLog("ALM Octane branch collector failed : " + e.getMessage() + exceptions); + run.setResult(Result.FAILURE); + } catch (Exception e) { + logConsumer.printLog("ALM Octane branch collector failed : " + e.getMessage()); + e.printStackTrace(taskListener.getLogger()); + run.setResult(Result.FAILURE); + } + } + + @DataBoundSetter + public void setUseSSHFormat(boolean useSSHFormat) { + this.useSSHFormat = Boolean.toString(useSSHFormat); + } + + + public boolean getUseSSHFormat() { + return Boolean.parseBoolean(useSSHFormat); + } + + private BranchFetchParameters createFetchParameters(@Nonnull Run run, @Nonnull TaskListener taskListener, String myUseSshFormat, Consumer logConsumer) { + + BranchFetchParameters fp; + try { + EnvVars env = run.getEnvironment(taskListener); + fp = new BranchFetchParameters() + .setRepoUrl(env.expand(repositoryUrl)) + .setFilter(env.expand(filter)) + .setUseSSHFormat(Boolean.parseBoolean(env.expand(myUseSshFormat))); + } catch (IOException | InterruptedException e) { + taskListener.error("Failed loading build environment " + e); + fp = new BranchFetchParameters() + .setRepoUrl(repositoryUrl) + .setFilter(filter) + .setUseSSHFormat(Boolean.parseBoolean(myUseSshFormat)); + } + + ParametersAction parameterAction = run.getAction(ParametersAction.class); + if (parameterAction != null) { + fp.setPageSize(getIntegerValueParameter(parameterAction, "branches_page_size")); + fp.setActiveBranchDays(getIntegerValueParameter(parameterAction, "branches_active_branch_days")); + fp.setMaxBranchesToFill(getIntegerValueParameter(parameterAction, "branches_max_branches_to_fill")); + } + + logConsumer.accept("Repository URL : " + fp.getRepoUrl()); + logConsumer.accept("Filter : " + fp.getFilter()); + logConsumer.accept("Page size : " + fp.getPageSize()); + logConsumer.accept("Max branches to fill : " + fp.getMaxBranchesToFill()); + logConsumer.accept("Branch active days : " + fp.getActiveBranchDays()); + logConsumer.accept("Use ssh format : " + fp.isUseSSHFormat()); + + return fp; + } + + private Integer getIntegerValueParameter(ParametersAction parameterAction, String paramValue) { + ParameterValue pv = parameterAction.getParameter(paramValue); + if (pv != null && pv.getValue() instanceof String) { + try { + return Integer.valueOf((String) pv.getValue()); + } catch (Exception e) { + return null; + } + } + return null; + } + + public String getConfigurationId() { + return configurationId; + } + + public String getWorkspaceId() { + return workspaceId; + } + + private static class LogConsumer { + + private final PrintStream ps; + + public LogConsumer(PrintStream ps) { + this.ps = ps; + } + + public void printLog(String msg) { + ps.println("BranchPublisher : " + msg); + } + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } + + public String getCredentialsId() { + return credentialsId; + } + + public String getFilter() { + return filter; + } + + public String getScmTool() { + return scmTool; + } + + @Symbol("collectBranchesToAlmOctane") + @Extension // This indicates to Jenkins that this is an implementation of an extension point. + public static final class DescriptorImpl extends BuildStepDescriptor { + + static final CredentialsMatcher CREDENTIALS_MATCHER = CredentialsMatchers.anyOf(new CredentialsMatcher[]{ + CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class), + CredentialsMatchers.instanceOf(StringCredentials.class)}); + + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + + return JellyUtils.fillCredentialsIdItems(project, credentialsId, CREDENTIALS_MATCHER); + } + + public ListBoxModel doFillScmToolItems() { + ListBoxModel m = JellyUtils.createComboModelWithNoneValue(); + for (ScmTool tool : ScmTool.values()) { + m.add(tool.getDesc(), tool.getValue()); + } + + return m; + } + + public boolean isApplicable(Class aClass) { + return true; + } + + public ListBoxModel doFillConfigurationIdItems() { + return JellyUtils.fillConfigurationIdModel(); + } + + public ListBoxModel doFillWorkspaceIdItems(@QueryParameter String configurationId, @QueryParameter(value = "workspaceId") String workspaceId) { + return JellyUtils.fillWorkspaceModel(configurationId, workspaceId); + } + + public String getDisplayName() { + return "ALM Octane branch collector"; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction.java new file mode 100644 index 0000000000..3780997fd0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.model.Action; +import hudson.model.Item; +import hudson.model.Job; +import org.kohsuke.stapler.StaplerProxy; + +public class ConfigurationAction implements Action, StaplerProxy { + + final public Job owner; + final public JobConfigurationProxy proxy; + + public ConfigurationAction(Job job) { + this.owner = job; + this.proxy = new JobConfigurationProxy(job,null); + } + + @Override + public String getIconFileName() { + return owner.getACL().hasPermission(Item.CONFIGURE)? "setting.png": null; + } + + @Override + public String getDisplayName() { + return Messages.ConfigurationLabel(); + } + + @Override + public String getUrlName() { + return "mqmConfiguration"; + } + + @Override + public Object getTarget() { + owner.getACL().checkPermission(Item.CONFIGURE); + return this; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactory.java new file mode 100644 index 0000000000..9f74c7874c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactory.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import hudson.Extension; +import hudson.model.Action; +import hudson.model.Job; +import jenkins.model.TransientActionFactory; + +import javax.annotation.Nonnull; +import java.util.Collection; +import java.util.Collections; + +@Extension +public class ConfigurationActionFactory extends TransientActionFactory { + + @Override + public Class type() { + return Job.class; + } + + @Nonnull + @Override + public Collection createFor(@Nonnull Job job) { + // not sure if we need proper extensibility mechanism here: let's start small and extend if needed + if ("hudson.matrix.MatrixConfiguration".equals(job.getClass().getName())) { + return Collections.emptyList(); + } + return Collections.singleton(new ConfigurationAction(job)); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch.java new file mode 100644 index 0000000000..bf92a138e0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch.java @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.model.Action; +import hudson.model.Item; +import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; +import org.kohsuke.stapler.StaplerProxy; + +public class ConfigurationActionMultibranch implements Action, StaplerProxy { + + final public WorkflowMultiBranchProject owner; + final public JobConfigurationProxy proxy; + + public ConfigurationActionMultibranch(WorkflowMultiBranchProject job) { + this.owner = job; + this.proxy = new JobConfigurationProxy(null,job); + } + + @Override + public String getIconFileName() { + return owner.getACL().hasPermission(Item.CONFIGURE)? "setting.png": null; + } + + @Override + public String getDisplayName() { + return Messages.ConfigurationLabel(); + } + + @Override + public String getUrlName() { + return "mqmConfigurationMultibranch"; + } + + @Override + public Object getTarget() { + owner.getACL().checkPermission(Item.CONFIGURE); + + return this; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranchFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranchFactory.java new file mode 100644 index 0000000000..8a92b409eb --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranchFactory.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import hudson.Extension; +import hudson.model.Action; +import jenkins.model.TransientActionFactory; +import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; + +import javax.annotation.Nonnull; +import java.util.Collection; +import java.util.Collections; + +@Extension +public class ConfigurationActionMultibranchFactory extends TransientActionFactory { + + @Override + public Class type() { + return WorkflowMultiBranchProject.class; + } + + @Nonnull + @Override + public Collection createFor(@Nonnull WorkflowMultiBranchProject job) { + // not sure if we need proper extensibility mechanism here: let's start small and extend if needed + if ("hudson.matrix.MatrixConfiguration".equals(job.getClass().getName())) { + return Collections.emptyList(); + } + return Collections.singleton(new ConfigurationActionMultibranch(job)); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListener.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListener.java new file mode 100644 index 0000000000..a743cbc756 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListener.java @@ -0,0 +1,42 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import hudson.ExtensionPoint; + +public interface ConfigurationListener extends ExtensionPoint { + + void onChanged(OctaneServerSettingsModel newConf, OctaneServerSettingsModel oldConf); + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationService.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationService.java new file mode 100644 index 0000000000..d5d7d0da2d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationService.java @@ -0,0 +1,89 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.settings.OctaneServerSettingsGlobalConfiguration; +import hudson.Plugin; +import jenkins.model.Jenkins; + +import java.util.Arrays; +import java.util.List; + +/*** + * Octane plugin configuration service - + * 1. helps to change Octane configuration + * 2. helps to get Octane configuration and model + */ +public class ConfigurationService { + + /** + * provides all available configurations + * + * @return list of all available configurations + */ + public static List getAllSettings() { + return Arrays.asList(OctaneServerSettingsGlobalConfiguration.getInstance().getServers()); + } + + /** + * Get current {@see OctaneServerSettingsModel} model + * + * @return current configuration + */ + public static OctaneServerSettingsModel getSettings(String instanceId) { + return OctaneServerSettingsGlobalConfiguration.getInstance().getSettings(instanceId); + } + + /** + * Change model (used by tests) + * + * @param newModel new configuration + */ + public static void configurePlugin(OctaneServerSettingsModel newModel) { + OctaneServerSettingsGlobalConfiguration.getInstance().setModel(newModel); + } + + /** + * Get plugin version + * + * @return plugin version + */ + public static String getPluginVersion() { + Plugin plugin = Jenkins.getInstanceOrNull().getPlugin("hp-application-automation-tools-plugin"); + if(plugin == null){ + return "na"; + } + return plugin.getWrapper().getVersion(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationValidator.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationValidator.java new file mode 100644 index 0000000000..85c03e1b34 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationValidator.java @@ -0,0 +1,290 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.entities.Entity; +import com.hp.octane.integrations.exceptions.OctaneConnectivityException; +import com.hp.octane.integrations.services.configurationparameters.JobListCacheAllowedParameter; +import com.hp.octane.integrations.services.configurationparameters.UftTestRunnerFolderParameter; +import com.hp.octane.integrations.services.configurationparameters.factory.ConfigurationParameter; +import com.hp.octane.integrations.services.configurationparameters.factory.ConfigurationParameterFactory; +import com.hp.octane.integrations.utils.OctaneUrlParser; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.ImpersonationUtil; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.exceptions.AggregatedMessagesException; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.ProxyConfiguration; +import hudson.model.Item; +import hudson.model.Job; +import hudson.model.User; +import hudson.security.ACLContext; +import hudson.security.Permission; +import hudson.util.FormValidation; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +public class ConfigurationValidator { + private final static Logger logger = SDKBasedLoggerProvider.getLogger(ConfigurationValidator.class); + + + private ConfigurationValidator() { + //hiding public constructor + } + + + public static OctaneUrlParser parseUiLocation(String uiLocation) throws FormValidation { + try { + return OctaneUrlParser.parse(uiLocation); + } catch (IllegalArgumentException e) { + throw wrapWithFormValidation(false, e.getMessage()); + } + } + + /** + * Used by tests only + * + * @param location + * @param sharedSpace + * @param username + * @param password + * @return + */ + public static FormValidation checkConfigurationAndWrapWithFormValidation(String location, String sharedSpace, String username, Secret password) { + List errors = new ArrayList<>(); + checkConfiguration(errors, location, sharedSpace, username, password); + return wrapWithFormValidation(errors.isEmpty(), errors.isEmpty() ? Messages.ConnectionSuccess() : errors.get(0)); + } + + public static List checkConfiguration(List errorMessages, String location, String sharedSpace, String username, Secret password) { + + try { + return OctaneSDK.testOctaneConfigurationAndFetchAvailableWorkspaces(location, sharedSpace, username, password.getPlainText(), CIJenkinsServicesImpl.class); + } catch (OctaneConnectivityException octaneException) { + errorMessages.add(octaneException.getErrorMessageVal()); + } catch (IOException ioe) { + logger.warn("Connection check failed due to communication problem", ioe); + errorMessages.add(Messages.ConnectionFailure()); + } + return Collections.emptyList(); + } + + public static void checkImpersonatedUser(List errorMessages, String impersonatedUser) { + User jenkinsUser = null; + if (!StringUtils.isEmpty(impersonatedUser)) { + jenkinsUser = User.get(impersonatedUser, false, Collections.emptyMap()); + if (jenkinsUser == null) { + errorMessages.add(String.format(Messages.JenkinsUserMisconfiguredFailure(), impersonatedUser)); + return; + } + } + + ACLContext impersonatedContext = null; + try { + //start impersonation + impersonatedContext = ImpersonationUtil.startImpersonation(jenkinsUser); + + //test permissions + Map requiredPermissions = new HashMap<>(); + requiredPermissions.put(Item.BUILD, "Job.BUILD"); + requiredPermissions.put(Item.READ, "Job.READ"); + Jenkins jenkins = Jenkins.get(); + Set missingPermissions = requiredPermissions.keySet().stream().filter(p -> !jenkins.hasPermission(p)).map(p -> requiredPermissions.get(p)).collect(Collectors.toSet()); + if (!missingPermissions.isEmpty()) { + errorMessages.add(String.format(Messages.JenkinsUserPermissionsFailure(), jenkinsUser!= null ? jenkinsUser.getId() : impersonatedUser, StringUtils.join(missingPermissions, ", "))); + } + } catch (Exception e) { + errorMessages.add(String.format(Messages.JenkinsUserUnexpectedError(), impersonatedUser, e.getMessage())); + } finally { + //depersonate + ImpersonationUtil.stopImpersonation(impersonatedContext); + } + } + + private static Set getAvailableJobNames(List errorMessages, String impersonatedUser) { + User jenkinsUser = User.get(impersonatedUser, false, Collections.emptyMap()); + if (jenkinsUser == null) { + errorMessages.add(String.format(Messages.JenkinsUserMisconfiguredFailure(), impersonatedUser)); + return Collections.emptySet(); + } + + ACLContext impersonatedContext = null; + try { + //start impersonation + impersonatedContext = ImpersonationUtil.startImpersonation(jenkinsUser); + + //get job names + Collection jobNames = Jenkins.get().getJobNames(); + Set validJobNames = jobNames.stream().filter(jobName -> CIJenkinsServicesImpl.isJobIsRelevantForPipelineModule((Job) Jenkins.get().getItemByFullName(jobName))) + .collect(Collectors.toSet()); + if (validJobNames.isEmpty()) { + errorMessages.add(String.format("No job is available to the workspace Jenkins user '%s'", impersonatedUser)); + } + return validJobNames; + } catch (Exception e) { + errorMessages.add(String.format(Messages.JenkinsUserUnexpectedError(), impersonatedUser, e.getMessage())); + return Collections.emptySet(); + } finally { + //depersonate + ImpersonationUtil.stopImpersonation(impersonatedContext); + } + } + + public static FormValidation wrapWithFormValidation(boolean success, String message) { + String color = success ? "green" : "red"; + String msg = "" + message + ""; + if (success) { + return FormValidation.okWithMarkup(msg); + } else { + return FormValidation.errorWithMarkup(msg); + } + } + + public static void checkHoProxySettins(List errorMessages) { + ProxyConfiguration proxy = Jenkins.get().proxy; + boolean containsHttp = (proxy != null && proxy.getNoProxyHostPatterns().stream().anyMatch(p -> p.pattern().toLowerCase().startsWith("http"))); + if (containsHttp) { + errorMessages.add("In the HTTP Proxy Configuration area, the No Proxy Host field must contain a host name only. Remove the http:// prefix before the host name."); + } + } + + public static Map checkWorkspace2ImpersonatedUserConf(String workspace2ImpersonatedUserConf, List availableWorkspaces, String impersonatedUser, List errorMessages) { + Map workspace2ImpersonatedUser = Collections.emptyMap(); + if (workspace2ImpersonatedUserConf == null || workspace2ImpersonatedUserConf.trim().isEmpty()) { + return workspace2ImpersonatedUser; + } + + //collect parse errors + try { + OctaneServerSettingsModel.parseWorkspace2ImpersonatedUserConf(workspace2ImpersonatedUserConf, false); + } catch (AggregatedMessagesException e) { + errorMessages.addAll(e.getMessages()); + } + + if (!availableWorkspaces.isEmpty()) { + workspace2ImpersonatedUser = OctaneServerSettingsModel.parseWorkspace2ImpersonatedUserConf(workspace2ImpersonatedUserConf, true); + + //try to find non-accessible workspaces + Set accessibleWorkspaceIds = availableWorkspaces.stream().map(Entity::getId).map(id -> Long.parseLong(id)).collect(Collectors.toSet()); + List notAccessibleWorkspaceIds = workspace2ImpersonatedUser.keySet().stream().filter(workspaceId -> !accessibleWorkspaceIds.contains(workspaceId)).collect(Collectors.toList()); + if (!notAccessibleWorkspaceIds.isEmpty()) { + errorMessages.add("Workspace configuration contains non-accessible ALM Octane workspaces: " + notAccessibleWorkspaceIds); + } + + List tempErrorListForGeneralImpersonatedUser = new ArrayList<>(); + + //get available jobs for general jenkins user for comparison with jobs of workspace jenkins user + Set availableJobsForGeneralJenkinsUser = getAvailableJobNames(tempErrorListForGeneralImpersonatedUser, impersonatedUser); + + //validate that workspace impersonated uses has access to subset of jobs available to general impersonated user + Set userNames = workspace2ImpersonatedUser.values().stream().collect(Collectors.toSet()); + userNames.forEach(user -> { + Set availableJobs = getAvailableJobNames(errorMessages, user); + if (!availableJobs.isEmpty()) { + Set unavailableJobsByGeneralImpersonatedUser = availableJobs.stream() + .filter(jobName -> !availableJobsForGeneralJenkinsUser.contains(jobName)).collect(Collectors.toSet()); + if (!unavailableJobsByGeneralImpersonatedUser.isEmpty()) { + errorMessages.add(String.format("There are jobs that are not accessible by '%s', but are accessible by the workspace jenkins user '%s', for example %s ", + impersonatedUser, user, + unavailableJobsByGeneralImpersonatedUser.stream().limit(3).collect(Collectors.toSet()))); + } + } + }); + } + return workspace2ImpersonatedUser; + } + + public static void checkParameters(String parameters, String impersonatedUser, Map workspace2ImpersonatedUser, List fails) { + Map params = OctaneServerSettingsModel.parseParameters(parameters); + params.entrySet().forEach(entry -> { + try { + ConfigurationParameter parameter = ConfigurationParameterFactory.tryCreate(entry.getKey(), entry.getValue()); + + if (parameter.getKey().equals(UftTestRunnerFolderParameter.KEY)) { + checkUftFolderParameterWithImpersonation((UftTestRunnerFolderParameter) parameter, impersonatedUser, fails); + } + if (parameter.getKey().equals(JobListCacheAllowedParameter.KEY) && ((JobListCacheAllowedParameter) parameter).isAllowed() && + !workspace2ImpersonatedUser.isEmpty()) { + fails.add(JobListCacheAllowedParameter.KEY + " - is not compatible with defining 'Jenkins user for specific workspaces'"); + } + } catch (NoSuchElementException e1) { + String failMessage = e1.getMessage() + ". Validate that you use correct format : : "; + fails.add(failMessage); + } catch (Exception ex) { + fails.add(ex.getMessage()); + } + }); + } + + private static void checkUftFolderParameterWithImpersonation(UftTestRunnerFolderParameter param, String impersonatedUser, List fails) { + User jenkinsUser = null; + if (!StringUtils.isEmpty(impersonatedUser)) { + jenkinsUser = User.get(impersonatedUser, false, Collections.emptyMap()); + if (jenkinsUser == null) { + //user exception will be thrown earlier + return; + } + } + + ACLContext acl = ImpersonationUtil.startImpersonation(jenkinsUser); + try { + checkUftFolderParameter(param, fails); + } catch (Exception e) { + fails.add(UftTestRunnerFolderParameter.KEY + " - Failed to check parameter : " + e.getMessage()); + } finally { + ImpersonationUtil.stopImpersonation(acl); + } + } + + public static void checkUftFolderParameter(UftTestRunnerFolderParameter param, List fails) { + String folder = param.getFolder(); + Item item = Jenkins.get().getItemByFullName(folder); + if (item == null) { + String msg = UftTestRunnerFolderParameter.KEY + " : folder '" + folder + "' is not found. Validate that folder exist and jenkins user has READ permission on the folder."; + if (folder.contains("/job/")) { + msg += " Replace '/job/' by '/'."; + } + fails.add(msg); + } else if (!JobProcessorFactory.isFolder(item)) { + fails.add(UftTestRunnerFolderParameter.KEY + " : '" + folder + "' is not a folder."); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/FodConfigUtil.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/FodConfigUtil.java new file mode 100644 index 0000000000..cce6fe2bfd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/FodConfigUtil.java @@ -0,0 +1,281 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Descriptor; +import hudson.security.ACL; +import hudson.tasks.Publisher; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.StringUtils; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.IOException; +import java.util.Map; + +import static com.microfocus.application.automation.tools.octane.configuration.ReflectionUtils.getFieldValue; + +/*** + * A utility class to help retrieving the configuration of the FOD + * in Jenkins: URL, connection params, releaseId etc. + */ +public class FodConfigUtil { + private final static Logger logger = SDKBasedLoggerProvider.getLogger(FodConfigUtil.class); + + public final static String FOD_DESCRIPTOR = "org.jenkinsci.plugins.fodupload.FodGlobalDescriptor"; + public final static String FOD_STATIC_ASSESSMENT_STEP = "org.jenkinsci.plugins.fodupload.StaticAssessmentBuildStep"; + + public static class ServerConnectConfig { + public String baseUrl; + public String apiUrl; + public String clientId; + public String clientSecret; + + } + + public static ServerConnectConfig getFODServerConfig() { + Descriptor fodDescriptor = getFODDescriptor(); + ServerConnectConfig serverConnectConfig = null; + if (fodDescriptor != null) { + serverConnectConfig = new ServerConnectConfig(); + serverConnectConfig.apiUrl = getFieldValue(fodDescriptor, "apiUrl"); + serverConnectConfig.baseUrl = getFieldValue(fodDescriptor, "baseUrl"); + serverConnectConfig.clientId = getFieldValue(fodDescriptor, "clientId"); + serverConnectConfig.clientSecret = retrieveSecretDecryptedValue(getFieldValue(fodDescriptor, "clientSecret")); + } + return serverConnectConfig; + } + + private static Descriptor getFODDescriptor() { + return Jenkins.getInstanceOrNull().getDescriptorByName(FOD_DESCRIPTOR); + + } + + public static Long getFODReleaseFromBuild(AbstractBuild build) { + return build != null ? getRelease(build.getProject()) : null; + } + + public static Long getFODReleaseFromRun(WorkflowRun run) { + // to understand what does it mean for pipeline run + logger.debug("implement get release for " + run ); + return null; + } + + private static Long getRelease(AbstractProject project) { + // BSI Token is being deprecated, try to get releaseId directly first then fallback to BSI Token parsing + Long release = getReleaseId(project); + if (release != null) { + return release; + } else { + logger.debug("Falling back to retrieving release from BSI Token"); + } + + release = getReleaseVersionBefore12(project); + if(release != null){ + logger.debug("A Version before 12 is detected."); + return release; + } + + release = getReleaseVersion12(project); + if(release != null) { + logger.debug("A Version 12 or higher is detected."); + } + logger.debug("No release was set to this job"); + return release; + } + + private static Long getReleaseId(AbstractProject project){ + for (Object publisher : project.getPublishersList()) { + if (publisher instanceof Publisher && + FOD_STATIC_ASSESSMENT_STEP.equals(publisher.getClass().getName())) { + Object sharedBuildStep = getFieldValue(publisher, "sharedBuildStep"); + if (sharedBuildStep != null) { + logger.debug(sharedBuildStep.toString()); + return getReleaseIdByReflection(sharedBuildStep); + } else { + return getReleaseIdByReflection(publisher); + } + } + } + return null; + } + private static Long getReleaseIdByReflection(Object fodPublisher) { + + Object modelObj = getFieldValue(fodPublisher, "model"); + if (modelObj == null) { + return null; + } + String releaseId = getFieldValue(modelObj, "releaseId"); + if (releaseId != null) { + return Long.valueOf(releaseId); + } else { + logger.debug("Unable to find releaseId directly"); + return null; + } + } + + private static Long getReleaseVersion12(AbstractProject project){ + for (Object publisher : project.getPublishersList()) { + if (publisher instanceof Publisher && + FOD_STATIC_ASSESSMENT_STEP.equals(publisher.getClass().getName())) { + return getReleaseByReflectionV12(publisher); + } + } + return null; + } + private static Long getReleaseVersionBefore12(AbstractProject project){ + for (Object publisher : project.getPublishersList()) { + if (publisher instanceof Publisher && + FOD_STATIC_ASSESSMENT_STEP.equals(publisher.getClass().getName())) { + return getReleaseByReflection(publisher); + } + } + return null; + } + private static Long getReleaseByReflectionV12(Object fodPublisher) { + + Object sharedBuildStep = getFieldValue(fodPublisher, "sharedBuildStep"); + if(sharedBuildStep == null){ + return null; + } + return getReleaseByReflection(sharedBuildStep); + } + private static Long getReleaseByReflection(Object fodPublisher) { + + Object modelObj = getFieldValue(fodPublisher, "model"); + if (modelObj == null) { + return null; + } + String bsiToken = getFieldValue(modelObj, "bsiTokenOriginal"); + return parseBSITokenAndGetReleaseId(bsiToken); + } + + private static Long parseBSITokenAndGetReleaseId(String bsiToken) { + try { + return handleURLFormat(bsiToken); + } catch (Exception e) { + return handleBase64Format(bsiToken); + } + } + + private static Long handleBase64Format(String bsiToken) { + + String bsi64 = StringUtils.newStringUtf8(Base64.decodeBase64(bsiToken)); + try { + Map bsiJsonAsMap = new ObjectMapper().readValue(bsi64, + TypeFactory.defaultInstance().constructType(Map.class)); + return Long.valueOf(bsiJsonAsMap.get("releaseId").toString()); + + } catch (IOException e) { + logger.error("failed to read the BSI token base64:" + e.getMessage()); + return null; + } + + } + + private static Long handleURLFormat(String bsiToken) { + //https://api.sandbox.fortify.com/bsi2.aspx?tid=159&tc=Octane&pv=3059&payloadType=ANALYSIS_PAYLOAD&astid=25&ts=JS%2fXML%2fHTML + if (bsiToken == null) { + return null; + } + + int pvIndex = bsiToken.indexOf("pv"); + String releaseString = bsiToken.substring(bsiToken.indexOf('=', pvIndex) + 1, bsiToken.indexOf('&', pvIndex)); + return Long.valueOf(releaseString); + } + + // + + public static String decrypt(String stringToDecrypt) { + Secret decryptedSecret = Secret.decrypt(stringToDecrypt); + return decryptedSecret != null ? decryptedSecret.getPlainText() : stringToDecrypt; + } + + public static String decrypt(Secret stringToDecrypt) { + return stringToDecrypt.getPlainText(); + } + + public static String encrypt(String stringToEncrypt) { + String result = stringToEncrypt; + if(Secret.decrypt(stringToEncrypt) == null){ + result = Secret.fromString(stringToEncrypt).getEncryptedValue(); + } + return result; + } + + public static boolean isEncrypted(String stringToEncrypt) { + return (Secret.decrypt(stringToEncrypt) != null); + } + + public static boolean isCredential(String id) { + StringCredentials s = CredentialsMatchers.firstOrNull( + CredentialsProvider.lookupCredentials( + StringCredentials.class, + Jenkins.get(), + ACL.SYSTEM, + null, + null + ), + CredentialsMatchers.allOf( + CredentialsMatchers.withId(id) + ) + ); + return (s != null); + } + + public static String retrieveSecretDecryptedValue(String id) { + StringCredentials s = CredentialsMatchers.firstOrNull( + CredentialsProvider.lookupCredentials( + StringCredentials.class, + Jenkins.get(), + ACL.SYSTEM, + null, + null + ), + CredentialsMatchers.allOf( + CredentialsMatchers.withId(id) + ) + ); + return s != null ? decrypt(s.getSecret()) : id; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/JobConfigurationProxy.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/JobConfigurationProxy.java new file mode 100644 index 0000000000..4ebaa7dedf --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/JobConfigurationProxy.java @@ -0,0 +1,1134 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.entities.Entity; +import com.hp.octane.integrations.dto.entities.EntityConstants; +import com.hp.octane.integrations.dto.entities.ResponseEntityList; +import com.hp.octane.integrations.dto.general.CIServerInfo; +import com.hp.octane.integrations.dto.general.ListItem; +import com.hp.octane.integrations.dto.general.Taxonomy; +import com.hp.octane.integrations.dto.pipelines.PipelineContext; +import com.hp.octane.integrations.dto.pipelines.PipelineContextList; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.services.entities.EntitiesService; +import com.hp.octane.integrations.services.entities.QueryHelper; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.model.Job; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; +import org.kohsuke.stapler.bind.JavaScriptMethod; + +import java.util.*; +import java.util.Map.Entry; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * This class is a proxy between JS UI code and server-side job configuration. + */ +public class JobConfigurationProxy { + private final static Logger logger = SDKBasedLoggerProvider.getLogger(JobConfigurationProxy.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + private static final String MILESTONE_ID_FIELD = "milestoneId"; + private static final String RELEASE_ID_FIELD = "releaseId"; + private static final String WORKSPACE_ID_FIELD = "workspaceId"; + private static final String NAME_FIELD = "name"; + public static final String INSTANCE_ID_FIELD = "instanceId"; + public static final String ID_FIELD = "id"; + public static final String TEXT_FIELD = "text"; + private static final String IGNORE_TESTS = "ignoreTests"; + private static final String FIELDS = "fields"; + private static final String TAXONOMY_TAGS = "taxonomyTags"; + private static final String FIELD_CREATE_MESSAGE = "Failed to create pipeline"; + + final private Job job; + final private WorkflowMultiBranchProject multibranch; + + private static final String NOT_SPECIFIED = "-- Not specified --"; + + JobConfigurationProxy(Job job,WorkflowMultiBranchProject multiBranchProject) { + this.job = job; + this.multibranch = multiBranchProject; + } + + + @JavaScriptMethod + public JSONObject createPipelineOnServer(JSONObject pipelineObject) { + JSONObject result = new JSONObject(); + + if(multibranch != null){ + return createMultiBranchOnServer(pipelineObject); + } + + PipelineNode pipelineNode = ModelFactory.createStructureItem(job); + String instanceId = pipelineObject.getString(INSTANCE_ID_FIELD); + CIServerInfo ciServerInfo = CIJenkinsServicesImpl.getJenkinsServerInfo(); + ciServerInfo.setInstanceId(instanceId); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + try { + + + PipelineContext pipelineContext = dtoFactory.newDTO(PipelineContext.class) + .setContextName(pipelineObject.getString(NAME_FIELD)) + .setWorkspace(pipelineObject.getLong(WORKSPACE_ID_FIELD)) + .setReleaseId(pipelineObject.getLong(RELEASE_ID_FIELD)) + .setMilestoneId(pipelineObject.getLong(MILESTONE_ID_FIELD)) + .setStructure(pipelineNode) + .setServer(ciServerInfo); + PipelineContext createdPipelineContext = octaneClient.getPipelineContextService().createPipeline(octaneClient.getInstanceId(), pipelineNode.getJobCiId(), pipelineContext); + + //update cache that new pipeline root is added + octaneClient.getConfigurationService().addToOctaneRootsCache(pipelineNode.getJobCiId()); + + //WORKAROUND BEGIN + //getting workspaceName - because the workspaceName is not returned from configuration API + Entity workspace = getWorkspace(octaneClient, pipelineContext.getWorkspaceId()); + //WORKAROUND END + + JSONObject pipelineJSON = fromPipeline(createdPipelineContext, workspace); + enrichPipelineInstanceId(pipelineJSON, instanceId); + + //WORKAROUND BEGIN + //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API + enrichPipelineInternal(pipelineJSON, octaneClient); + //WORKAROUND END + result.put("pipeline", pipelineJSON); + + JSONArray fieldsMetadata = convertToJsonMetadata(getPipelineListNodeFieldsMetadata(octaneClient, createdPipelineContext.getWorkspaceId())); + result.put("fieldsMetadata", fieldsMetadata); + + } catch (ClientException e) { + logger.warn(FIELD_CREATE_MESSAGE, e); + return error(e.getMessage(), e.getLink()); + } catch (Exception e) { + logger.warn(FIELD_CREATE_MESSAGE, e); + return error(e.getMessage()); + } + return result; + } + + private Entity getWorkspace(OctaneClient octaneClient, Long workspaceId) throws ClientException { + List workspaces = getWorkspacesById(octaneClient, Collections.singletonList(workspaceId)); + if (workspaces.size() != 1) { + throw new ClientException("WorkspaceName could not be retrieved for workspaceId: " + workspaceId); + } + return workspaces.get(0); + } + + public JSONObject createMultiBranchOnServer(JSONObject pipelineObject) { + + + JSONObject result = new JSONObject(); + + try { + String ciId = multibranch.getFullName(); + String name = pipelineObject.getString(NAME_FIELD); + Long workspaceId = pipelineObject.getLong(WORKSPACE_ID_FIELD); + long releaseId = pipelineObject.getLong(RELEASE_ID_FIELD); + long milestoneId = pipelineObject.getLong(MILESTONE_ID_FIELD); + String instanceId = pipelineObject.getString(INSTANCE_ID_FIELD); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + + String condition = QueryHelper.condition(EntityConstants.CIServer.INSTANCE_ID_FIELD, instanceId); + ResponseEntityList response = queryEntitiesByName(octaneClient, null, Collections.singletonList(condition), workspaceId, "ci_servers", 1); + + if (response != null && response.getTotalCount() == 0 && response.getData() != null) { + throw new ClientException(String.format("CI Server not exist on Octane please create it on workspace %s, Instance ID %s.", workspaceId, instanceId)); + } + + Entity CIServer = response.getData().get(0); + Entity release = releaseId > 0 ? dtoFactory.newDTO(Entity.class).setType(EntityConstants.Release.ENTITY_NAME).setId(Long.toString(releaseId)) : null; + Entity milestone = milestoneId > 0 ? dtoFactory.newDTO(Entity.class).setType(EntityConstants.Milestone.ENTITY_NAME).setId(Long.toString(milestoneId)) : null; + + Entity pipeline = dtoFactory.newDTO(Entity.class) + .setField(EntityConstants.Pipeline.CI_SERVER, CIServer) + .setField(EntityConstants.Pipeline.NAME_FIELD, name) + .setField(EntityConstants.Pipeline.ROOT_JOB_NAME, ciId); + if (release != null) { + pipeline.setField(EntityConstants.Pipeline.CURRENT_RELEASE, release); + } + if (milestone != null) { + pipeline.setField(EntityConstants.Pipeline.CURRENT_MILESTONE, milestone); + } + + EntitiesService entitiesService = octaneClient.getEntitiesService(); + List results = entitiesService.postEntities(workspaceId, EntityConstants.Pipeline.COLLECTION_NAME, Collections.singletonList(pipeline), + Stream.of(EntityConstants.Pipeline.NAME_FIELD, EntityConstants.Pipeline.CURRENT_RELEASE, EntityConstants.Pipeline.CURRENT_MILESTONE) + .collect(Collectors.toList())); + + if (results.size() != 1) { + throw new ClientException(FIELD_CREATE_MESSAGE); + } + + Entity workspace = getWorkspace(octaneClient,workspaceId); + + Entity pipelineCreated = results.get(0); + + JSONObject pipelineJSON = new JSONObject(); + pipelineJSON.put(ID_FIELD, pipelineCreated.getId()); + pipelineJSON.put(NAME_FIELD, pipelineCreated.getStringValue(EntityConstants.Pipeline.NAME_FIELD)); + pipelineJSON.put(RELEASE_ID_FIELD, getReferenceFieldId(EntityConstants.Pipeline.CURRENT_RELEASE,pipelineCreated)); + pipelineJSON.put(MILESTONE_ID_FIELD, getReferenceFieldId(EntityConstants.Pipeline.CURRENT_MILESTONE,pipelineCreated)); + pipelineJSON.put("isRoot", true); + pipelineJSON.put(WORKSPACE_ID_FIELD, workspaceId); + pipelineJSON.put("workspaceName", workspace.getName()); + pipelineJSON.put(IGNORE_TESTS, false); + pipelineJSON.put(FIELDS, new JSONObject()); + pipelineJSON.put(TAXONOMY_TAGS, new JSONArray()); + + + enrichPipelineInstanceId(pipelineJSON, instanceId); + //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API + enrichPipelineInternal(pipelineJSON,octaneClient); + result.put("pipeline", pipelineJSON); + + JSONArray fieldsMetadata = convertToJsonMetadata(getPipelineListNodeFieldsMetadata(octaneClient, workspaceId)); + result.put("fieldsMetadata", fieldsMetadata); + } catch (ClientException e) { + logger.warn(FIELD_CREATE_MESSAGE, e); + return error(e.getMessage(), e.getLink()); + } catch (Exception e) { + logger.warn(FIELD_CREATE_MESSAGE, e); + return error(e.getMessage()); + } + return result; + } + + private Object getReferenceFieldId(String fieldName,Entity entity){ + return entity.getEntityValue(fieldName) != null ? entity.getEntityValue(fieldName).getId() : -1; + } + + @JavaScriptMethod + public JSONObject updatePipelineOnSever(JSONObject pipelineObject) { + JSONObject result = new JSONObject(); + + String instanceId = pipelineObject.getString(INSTANCE_ID_FIELD); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + try { + long pipelineId = pipelineObject.getLong(ID_FIELD); + + //build taxonomies + LinkedList taxonomies = new LinkedList<>(); + JSONArray taxonomyTags = pipelineObject.getJSONArray(TAXONOMY_TAGS); + for (JSONObject jsonObject : toCollection(taxonomyTags)) { + taxonomies.add(dtoFactory.newDTO(Taxonomy.class) + .setId(jsonObject.optLong("tagId")) + .setName(jsonObject.getString("tagName")) + .setParent(dtoFactory.newDTO(Taxonomy.class) + .setId(jsonObject.optLong("tagTypeId")) + .setName(jsonObject.getString("tagTypeName"))) + ); + } + + //build list fields + Map> fields = new HashMap<>(); + JSONArray fieldTags = pipelineObject.getJSONArray("fieldTags"); + for (JSONObject jsonObject : toCollection(fieldTags)) { + List assignedValues = new LinkedList<>(); + for (JSONObject value : toCollection(jsonObject.getJSONArray("values"))) { + String id; + if (value.containsKey(ID_FIELD)) { + id = value.getString(ID_FIELD); + } else { + id = null; + } + assignedValues.add(dtoFactory.newDTO(ListItem.class).setId(id).setName(value.getString(NAME_FIELD))); + } + fields.put(jsonObject.getString(NAME_FIELD), assignedValues); + } + + final String jobCiId = job != null ? JobProcessorFactory.getFlowProcessor(job).getTranslatedJobName() : + multibranch.getFullName(); + + PipelineContext pipelineContext = dtoFactory.newDTO(PipelineContext.class) + .setContextEntityId(pipelineId) + .setContextName(pipelineObject.getString(NAME_FIELD)) + .setWorkspace(pipelineObject.getLong(WORKSPACE_ID_FIELD)) + .setReleaseId(pipelineObject.getLong(RELEASE_ID_FIELD)) + .setMilestoneId(pipelineObject.getLong(MILESTONE_ID_FIELD)) + .setIgnoreTests(pipelineObject.getBoolean(IGNORE_TESTS)) + .setTaxonomies(taxonomies) + .setListFields(fields); + + PipelineContext pipeline = octaneClient.getPipelineContextService().updatePipeline(octaneClient.getInstanceId(), jobCiId, pipelineContext); + + //WORKAROUND BEGIN + //getting workspaceName - because the workspaceName is not returned from configuration API + Entity workspace = getWorkspace(octaneClient, pipeline.getWorkspaceId()); + //WORKAROUND END + + //TODO uncomment after getting pipelineContext + JSONObject pipelineJSON = fromPipeline(pipeline, workspace); + enrichPipelineInstanceId(pipelineJSON, instanceId); + + //WORKAROUND BEGIN + //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API + enrichPipelineInternal(pipelineJSON, octaneClient); + //WORKAROUND END + result.put("pipeline", pipelineJSON); + + + //Server might do partial sucess + //So need to validate each item if it succedded or not + //For now we add handling of duplicate pipeline name + String originalName = pipelineObject.get(NAME_FIELD).toString(); + String updatedName = pipelineJSON.get(NAME_FIELD).toString(); + if (!originalName.equalsIgnoreCase(updatedName)) { + JSONObject errorObj = new JSONObject(); + errorObj.put("message", "Failed to update pipeline name. Make sure not to enter the name of an existing pipeline."); + result.put("error", errorObj); + } + } catch (ClientException e) { + logger.warn("Failed to update pipeline", e); + return error(e.getMessage(), e.getLink()); + } catch (Exception e) { + logger.warn("Failed to update pipeline", e); + return error("Unable to update pipeline"); + } + + return result; + } + + @JavaScriptMethod + public JSONObject deleteTests(JSONObject pipelineObject) { + JSONObject result = new JSONObject(); + String instanceId = pipelineObject.getString(INSTANCE_ID_FIELD); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + try { + long pipelineId = pipelineObject.getLong(ID_FIELD); + long workspaceId = pipelineObject.getLong(WORKSPACE_ID_FIELD); + octaneClient.getPipelineContextService().deleteTestsFromPipelineNodes(job.getName(), pipelineId, workspaceId); + result.put("Test deletion was successful", ""); + } catch (Exception e) { + logger.warn("Failed to delete tests", e); + return error("Unable to delete tests"); + } + + return result; + } + + @JavaScriptMethod + public JSONObject loadJobConfigurationFromServer(String instanceId) { + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + JSONObject ret = new JSONObject(); + JSONObject workspaces = new JSONObject(); + JSONArray fieldsMetadata = new JSONArray(); + try { + final String jobCiId = job != null ? JobProcessorFactory.getFlowProcessor(job).getTranslatedJobName() + : multibranch.getFullName(); + PipelineContextList pipelineContextList = octaneClient.getPipelineContextService().getJobConfiguration(octaneClient.getInstanceId(), jobCiId); + + if (!pipelineContextList.getData().isEmpty()) { + Map> workspacesMap = pipelineContextList.buildWorkspace2PipelinesMap(); + //WORKAROUND BEGIN + //getting workspaceName - because the workspaceName is not returned from configuration API + Map relatedWorkspaces = new HashMap<>(); + List workspaceList = getWorkspacesById(octaneClient, workspacesMap.keySet()); + for (Entity workspace : workspaceList) { + relatedWorkspaces.put(Long.parseLong(workspace.getId()), workspace.getName()); + } + //WORKAROUND END + + Map> sortedWorkspacesMap = new TreeMap<>(Comparator.comparing(Entity::getName)); + Comparator pipelineComparator = Comparator.comparing(PipelineContext::getContextEntityName); + + //create workspaces JSON Object + for (Entry> workspacePipelines : workspacesMap.entrySet()) { + Entity relatedWorkspace = dtoFactory.newDTO(Entity.class); + + relatedWorkspace.setId(workspacePipelines.getKey().toString()); + relatedWorkspace.setName(relatedWorkspaces.get(workspacePipelines.getKey())); + + JSONObject relatedPipelinesJSON = new JSONObject(); + + for (PipelineContext relatedPipeline : workspacePipelines.getValue()) { + JSONObject pipelineJSON = fromPipeline(relatedPipeline, relatedWorkspace); + enrichPipelineInstanceId(pipelineJSON, instanceId); + relatedPipelinesJSON.put(String.valueOf(relatedPipeline.getContextEntityId()), pipelineJSON); + } + JSONObject workspaceJSON = new JSONObject(); + workspaceJSON.put(ID_FIELD, relatedWorkspace.getId()); + workspaceJSON.put(NAME_FIELD, relatedWorkspace.getName()); + workspaceJSON.put("pipelines", relatedPipelinesJSON); + workspaces.put(String.valueOf(relatedWorkspace.getId()), workspaceJSON); + + //inserting this workspace into sortedMap (sorted by workspaceName and by pipelineName, so that we can pick first workspace and its first pipeline as preselected values + LinkedList workspacePipelinesList = new LinkedList<>(workspacePipelines.getValue()); + workspacePipelinesList.sort(pipelineComparator); + sortedWorkspacesMap.put(relatedWorkspace, workspacePipelinesList); + } + + //create currentPipeline JSON Object + //currently the first pipeline in the first workspace is picked + Entity preSelectedWorkspace = sortedWorkspacesMap.keySet().iterator().next(); + PipelineContext preSelectedPipeline = sortedWorkspacesMap.get(preSelectedWorkspace).get(0); + JSONObject preSelectedPipelineJSON = fromPipeline(preSelectedPipeline, preSelectedWorkspace); + enrichPipelineInstanceId(preSelectedPipelineJSON, instanceId); + //WORKAROUND BEGIN + //all metadata have to be loaded in separate REST calls for this pipeline: releaseName, taxonomyNames and listFieldNames are not returned from configuration API + enrichPipelineInternal(preSelectedPipelineJSON, octaneClient); + //WORKAROUND END + ret.put("currentPipeline", preSelectedPipelineJSON); + + //retrieving metadata fields for preselected workspace + fieldsMetadata = convertToJsonMetadata(getPipelineListNodeFieldsMetadata(octaneClient, Long.parseLong(preSelectedWorkspace.getId()))); + } + + ret.put("workspaces", workspaces); + ret.put("fieldsMetadata", fieldsMetadata); + + } catch (Exception e) { + logger.warn("Failed to retrieve job configuration", e); + return error("Unable to retrieve job configuration"); + } + + return ret; + } + + @JavaScriptMethod + public JSONObject loadWorkspaceConfiguration(JSONObject pipelineJSON) { + String instanceId = pipelineJSON.getString(INSTANCE_ID_FIELD); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + JSONObject ret = new JSONObject(); + + try { + JSONArray fieldsMetadata = convertToJsonMetadata(getPipelineListNodeFieldsMetadata(octaneClient, pipelineJSON.getLong(WORKSPACE_ID_FIELD))); + ret.put("fieldsMetadata", fieldsMetadata); + enrichPipelineInternal(pipelineJSON, octaneClient); + ret.put("pipeline", pipelineJSON); + } catch (Exception e) { + logger.warn("Failed to retrieve metadata for workspace", e); + return error("Unable to retrieve metadata for workspace"); + } + + return ret; + } + + private static JSONObject fromPipeline(final PipelineContext pipeline, Entity relatedWorkspace) { + JSONObject pipelineJSON = new JSONObject(); + pipelineJSON.put(ID_FIELD, pipeline.getContextEntityId()); + pipelineJSON.put(NAME_FIELD, pipeline.getContextEntityName()); + pipelineJSON.put(RELEASE_ID_FIELD, pipeline.getReleaseId() != null ? pipeline.getReleaseId() : -1); + pipelineJSON.put(MILESTONE_ID_FIELD, pipeline.getMilestoneId() != null ? pipeline.getMilestoneId() : -1); + pipelineJSON.put("isRoot", pipeline.isPipelineRoot()); + pipelineJSON.put(WORKSPACE_ID_FIELD, relatedWorkspace.getId()); + pipelineJSON.put("workspaceName", relatedWorkspace.getName()); + pipelineJSON.put(IGNORE_TESTS, pipeline.getIgnoreTests()); + addTaxonomyTags(pipelineJSON, pipeline); + addFields(pipelineJSON, pipeline); + + return pipelineJSON; + } + + @JavaScriptMethod + public JSONObject enrichPipeline(JSONObject pipelineJSON) { + String instanceId = pipelineJSON.getString(INSTANCE_ID_FIELD); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + JSONObject ret = new JSONObject(); + try { + enrichPipelineInternal(pipelineJSON, octaneClient); + ret.put("pipeline", pipelineJSON); + } catch (Exception e) { + logger.warn("Failed to retrieve metadata for pipeline", e); + return error("Unable to retrieve metadata for pipeline"); + } + + return ret; + } + + private static void enrichPipelineInternal(JSONObject pipelineJSON, OctaneClient octaneClient) { + enrichRelease(pipelineJSON, octaneClient); + enrichMilestone(pipelineJSON, octaneClient); + enrichTaxonomies(pipelineJSON, octaneClient); + enrichFields(pipelineJSON, octaneClient); + } + + private static void enrichPipelineInstanceId(JSONObject pipelineJSON, String instanceId) { + pipelineJSON.put(INSTANCE_ID_FIELD, instanceId); + pipelineJSON.put("instanceCaption", ConfigurationService.getSettings(instanceId).getCaption()); + } + + private static void enrichRelease(JSONObject pipeline, OctaneClient octaneClient) { + long workspaceId = pipeline.getLong(WORKSPACE_ID_FIELD); + if (pipeline.containsKey(RELEASE_ID_FIELD) && pipeline.getLong(RELEASE_ID_FIELD) != -1) { + long releaseId = pipeline.getLong(RELEASE_ID_FIELD); + String releaseName = getReleasesById(octaneClient, Collections.singletonList(releaseId), workspaceId).get(0).getName(); + pipeline.put("releaseName", releaseName); + } + } + + private static void enrichMilestone(JSONObject pipeline, OctaneClient octaneClient) { + long workspaceId = pipeline.getLong(WORKSPACE_ID_FIELD); + if (pipeline.containsKey(MILESTONE_ID_FIELD) && pipeline.getLong(MILESTONE_ID_FIELD) != -1) { + long milestoneId = pipeline.getLong(MILESTONE_ID_FIELD); + String milestoneName = getMilestonesById(octaneClient, Arrays.asList(milestoneId), workspaceId).get(0).getName(); + pipeline.put("milestoneName", milestoneName); + } + } + + private static void enrichTaxonomies(JSONObject pipeline, OctaneClient octaneClient) { + JSONArray ret = new JSONArray(); + if (pipeline.has(TAXONOMY_TAGS)) { + + JSONArray taxonomyTags = pipeline.getJSONArray(TAXONOMY_TAGS); + List taxonomyIdsList = new LinkedList<>(); + for (int i = 0; i < taxonomyTags.size(); i++) { + JSONObject taxonomy = taxonomyTags.getJSONObject(i); + if (taxonomy.has("tagId")) { + taxonomyIdsList.add(taxonomy.getLong("tagId")); + } + } + List taxonomies = convertTaxonomies(getTaxonomiesById(octaneClient, taxonomyIdsList, pipeline.getLong(WORKSPACE_ID_FIELD))); + for (Taxonomy tax : taxonomies) { + ret.add(tag(tax)); + } + } + pipeline.put(TAXONOMY_TAGS, ret); + } + + private static void enrichFields(JSONObject pipeline, OctaneClient client) { + JSONObject ret = new JSONObject(); + + if (pipeline.has(FIELDS)) { + long workspaceId = pipeline.getLong(WORKSPACE_ID_FIELD); + JSONObject pipelineFields = pipeline.getJSONObject(FIELDS); + Iterator keys = pipelineFields.keys(); + //iteration over listFields + while (keys.hasNext()) { + String key = (String) keys.next(); + if (pipelineFields.get(key) instanceof JSONArray) { + List fieldTagsIdsList = new LinkedList<>(); + //getting all ids assigned to listField + for (JSONObject singleField : toCollection(pipelineFields.getJSONArray(key))) { + fieldTagsIdsList.add(singleField.getString(ID_FIELD)); + } + //retrieving names of assigned items + if (fieldTagsIdsList.size() > 0) { + List enrichedFields = getListItemsById(client, fieldTagsIdsList, workspaceId); + JSONArray values = new JSONArray(); + fillArray(values, enrichedFields, NAME_FIELD, null); + ret.put(key, values); + } + } + } + } + pipeline.put(FIELDS, ret); + } + + @JavaScriptMethod + public JSONObject searchListItems(String logicalListName, String term, String instanceId, long workspaceId, boolean multiValue, boolean extensible) { + int defaultSize = 10; + JSONObject ret = new JSONObject(); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + try { + ResponseEntityList listItemPagedList = queryListItems(octaneClient, logicalListName, term, workspaceId, defaultSize); + List listItems = listItemPagedList.getData(); + boolean moreResults = listItemPagedList.getTotalCount() > listItems.size(); + + JSONArray retArray = new JSONArray(); + if (moreResults) { + retArray.add(createMoreResultsJson()); + } + + if (!multiValue) { + String quotedTerm = Pattern.quote(term.toLowerCase()); + if (Pattern.matches(".*" + quotedTerm + ".*", NOT_SPECIFIED.toLowerCase())) { + JSONObject notSpecifiedItemJson = new JSONObject(); + notSpecifiedItemJson.put(ID_FIELD, -1); + notSpecifiedItemJson.put(TEXT_FIELD, NOT_SPECIFIED); + retArray.add(notSpecifiedItemJson); + } + } + fillArray(retArray,listItems,TEXT_FIELD, this::isNotManualTestingToolType); + + // we shall use "if (extensible){}" on following line, but we do not have UI ready for the case: multiValue = true & extensible = true + if (extensible && !multiValue) { + //if exactly one item matches, we do not want to bother user with "new value" item + if ((listItems.size() != 1) || (!listItems.get(0).getName().toLowerCase().equals(term.toLowerCase()))) { + retArray.add(createNewValueJson("0")); + } + } + + + ret.put("results", retArray); + } catch (Exception e) { + logger.warn("Failed to retrieve list items", e); + return error("Unable to retrieve job configuration"); + } + + return ret; + } + + private boolean isNotManualTestingToolType(Entity item) { + return !(item.getStringValue(EntityConstants.Base.LOGICAL_NAME_FIELD).equalsIgnoreCase("list_node.testing_tool_type.manual")); + } + + @JavaScriptMethod + public JSONObject searchReleases(String term, String instanceId, long workspaceId) { + int defaultSize = 5; + JSONObject ret = new JSONObject(); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + try { + + ResponseEntityList releasePagedList = queryReleasesByName(octaneClient, term, workspaceId, defaultSize); + List releases = releasePagedList.getData(); + boolean moreResults = releasePagedList.getTotalCount() > releases.size(); + + JSONArray retArray = new JSONArray(); + if (moreResults) { + retArray.add(createMoreResultsJson()); + } + + String quotedTerm = Pattern.quote(term.toLowerCase()); + if (Pattern.matches(".*" + quotedTerm + ".*", NOT_SPECIFIED.toLowerCase())) { + JSONObject notSpecifiedItemJson = new JSONObject(); + notSpecifiedItemJson.put(ID_FIELD, -1); + notSpecifiedItemJson.put(TEXT_FIELD, NOT_SPECIFIED); + retArray.add(notSpecifiedItemJson); + } + + fillArray(retArray, releases, TEXT_FIELD, null); + ret.put("results", retArray); + + } catch (Exception e) { + logger.warn("Failed to retrieve releases", e); + return error("Unable to retrieve releases"); + } + + return ret; + } + + @JavaScriptMethod + public JSONObject searchMilestones(String term, String instanceId, long workspaceId, long releaseId) { + int defaultSize = 5; + JSONObject ret = new JSONObject(); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + try { + + ResponseEntityList milestonePagedList = queryMilestonesByNameAndRelease(octaneClient, term, workspaceId, releaseId, defaultSize); + List milestones = milestonePagedList.getData(); + + boolean moreResults = milestonePagedList.getTotalCount() > milestones.size(); + JSONArray retArray = new JSONArray(); + if (moreResults) { + retArray.add(createMoreResultsJson()); + } + + String quotedTerm = Pattern.quote(term.toLowerCase()); + if (Pattern.matches(".*" + quotedTerm + ".*", NOT_SPECIFIED.toLowerCase())) { + JSONObject notSpecifiedItemJson = new JSONObject(); + notSpecifiedItemJson.put(ID_FIELD, -1); + notSpecifiedItemJson.put(TEXT_FIELD, NOT_SPECIFIED); + retArray.add(notSpecifiedItemJson); + } + + fillArray(retArray, milestones, TEXT_FIELD, null); + ret.put("results", retArray); + + } catch (Exception e) { + logger.warn("Failed to retrieve milestones", e); + return error("Unable to retrieve milestones"); + } + + return ret; + } + + + @JavaScriptMethod + public JSONObject searchWorkspaces(String term, String instanceId) { + int defaultSize = 5; + JSONObject ret = new JSONObject(); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + + try { + ResponseEntityList workspacePagedList = queryWorkspacesByName(octaneClient, term, defaultSize); + List workspaces = workspacePagedList.getData(); + boolean moreResults = workspacePagedList.getTotalCount() > workspaces.size(); + + JSONArray retArray = new JSONArray(); + if (moreResults) { + retArray.add(createMoreResultsJson()); + } + + fillArray(retArray, workspaces, TEXT_FIELD, null); + ret.put("results", retArray); + + } catch (Exception e) { + logger.warn("Failed to retrieve workspaces", e); + return error("Unable to retrieve workspaces"); + } + + return ret; + } + + private static void fillArray(JSONArray array, List entities, String valueFieldName, Predicate predicate) { + for (Entity entity : entities) { + if(predicate == null || predicate.test(entity)) { + JSONObject relJson = new JSONObject(); + relJson.put(ID_FIELD, entity.getId()); + relJson.put(valueFieldName, entity.getName()); + array.add(relJson); + } + } + } + + @JavaScriptMethod + public JSONObject searchSharedSpaces(String term) { + JSONObject ret = new JSONObject(); + JSONArray retArray = new JSONArray(); + + for (OctaneServerSettingsModel model : ConfigurationService.getAllSettings()) { + if (StringUtils.isNotEmpty(term) && !model.getCaption().toLowerCase().contains(term.toLowerCase())) { + continue; + } + JSONObject relJson = new JSONObject(); + relJson.put(ID_FIELD, model.getIdentity()); + relJson.put(TEXT_FIELD, model.getCaption()); + retArray.add(relJson); + } + ret.put("results", retArray); + + return ret; + } + + @JavaScriptMethod + public JSONObject searchTaxonomies(String term, String instanceId, long workspaceId, JSONArray pipelineTaxonomies) { + int defaultSize = 20; + JSONObject ret = new JSONObject(); + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + try { + + //currently existing taxonomies on pipeline -> we need to show these options as disabled + List pipelineTaxonomiesList = new LinkedList<>(); + for (int i = 0; i < pipelineTaxonomies.size(); i++) { + JSONObject pipelineTaxonomy = pipelineTaxonomies.getJSONObject(i); + if (pipelineTaxonomy.containsKey("tagId") && pipelineTaxonomy.containsKey("tagTypeId")) { // we need to compare only taxonomies which already exist on server + pipelineTaxonomiesList.add(pipelineTaxonomy.getLong("tagId")); + } + } + //retrieving taxonomies from server + ResponseEntityList foundTaxonomies = queryTaxonomiesByName(octaneClient, term, workspaceId, defaultSize); + final List foundTaxonomiesList = foundTaxonomies.getData(); + boolean moreResults = foundTaxonomies.getTotalCount() > foundTaxonomiesList.size(); + + //creating map > + // for easier creating result JSON + Map> taxonomyMap = new HashMap<>(); + Map taxonomyCategories = new HashMap<>(); + for (Entity taxonomy : foundTaxonomiesList) { + Entity root = (Entity) taxonomy.getField(EntityConstants.Taxonomy.CATEGORY_NAME); + if (root != null) { + if (taxonomyMap.containsKey(root.getId())) { + taxonomyMap.get(root.getId()).add(taxonomy); + } else { + taxonomyMap.put(root.getId(), new LinkedHashSet<>(Collections.singletonList(taxonomy))); + taxonomyCategories.put(root.getId(), root.getName()); + } + } + } + + //writing result json + JSONArray select2InputArray = new JSONArray(); + JSONObject allTags = new JSONObject(); + JSONObject tagTypesByName = new JSONObject(); + JSONObject tagTypes = new JSONObject(); + + //show warning, that there are more results and user should filter more specific + if (moreResults) { + select2InputArray.add(createMoreResultsJson()); + } + + for (Entry> taxonomyType : taxonomyMap.entrySet()) { + String tagTypeId = taxonomyType.getKey(); + String tagTypeName = taxonomyCategories.get(tagTypeId); + JSONArray childrenArray = new JSONArray(); + + JSONObject optgroup = new JSONObject(); + optgroup.put(TEXT_FIELD, tagTypeName); + + //for tagTypesByName + JSONObject tagTypeJson = new JSONObject(); + tagTypeJson.put("tagTypeId", tagTypeId); + tagTypeJson.put("tagTypeName", tagTypeName); + JSONArray tagTypeByNameValues = new JSONArray(); + + for (Entity tax : taxonomyType.getValue()) { + //creating input format for select2, so that this structure does not have to be refactored in javascript + JSONObject taxonomyJson = new JSONObject(); + taxonomyJson.put(ID_FIELD, tax.getId()); + taxonomyJson.put(TEXT_FIELD, tax.getName()); + taxonomyJson.put("value", tax.getId()); + if (pipelineTaxonomiesList.contains(tax.getId())) { + taxonomyJson.put("disabled", "disabled"); + } + childrenArray.add(taxonomyJson); + + //for allTags - adding tag into table of selected ones + Entity root = (Entity) tax.getField(EntityConstants.Taxonomy.CATEGORY_NAME); + JSONObject tagObject = new JSONObject(); + tagObject.put("tagId", tax.getId()); + tagObject.put("tagName", tax.getName()); + tagObject.put("tagTypeId", root.getId()); + tagObject.put("tagTypeName", root.getName()); + allTags.put(String.valueOf(tax.getId()), tagObject); + + //for tagTypesByName + JSONObject tagTypeByNameValue = new JSONObject(); + tagTypeByNameValue.put("tagId", tax.getId()); + tagTypeByNameValue.put("tagName", tax.getName()); + tagTypeByNameValues.add(tagTypeByNameValue); + } + //New value.. for current type + JSONObject newValueJson = createNewValueJson(Long.toString(tagTypeValue(Long.parseLong(tagTypeId)))); + childrenArray.add(newValueJson); + + optgroup.put("children", childrenArray); + select2InputArray.add(optgroup); + tagTypeJson.put("values", tagTypeByNameValues); + tagTypesByName.put(tagTypeName, tagTypeJson); + tagTypes.put(tagTypeId, tagTypeJson); + } + + // New type... New value... + JSONObject optgroup = new JSONObject(); + optgroup.put(TEXT_FIELD, "New type..."); + JSONObject newValueJson = createNewValueJson("newTagType"); + JSONArray childrenArray = new JSONArray(); + childrenArray.add(newValueJson); + optgroup.put("children", childrenArray); + select2InputArray.add(optgroup); + + ret.put("select2Input", select2InputArray); + ret.put("allTags", allTags); + ret.put("tagTypesByName", tagTypesByName); + ret.put("tagTypes", tagTypes); + ret.put("more", moreResults); + + } catch (Exception e) { + logger.warn("Failed to retrieve environments", e); + return error("Unable to retrieve environments"); + } + + return ret; + } + + private static JSONObject createMoreResultsJson() { + JSONObject moreResultsJson = new JSONObject(); + moreResultsJson.put(ID_FIELD, "moreResultsFound"); + moreResultsJson.put(TEXT_FIELD, Messages.TooManyResults()); + moreResultsJson.put("warning", "true"); + moreResultsJson.put("disabled", "disabled"); + return moreResultsJson; + } + + private static JSONObject createNewValueJson(String id) { + JSONObject newValueJson = new JSONObject(); + newValueJson.put(ID_FIELD, id); + newValueJson.put(TEXT_FIELD, "New value..."); + newValueJson.put("newValue", "true"); + return newValueJson; + } + + private static long tagTypeValue(long n) { + // mapping to ensure negative value (solve the "0" tag type ID) + return -(n + 1); + } + + private static void addTaxonomyTags(JSONObject result, PipelineContext pipeline) { + JSONArray pipelineTaxonomies = new JSONArray(); + for (Taxonomy taxonomy : pipeline.getTaxonomies()) { + pipelineTaxonomies.add(tag(taxonomy)); + } + result.put(TAXONOMY_TAGS, pipelineTaxonomies); + } + + private static void addFields(JSONObject result, PipelineContext pipeline) { + JSONObject listFields = new JSONObject(); + + for (Map.Entry> fieldEntry : pipeline.getListFields().entrySet()) { + JSONArray assignedValuesArray = listFieldValues(fieldEntry.getValue()); + listFields.put(fieldEntry.getKey(), assignedValuesArray); + } + result.put(FIELDS, listFields); + } + + private static JSONArray listFieldValues(List listItems) { + JSONArray ret = new JSONArray(); + + for (ListItem item : listItems) { + JSONObject value = new JSONObject(); + value.put(ID_FIELD, item.getId()); + if (item.getName() != null) { + value.put(NAME_FIELD, item.getName()); + } + ret.add(value); + } + return ret; + } + + private static Collection toCollection(JSONArray array) { + return (Collection) array.subList(0, array.size()); + } + + private static JSONObject tag(Long tagId, String value) { + JSONObject tag = new JSONObject(); + tag.put("tagId", String.valueOf(tagId)); + tag.put("tagName", value); + return tag; + } + + private static JSONObject tag(Taxonomy taxonomy) { + JSONObject tag = tag(taxonomy.getId(), taxonomy.getName()); + if (taxonomy.getParent() != null) { + tag.put("tagTypeId", String.valueOf(taxonomy.getParent().getId())); + tag.put("tagTypeName", taxonomy.getParent().getName()); + } + return tag; + } + + private static JSONObject error(String message) { + return error(message, null); + } + + private static JSONObject error(String message, ExceptionLink exceptionLink) { + JSONObject result = new JSONObject(); + JSONArray errors = new JSONArray(); + JSONObject error = new JSONObject(); + error.put("message", message); + if (exceptionLink != null) { + error.put("url", exceptionLink.getUrl()); + error.put("label", exceptionLink.getLabel()); + } + errors.add(error); + result.put("errors", errors); + return result; + } + + private static class ClientException extends Exception { + + private ExceptionLink link; + + ClientException(String message) { + this(message, null); + } + + ClientException(String message, ExceptionLink link) { + super(message); + this.link = link; + } + + public ExceptionLink getLink() { + return link; + } + } + + private static class ExceptionLink { + + private String url; + private String label; + + ExceptionLink(String url, String label) { + this.url = url; + this.label = label; + } + + public String getUrl() { + return url; + } + + public String getLabel() { + return label; + } + } + + private static ResponseEntityList queryWorkspacesByName(OctaneClient octaneClient, String name, int limit) { + return queryEntitiesByName(octaneClient, name, null, null, "workspaces", limit); + } + + private static ResponseEntityList queryReleasesByName(OctaneClient octaneClient, String name, long workspaceId, int limit) { + return queryEntitiesByName(octaneClient, name, null, workspaceId, "releases", limit); + } + + private static ResponseEntityList queryMilestonesByNameAndRelease(OctaneClient octaneClient, String name, long workspaceId, long releaseId, int limit) { + Collection conditions = new LinkedList<>(); + conditions.add(QueryHelper.conditionRef(EntityConstants.Milestone.RELEASE_FIELD, ID_FIELD, Long.toString(releaseId))); + return queryEntitiesByName(octaneClient, name, conditions, workspaceId, EntityConstants.Milestone.COLLECTION_NAME, limit); + } + + private static ResponseEntityList queryTaxonomiesByName(OctaneClient octaneClient, String name, long workspaceId, int limit) { + EntitiesService entityService = octaneClient.getEntitiesService(); + List conditions = new LinkedList(); + conditions.add("!category={null}"); + if (!StringUtils.isEmpty(name)) { + conditions.add(QueryHelper.condition(EntityConstants.Base.NAME_FIELD, "*" + name + "*")); + conditions.add("(" + QueryHelper.condition(NAME_FIELD, "*" + name + "*") + "||" + QueryHelper.conditionRef("category", NAME_FIELD, "*" + name + "*") + ")"); + } + + String url = entityService.buildEntityUrl(workspaceId, "taxonomy_nodes", conditions, Arrays.asList(EntityConstants.Base.NAME_FIELD, EntityConstants.Taxonomy.CATEGORY_NAME), 0, limit, EntityConstants.Base.NAME_FIELD); + ResponseEntityList result = entityService.getPagedEntities(url); + return result; + } + + private static ResponseEntityList queryEntitiesByName(OctaneClient octaneClient, String name, Collection conditions, Long workspaceId, String collectionName, int limit) { + EntitiesService entityService = octaneClient.getEntitiesService(); + if(conditions == null) { + conditions = new LinkedList(); + } + + if (!StringUtils.isEmpty(name)) { + conditions.add(QueryHelper.condition(EntityConstants.Base.NAME_FIELD, "*" + name + "*")); + } + String url = entityService.buildEntityUrl(workspaceId, collectionName, conditions, Collections.singletonList(EntityConstants.Base.NAME_FIELD), 0, limit, EntityConstants.Base.NAME_FIELD); + ResponseEntityList result = entityService.getPagedEntities(url); + return result; + } + + private static ResponseEntityList queryListItems(OctaneClient octaneClient, String logicalListName, String name, long workspaceId, int limit) { + int myLimit = limit; + EntitiesService entityService = octaneClient.getEntitiesService(); + List conditions = new LinkedList(); + if (!StringUtils.isEmpty(name)) { + //list node are not filterable by name + myLimit = 100; + } + if (!StringUtils.isEmpty(logicalListName)) { + conditions.add(QueryHelper.conditionRef("list_root", EntityConstants.Base.LOGICAL_NAME_FIELD, logicalListName)); + } + + String url = entityService.buildEntityUrl(workspaceId, "list_nodes", conditions, null, 0, myLimit, null); + ResponseEntityList result = entityService.getPagedEntities(url); + ResponseEntityList myResult = result; + if (!StringUtils.isEmpty(name)) { + List data = result.getData().stream().filter(l -> l.getName().toLowerCase().contains(name.toLowerCase())).limit(limit).collect(Collectors.toList()); + myResult = (ResponseEntityList) dtoFactory.newDTO(ResponseEntityList.class).setData(data); + } + return myResult; + } + + private static List getWorkspacesById(OctaneClient client, Collection itemIds) { + return getEntitiesById(client, null, "workspaces", itemIds); + } + + private static List getListItemsById(OctaneClient client, Collection itemIds, long workspaceId) { + return getEntitiesById(client, workspaceId, EntityConstants.Lists.COLLECTION_NAME, itemIds); + } + + private static List getReleasesById(OctaneClient client, Collection itemIds, long workspaceId) { + return getEntitiesById(client, workspaceId, EntityConstants.Release.COLLECTION_NAME, itemIds); + } + + private static List getMilestonesById(OctaneClient client, Collection itemIds, long workspaceId) { + return getEntitiesById(client, workspaceId, EntityConstants.Milestone.COLLECTION_NAME, itemIds); + } + + private static List getTaxonomiesById(OctaneClient client, Collection itemIds, long workspaceId) { + return getEntitiesById(client, workspaceId, EntityConstants.Taxonomy.COLLECTION_NAME, itemIds); + } + + private static List convertTaxonomies(List entities) { + List taxonomies = new ArrayList<>(); + for (Entity entity : entities) { + Taxonomy taxonomy = dtoFactory.newDTO(Taxonomy.class); + taxonomy.setId(Long.parseLong(entity.getId())).setName(entity.getName()); + if (entity.containsField(EntityConstants.Taxonomy.CATEGORY_NAME)) { + Taxonomy parent = dtoFactory.newDTO(Taxonomy.class); + parent.setId(Long.parseLong(entity.getId())).setName(entity.getName()); + taxonomy.setParent(parent); + } + taxonomies.add(taxonomy); + } + return taxonomies; + } + + private static List getEntitiesById(OctaneClient octaneClient, Long workspaceId, String collectionName, Collection itemIds) { + return octaneClient.getEntitiesService().getEntitiesByIds(workspaceId, collectionName, itemIds); + } + + private static List getPipelineListNodeFieldsMetadata(OctaneClient octaneClient, long workspaceId) { + List conditions = new LinkedList<>(); + conditions.add(QueryHelper.condition("entity_name", "pipeline_node")); + conditions.add(QueryHelper.conditionIn(NAME_FIELD, Arrays.asList("test_tool_type", "test_level", "test_type", "test_framework"), false)); + + EntitiesService entityService = octaneClient.getEntitiesService(); + String url = entityService.buildEntityUrl(workspaceId, "metadata/fields", conditions, null, 0, null, null); + ResponseEntityList list = entityService.getPagedEntities(url); + return list.getData(); + } + + private static JSONArray convertToJsonMetadata(List listNodeFieldMetadataList) { + JSONArray fieldMetadataArray = new JSONArray(); + for (Entity entity : listNodeFieldMetadataList) { + Map fieldTypeData = (Map) entity.getField("field_type_data"); + List targets = (List) fieldTypeData.get("targets"); + Map listNodeTarget = (Map) targets.get(0); + + //find pipeline_tagging feature + List> fieldFeatures = (List>) entity.getField("field_features"); + Map pipelineTaggingFeature = null; + for (Map feature : fieldFeatures) { + if (feature.get(NAME_FIELD).equals("pipeline_tagging")) { + pipelineTaggingFeature = feature; + } + } + + JSONObject fieldMetadataJSON = new JSONObject(); + fieldMetadataJSON.put(NAME_FIELD, entity.getName()); + fieldMetadataJSON.put("listName", entity.getStringValue("label")); + fieldMetadataJSON.put("logicalListName", listNodeTarget.get("logical_name")); + fieldMetadataJSON.put("extensible", pipelineTaggingFeature.get("extensibility")); + fieldMetadataJSON.put("multiValue", fieldTypeData.get("multiple")); + fieldMetadataJSON.put("order", pipelineTaggingFeature.get("order")); + fieldMetadataArray.add(fieldMetadataJSON); + } + return fieldMetadataArray; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ReflectionUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ReflectionUtils.java new file mode 100644 index 0000000000..3d119af0fd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/ReflectionUtils.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import hudson.model.Action; +import org.apache.logging.log4j.Logger; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; + +/*** + * A utility class to help retrieving data from objects, + * on whom we have no type data. + */ +public class ReflectionUtils { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ReflectionUtils.class); + + public static T getFieldValue(Object someObject, String fieldName) { + for (Field field : someObject.getClass().getDeclaredFields()) { + field.setAccessible(true); + if (field.getName().equals(fieldName)) { + Object value = null; + try { + value = field.get(someObject); + } catch (IllegalAccessException e) { + logger.error("Failed to getFieldValue", e); + } + if (value != null) { + return (T)value; + } + } + } + return null; + } + + public static Object invokeMethodByName(Action action, String methodName, Object... args) throws InvocationTargetException, IllegalAccessException { + Method method = getMethodByName(action, methodName); + + return method.invoke(action, args); + } + + public static Method getMethodByName(Action action, String methodName) { + Method method = Arrays.stream(action.getClass().getDeclaredMethods()) + .filter(m->m.getName().equals(methodName)) + .findFirst().orElse(null); + return method; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SDKBasedLoggerProvider.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SDKBasedLoggerProvider.java new file mode 100644 index 0000000000..903bfb0183 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SDKBasedLoggerProvider.java @@ -0,0 +1,1948 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.hp.octane.integrations.services.logging.CommonLoggerContextUtil; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.message.EntryMessage; +import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.message.MessageFactory; +import org.apache.logging.log4j.util.MessageSupplier; +import org.apache.logging.log4j.util.Supplier; + +import java.io.File; + +/** + * SDK based (log4j brought by SDK) logger provider + * Main purpose of this custom logger provider is to ensure correct logs location configuration at the earliest point of the plugin initialization + * TODO: this method might become a part of an SPI interface of SDK's plugin services + */ +public final class SDKBasedLoggerProvider { + private static volatile boolean sysParamConfigured = false; + + private SDKBasedLoggerProvider() { + //CodeClimate : Add a private constructor to hide the implicit public one. + } + + public static Logger getLogger(Class type) { + try { + if (!sysParamConfigured) { + System.setProperty("octaneAllowedStorage", CIJenkinsServicesImpl.getAllowedStorageFile().getAbsolutePath() + File.separator); + //CommonLoggerContextUtil.configureLogger(CIJenkinsServicesImpl.getAllowedStorageFile()); + sysParamConfigured = true; + } + return LogManager.getLogger(type); + } catch (Exception e) { + //it can fail on slave because of missing permissions to create a folder for logs. In this case we return logger that do nothing + //JENKINS-6010 : Cannot send junit results to Octane, because there is no permission on slave to create log folder + return new EmptyLogger(); + } + } + + private static class EmptyLogger implements Logger { + + @Override + public void catching(Level level, Throwable throwable) { + //do nothing + } + + @Override + public void catching(Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, Message message) { + //do nothing + } + + @Override + public void debug(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void debug(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void debug(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, Object o) { + //do nothing + } + + @Override + public void debug(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, String s) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void debug(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Message message) { + //do nothing + } + + @Override + public void debug(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void debug(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void debug(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void debug(CharSequence charSequence) { + //do nothing + } + + @Override + public void debug(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Object o) { + //do nothing + } + + @Override + public void debug(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void debug(String s) { + //do nothing + } + + @Override + public void debug(String s, Object... objects) { + //do nothing + } + + @Override + public void debug(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void debug(String s, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Supplier supplier) { + //do nothing + } + + @Override + public void debug(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void debug(String s, Object o) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void debug(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void entry() { + //do nothing + } + + @Override + public void entry(Object... objects) { + //do nothing + } + + @Override + public void error(Marker marker, Message message) { + //do nothing + } + + @Override + public void error(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void error(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void error(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, Object o) { + //do nothing + } + + @Override + public void error(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, String s) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void error(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void error(Message message) { + //do nothing + } + + @Override + public void error(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void error(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void error(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void error(CharSequence charSequence) { + //do nothing + } + + @Override + public void error(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void error(Object o) { + //do nothing + } + + @Override + public void error(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void error(String s) { + //do nothing + } + + @Override + public void error(String s, Object... objects) { + //do nothing + } + + @Override + public void error(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void error(String s, Throwable throwable) { + //do nothing + } + + @Override + public void error(Supplier supplier) { + //do nothing + } + + @Override + public void error(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void error(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void error(String s, Object o) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void error(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void exit() { + //do nothing + } + + @Override + public R exit(R r) { + return null; + } + + @Override + public void fatal(Marker marker, Message message) { + //do nothing + } + + @Override + public void fatal(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void fatal(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void fatal(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, Object o) { + //do nothing + } + + @Override + public void fatal(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void fatal(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Message message) { + //do nothing + } + + @Override + public void fatal(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void fatal(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(CharSequence charSequence) { + //do nothing + } + + @Override + public void fatal(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Object o) { + //do nothing + } + + @Override + public void fatal(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(String s) { + //do nothing + } + + @Override + public void fatal(String s, Object... objects) { + //do nothing + } + + @Override + public void fatal(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void fatal(String s, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Supplier supplier) { + //do nothing + } + + @Override + public void fatal(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void fatal(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void fatal(String s, Object o) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void fatal(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public Level getLevel() { + return null; + } + + @Override + public MF getMessageFactory() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, Message message) { + //do nothing + } + + @Override + public void info(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void info(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void info(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, Object o) { + //do nothing + } + + @Override + public void info(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, String s) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void info(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void info(Message message) { + //do nothing + } + + @Override + public void info(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void info(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void info(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void info(CharSequence charSequence) { + //do nothing + } + + @Override + public void info(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void info(Object o) { + //do nothing + } + + @Override + public void info(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void info(String s) { + //do nothing + } + + @Override + public void info(String s, Object... objects) { + //do nothing + } + + @Override + public void info(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void info(String s, Throwable throwable) { + //do nothing + } + + @Override + public void info(Supplier supplier) { + //do nothing + } + + @Override + public void info(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void info(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void info(String s, Object o) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void info(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public boolean isDebugEnabled() { + return false; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return false; + } + + @Override + public boolean isEnabled(Level level) { + return false; + } + + @Override + public boolean isEnabled(Level level, Marker marker) { + return false; + } + + @Override + public boolean isErrorEnabled() { + return false; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return false; + } + + @Override + public boolean isFatalEnabled() { + return false; + } + + @Override + public boolean isFatalEnabled(Marker marker) { + return false; + } + + @Override + public boolean isInfoEnabled() { + return false; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return false; + } + + @Override + public boolean isTraceEnabled() { + return false; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return false; + } + + @Override + public boolean isWarnEnabled() { + return false; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return false; + } + + @Override + public void log(Level level, Marker marker, Message message) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, Object o) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Message message) { + //do nothing + } + + @Override + public void log(Level level, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void log(Level level, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, CharSequence charSequence) { + //do nothing + } + + @Override + public void log(Level level, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Object o) { + //do nothing + } + + @Override + public void log(Level level, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, String s) { + //do nothing + } + + @Override + public void log(Level level, String s, Object... objects) { + //do nothing + } + + @Override + public void log(Level level, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void log(Level level, String s, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Supplier supplier) { + //do nothing + } + + @Override + public void log(Level level, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void log(Level level, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void log(Level level, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void printf(Level level, Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void printf(Level level, String s, Object... objects) { + //do nothing + } + + @Override + public T throwing(Level level, T t) { + return null; + } + + @Override + public T throwing(T t) { + return null; + } + + @Override + public void trace(Marker marker, Message message) { + //do nothing + } + + @Override + public void trace(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void trace(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void trace(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, Object o) { + //do nothing + } + + @Override + public void trace(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, String s) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void trace(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Message message) { + //do nothing + } + + @Override + public void trace(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void trace(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void trace(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void trace(CharSequence charSequence) { + //do nothing + } + + @Override + public void trace(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Object o) { + //do nothing + } + + @Override + public void trace(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void trace(String s) { + //do nothing + } + + @Override + public void trace(String s, Object... objects) { + //do nothing + } + + @Override + public void trace(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void trace(String s, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Supplier supplier) { + //do nothing + } + + @Override + public void trace(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void trace(String s, Object o) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void trace(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public EntryMessage traceEntry() { + return null; + } + + @Override + public EntryMessage traceEntry(String s, Object... objects) { + return null; + } + + @Override + public EntryMessage traceEntry(Supplier... suppliers) { + return null; + } + + @Override + public EntryMessage traceEntry(String s, Supplier... suppliers) { + return null; + } + + @Override + public EntryMessage traceEntry(Message message) { + return null; + } + + @Override + public void traceExit() { + //do nothing + } + + @Override + public R traceExit(R r) { + return null; + } + + @Override + public R traceExit(String s, R r) { + return null; + } + + @Override + public void traceExit(EntryMessage entryMessage) { + //do nothing + } + + @Override + public R traceExit(EntryMessage entryMessage, R r) { + return null; + } + + @Override + public R traceExit(Message message, R r) { + return null; + } + + @Override + public void warn(Marker marker, Message message) { + //do nothing + } + + @Override + public void warn(Marker marker, Message message, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void warn(Marker marker, MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, CharSequence charSequence) { + //do nothing + } + + @Override + public void warn(Marker marker, CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, Object o) { + //do nothing + } + + @Override + public void warn(Marker marker, Object o, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, String s) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object... objects) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, Supplier supplier) { + //do nothing + } + + @Override + public void warn(Marker marker, Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Message message) { + //do nothing + } + + @Override + public void warn(Message message, Throwable throwable) { + //do nothing + } + + @Override + public void warn(MessageSupplier messageSupplier) { + //do nothing + } + + @Override + public void warn(MessageSupplier messageSupplier, Throwable throwable) { + //do nothing + } + + @Override + public void warn(CharSequence charSequence) { + //do nothing + } + + @Override + public void warn(CharSequence charSequence, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Object o) { + //do nothing + } + + @Override + public void warn(Object o, Throwable throwable) { + //do nothing + } + + @Override + public void warn(String s) { + //do nothing + } + + @Override + public void warn(String s, Object... objects) { + //do nothing + } + + @Override + public void warn(String s, Supplier... suppliers) { + //do nothing + } + + @Override + public void warn(String s, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Supplier supplier) { + //do nothing + } + + @Override + public void warn(Supplier supplier, Throwable throwable) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + + @Override + public void warn(String s, Object o) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { + //do nothing + } + + @Override + public void warn(String s, Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { + //do nothing + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SSCServerConfigUtil.java b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SSCServerConfigUtil.java new file mode 100644 index 0000000000..74d8909fa4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/configuration/SSCServerConfigUtil.java @@ -0,0 +1,212 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Action; +import hudson.model.Descriptor; +import hudson.tasks.Publisher; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/* + Utility to help retrieving the configuration of the SSC Server URL and SSC project/version pair + */ + +public class SSCServerConfigUtil { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(SSCServerConfigUtil.class); + private static final String PUBLISHER_NEW_NAME = "com.fortify.plugin.jenkins.FortifyPlugin"; + private static final String PUBLISHER_OLD_VERSION = "com.fortify.plugin.jenkins.FPRPublisher"; + + private static final String FORTIFY_UPLOAD_ACTION_NAME = "com.fortify.plugin.jenkins.FortifyUploadBuildAction"; + private static final String FORTIFY_UPLOAD_PROJECT_ACTIONS_METHOD = "getProjectActions"; + private static final String FORTIFY_UPLOAD_APP_NAME_METHOD = "getAppName"; + private static final String FORTIFY_UPLOAD_APP_VERSION_METHOD = "getAppVersion"; + + public static String getSSCServer() { + Descriptor sscDescriptor = getSSCDescriptor(); + return sscDescriptor != null ? getFieldValue(sscDescriptor, "url") : null; + } + + /** + * extracts and returns SSC project name and version if found on the AbstractProject configuration of the specified build + * + * @param build AbstractBuild + * @return valid SSC project name and version pair; otherwise NULL + */ + public static SSCProjectVersionPair getProjectConfigurationFromBuild(AbstractBuild build) { + return build != null ? getProjectVersion(build.getProject()) : null; + } + + public static SSCProjectVersionPair getProjectConfigurationFromWorkflowRun(WorkflowRun run) { + + SSCProjectVersionPair projectVersionPair = null; + List workflowActions = run != null ? (List) run.getAllActions() : new ArrayList<>(); + + for (Action action: workflowActions) { + if (action.getClass().getName().equals(FORTIFY_UPLOAD_ACTION_NAME)) { + try { + List projectActions = (List) ReflectionUtils.invokeMethodByName(action, FORTIFY_UPLOAD_PROJECT_ACTIONS_METHOD, null); + Action projectMethods = projectActions != null && projectActions.size() > 0 ? projectActions.get(0) : null; + + if (projectMethods != null) { + String projName = (String) ReflectionUtils.invokeMethodByName(projectMethods, FORTIFY_UPLOAD_APP_NAME_METHOD, null); + String version = (String) ReflectionUtils.invokeMethodByName(projectMethods, FORTIFY_UPLOAD_APP_VERSION_METHOD, null); + + projectVersionPair = new SSCProjectVersionPair(projName, version); + } + } catch(Exception e) { + logger.error("Failed getProjectConfigurationFromWorkflowRun", e); + } + } + } + + return projectVersionPair; + } + + private static SSCProjectVersionPair getProjectVersion(AbstractProject project) { + for (Object publisher : project.getPublishersList()) { + if (publisher instanceof Publisher && + isSSCPublisher(publisher.getClass().getName())) { + return getProjectNameByReflection(publisher); + } + } + return null; + } + + private static boolean isSSCPublisher(String publisherName) { + return PUBLISHER_NEW_NAME.equals(publisherName) || + PUBLISHER_OLD_VERSION.equals(publisherName); + } + + private static SSCProjectVersionPair getProjectNameByReflection(Object fprPublisher) { + String projectName = getFieldValue(fprPublisher, "projectName"); + String projectVersion = getFieldValue(fprPublisher, "projectVersion"); + if (projectName != null && !projectName.isEmpty() && projectVersion != null && !projectVersion.isEmpty()) { + return new SSCProjectVersionPair(projectName, projectVersion); + } + logger.warn("Version seems to be 18.20.1071 or higher"); + //18.20.1071 version. + Object uploadSSC = getFieldValueAsObj(fprPublisher, "uploadSSC"); + if (uploadSSC == null) { + Object analysisRunType = getFieldValueAsObj(fprPublisher, "analysisRunType"); + if (analysisRunType == null) { + logger.warn("uploadSSC section was not found"); + } else { + uploadSSC = getFieldValueAsObj(analysisRunType, "uploadSSC"); + if (uploadSSC == null) { + logger.warn("uploadSSC section was not found"); + } else { + projectName = getFieldValue(uploadSSC, "appName"); + projectVersion = getFieldValue(uploadSSC, "appVersion"); + if (projectName != null && !projectName.isEmpty() && projectVersion != null && !projectVersion.isEmpty()) { + return new SSCProjectVersionPair(projectName, projectVersion); + } + } + + logger.warn("uploadSSC section was not found"); + } + } else { + logger.warn("uploadSSC was found "); + projectName = getFieldValue(uploadSSC, "projectName"); + projectVersion = getFieldValue(uploadSSC, "projectVersion"); + logger.warn("projectName" + projectName + " , ProjectVersion" + projectVersion); + } + if (projectName != null && !projectName.isEmpty() && projectVersion != null && !projectVersion.isEmpty()) { + return new SSCProjectVersionPair(projectName, projectVersion); + } + return null; + } + + private static String getFieldValue(Object someObject, String fieldName) { + for (Field field : someObject.getClass().getDeclaredFields()) { + field.setAccessible(true); + if (field.getName().equals(fieldName)) { + Object value = null; + try { + value = field.get(someObject); + } catch (IllegalAccessException e) { + logger.error("Failed to getFieldValue", e); + } + if (value != null) { + return value.toString(); + } + } + } + return null; + } + + private static Object getFieldValueAsObj(Object someObject, String fieldName) { + for (Field field : someObject.getClass().getDeclaredFields()) { + field.setAccessible(true); + if (field.getName().equals(fieldName)) { + try { + return field.get(someObject); + } catch (IllegalAccessException e) { + logger.error("Failed to getFieldValue", e); + } + } + } + return null; + } + + private static Descriptor getSSCDescriptor() { + Descriptor publisher = Jenkins.get().getDescriptorByName(PUBLISHER_OLD_VERSION); + if (publisher == null) { + //18.20 version and above. + logger.debug("didn't find Old SSC FPRPublisher"); + Descriptor plugin = Jenkins.get().getDescriptorByName(PUBLISHER_NEW_NAME); + if (plugin == null) { + logger.debug("didn't find Fortify Plugin of 18.20 version and above"); + } + return plugin; + } + return publisher; + } + + public static final class SSCProjectVersionPair { + public final String project; + public final String version; + + public SSCProjectVersionPair(String project, String version) { + this.project = project; + this.version = version; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/AbstractBuildListenerOctaneImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/AbstractBuildListenerOctaneImpl.java new file mode 100644 index 0000000000..b7c59c2714 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/AbstractBuildListenerOctaneImpl.java @@ -0,0 +1,195 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.google.inject.Inject; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.hp.octane.integrations.dto.events.PhaseType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.CIEventCausesFactory; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.model.processors.scm.CommonOriginRevision; +import com.microfocus.application.automation.tools.octane.model.processors.scm.SCMProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.scm.SCMProcessors; +import com.microfocus.application.automation.tools.octane.tests.TestListener; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import hudson.model.*; +import hudson.model.listeners.RunListener; +import hudson.scm.SCM; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; + +import java.util.List; + +/** + * Run Listener that handles basic CI events and dispatches notifications to the Octane server + * User: gullery + * Date: 24/08/14 + * Time: 17:21 + */ + +@Extension +@SuppressWarnings({"squid:S2259", "squid:S1872", "squid:S1698", "squid:S1132"}) +public final class AbstractBuildListenerOctaneImpl extends RunListener { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(AbstractBuildListenerOctaneImpl.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + @Inject + private TestListener testListener; + + @Override + public void onStarted(AbstractBuild build, TaskListener listener) { + if(!OctaneSDK.hasClients()){ + return; + } + publishStartEvent(build); + } + + private void publishStartEvent(AbstractBuild build) { + try { + CIEvent event = dtoFactory.newDTO(CIEvent.class) + .setEventType(CIEventType.STARTED) + .setProject(BuildHandlerUtils.getJobCiId(build)) + .setProjectDisplayName(BuildHandlerUtils.translateFullDisplayName(build.getParent().getFullDisplayName())) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(build)) + .setNumber(String.valueOf(build.getNumber())) + .setStartTime(build.getStartTimeInMillis()) + .setEstimatedDuration(build.getEstimatedDuration()) + .setCauses(CIEventCausesFactory.processCauses(build)) + .setParameters(ParameterProcessors.getInstances(build)); + if (isInternal(build)) { + event.setPhaseType(PhaseType.INTERNAL); + } else { + event.setPhaseType(PhaseType.POST); + } + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } catch (Throwable throwable) { + logger.error("failed to build and/or dispatch STARTED event for " + build, throwable); + } + } + + @Override + public void onFinalized(AbstractBuild build) { + if(!OctaneSDK.hasClients()){ + return; + } + publishFinishEvent(build); + BuildLogHelper.enqueueBuildLog(build); + } + + private void publishFinishEvent(AbstractBuild build) { + try { + boolean hasTests = testListener.processBuild(build); + CIEvent event = dtoFactory.newDTO(CIEvent.class) + .setEventType(CIEventType.FINISHED) + .setProject(BuildHandlerUtils.getJobCiId(build)) + .setProjectDisplayName((BuildHandlerUtils.translateFullDisplayName(build.getParent().getFullDisplayName()))) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(build)) + .setNumber(String.valueOf(build.getNumber())) + .setStartTime(build.getStartTimeInMillis()) + .setEstimatedDuration(build.getEstimatedDuration()) + .setCauses(CIEventCausesFactory.processCauses(build)) + .setParameters(ParameterProcessors.getInstances(build)) + .setResult(BuildHandlerUtils.translateRunResult(build)) + .setDuration(build.getDuration()) + .setTestResultExpected(hasTests) + .setEnvironmentOutputtedParameters(OutputEnvironmentParametersHelper.getOutputEnvironmentParams(build)); + CommonOriginRevision commonOriginRevision = getCommonOriginRevision(build); + if (commonOriginRevision != null) { + event + .setCommonHashId(commonOriginRevision.revision) + .setBranchName(commonOriginRevision.branch); + } + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } catch (Throwable throwable) { + logger.error("failed to build and/or dispatch FINISHED event for " + build, throwable); + } + } + + private CommonOriginRevision getCommonOriginRevision(AbstractBuild build) { + CommonOriginRevision commonOriginRevision = null; + SCM scm = build.getProject().getScm(); + if (scm != null) { + SCMProcessor scmProcessor = SCMProcessors.getAppropriate(scm.getClass().getName()); + if (scmProcessor != null) { + commonOriginRevision = scmProcessor.getCommonOriginRevision(build); + } + } + return commonOriginRevision; + } + + // TODO: https://issues.jenkins-ci.org/browse/JENKINS-53410 + private boolean isInternal(Run r) { + boolean result = false; + + // get upstream cause, if any + Cause.UpstreamCause upstreamCause = null; + for (Object cause : r.getCauses()) { + if (cause instanceof Cause.UpstreamCause) { + upstreamCause = (Cause.UpstreamCause) cause; + break; + } + } + + if (upstreamCause != null) { + String causeJobName = upstreamCause.getUpstreamProject(); + Item parent = Jenkins.get().getItemByFullName(causeJobName); + if (parent == null) { + result = true; + } else { + if (parent.getClass().getName().equals(JobProcessorFactory.WORKFLOW_JOB_NAME)) { + result = true; + } else { + List phases = JobProcessorFactory.getFlowProcessor((Job) parent).getInternals(); + for (PipelinePhase p : phases) { + for (PipelineNode n : p.getJobs()) { + if (n != null && n.getName().equals(r.getParent().getName())) { + return true; + } + } + } + return false; + } + } + } + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/BuildLogHelper.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/BuildLogHelper.java new file mode 100644 index 0000000000..7c2ace82ed --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/BuildLogHelper.java @@ -0,0 +1,65 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.Run; +import org.apache.logging.log4j.Logger; + +public class BuildLogHelper { + private static Logger logger = SDKBasedLoggerProvider.getLogger(BuildLogHelper.class); + + private BuildLogHelper(){ + //for code climate + } + + public static void enqueueBuildLog(Run run) { + if(!OctaneSDK.hasClients()){ + return; + } + try { + String jobCiId = BuildHandlerUtils.getJobCiId(run); + String buildCiId = BuildHandlerUtils.getBuildCiId(run); + String parents = BuildHandlerUtils.getRootJobCiIds(run); + + logger.debug("enqueued build '" + jobCiId + " #" + buildCiId + "' for log submission"); + OctaneSDK.getClients().forEach(octaneClient -> { + octaneClient.getLogsService().enqueuePushBuildLog(jobCiId, buildCiId, parents); + }); + } catch (Exception t) { + logger.error("failed to enqueue " + run + " for logs push to Octane", t); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/GlobalEventsListenerOctaneImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/GlobalEventsListenerOctaneImpl.java new file mode 100644 index 0000000000..148d63c8da --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/GlobalEventsListenerOctaneImpl.java @@ -0,0 +1,143 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.hp.octane.integrations.dto.events.ItemType; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.executor.UftTestDiscoveryDispatcher; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.settings.OctaneServerSettingsGlobalConfiguration; +import hudson.Extension; +import hudson.model.Item; +import hudson.model.listeners.ItemListener; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; + +/** + * Run Listener that handles basic CI item events and dispatches notifications to the Octane server + * User: shitritn + * Date: 12/06/18 + * Time: 09:33 + */ + +@Extension +public class GlobalEventsListenerOctaneImpl extends ItemListener { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(GlobalEventsListenerOctaneImpl.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + @Override + public void onLoaded() { + logger.info("**********************************************************************"); + logger.info("********************STARTING JENKINS *********************************"); + logger.info("**********************************************************************"); + logger.info("Jenkins version " + Jenkins.getVersion()); + logger.info("Plugin version " + ConfigurationService.getPluginVersion()); + logger.info("CI SDK version " + OctaneSDK.SDK_VERSION); + + OctaneServerSettingsGlobalConfiguration.getInstance().initOctaneClients(); + } + + @Override + public void onDeleted(Item item) { + if(!OctaneSDK.hasClients()){ + return; + } + try { + CIEvent event; + if (item.getParent() != null && item.getParent().getClass().getName().equalsIgnoreCase(JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME)) { + event = dtoFactory.newDTO(CIEvent.class) + .setEventType(CIEventType.DELETED) + .setProject(JobProcessorFactory.getFlowProcessor((WorkflowJob) item).getTranslatedJobName()); + + OctaneSDK.getClients().forEach(client -> client.getEventsService().publishEvent(event)); + } + } catch (Throwable throwable) { + logger.error("failed to build and/or dispatch DELETED event for " + item, throwable); + } + } + + @Override + public void onBeforeShutdown() { + OctaneSDK.getClients().forEach(OctaneSDK::removeClient); + UftTestDiscoveryDispatcher dispatcher = Jenkins.get().getExtensionList(UftTestDiscoveryDispatcher.class).get(0); + dispatcher.close(); + } + + @Override + public void onLocationChanged(Item item, String oldFullName, String newFullName) { + + if (!OctaneSDK.hasClients()) { + return; + } + + boolean skip = JobProcessorFactory.isFolder(item) || JobProcessorFactory.isMultibranchChild(item);//for MultibranchChild - there is a logic in Octane that handle child on parent event + logger.info("onLocationChanged '" + oldFullName + "' to '" + newFullName + "'" + (skip ? ". Skipped." : "")); + if (skip) { + return; + } + + try { + CIEvent event = dtoFactory.newDTO(CIEvent.class).setEventType(CIEventType.RENAMED); + if (JobProcessorFactory.isJob(item)) { + event.setItemType(ItemType.JOB); + } else if (JobProcessorFactory.isMultibranch(item)) { + event.setItemType(ItemType.MULTI_BRANCH); + } else { + logger.info("Cannot handle onLocationChanged for " + item.getClass().getName()); + return; + } + + event.setProject(BuildHandlerUtils.translateFolderJobName(newFullName)) + .setProjectDisplayName(newFullName) + .setPreviousProject(BuildHandlerUtils.translateFolderJobName(oldFullName)) + .setPreviousProjectDisplayName(oldFullName); + + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + OctaneSDK.getClients().forEach(c -> { + if (c.getConfigurationService().removeFromOctaneRoots(event.getPreviousProject())) { + c.getConfigurationService().addToOctaneRootsCache(event.getProject()); + } + }); + } catch (Throwable throwable) { + logger.error("failed to build and/or dispatch RENAMED event for " + item, throwable); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/OctaneQueueListener.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/OctaneQueueListener.java new file mode 100644 index 0000000000..f18e5f8e3a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/OctaneQueueListener.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.Extension; +import hudson.model.AbstractProject; +import hudson.model.ParametersAction; +import hudson.model.Queue; +import hudson.model.queue.QueueListener; +import org.apache.logging.log4j.Logger; + +@Extension +public class OctaneQueueListener extends QueueListener { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(OctaneQueueListener.class); + + @Override + public void onLeft(Queue.LeftItem li) { + if (!OctaneSDK.hasClients()) { + return; + } + + if (li.isCancelled()) { + if (li.task instanceof AbstractProject) { + try { + ParametersAction paramActions = li.getAction(ParametersAction.class); + AbstractProject project = (AbstractProject) li.task; + CIEvent event = DTOFactory.getInstance().newDTO(CIEvent.class) + .setEventType(CIEventType.REMOVED_FROM_QUEUE) + .setProject(JobProcessorFactory.getFlowProcessor(project).getTranslatedJobName()) + .setBuildCiId("-1") + .setParameters(ParameterProcessors.getInstances(paramActions)); + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } catch (Exception e) { + logger.error("Failed to set REMOVED_FROM_QUEUE event :" + e.getMessage() + "(" + li.task.getName() + ")"); + } + } else { + logger.error("Job is cancelled in queue but it isn't AbstractProject :" + li.task.getFullDisplayName() + "(" + li.task.getClass().getName() + ")"); + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/OutputEnvironmentParametersHelper.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/OutputEnvironmentParametersHelper.java new file mode 100644 index 0000000000..6ef6f557c0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/OutputEnvironmentParametersHelper.java @@ -0,0 +1,125 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.settings.OutputEnvironmentVariablesBuildWrapper; +import com.microfocus.application.automation.tools.settings.RunnerMiscSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.EnvVars; +import hudson.model.AbstractBuild; +import hudson.model.BuildableItemWithBuildWrappers; +import hudson.model.Job; +import hudson.model.Run; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class OutputEnvironmentParametersHelper { + + private static final String SPLIT_SYMBOL = "\\s++"; + + private OutputEnvironmentParametersHelper(){} + + private static Logger logger = SDKBasedLoggerProvider.getLogger(OutputEnvironmentParametersHelper.class); + + public static Map getOutputEnvironmentParams(Run run) { + EnvVars environment = getEnvironment(run); + if (environment == null) { + return Collections.emptyMap(); + } else { + List paramKeysList = new ArrayList<>(); + paramKeysList.addAll(getGlobalParamsList()); + paramKeysList.addAll(getJobParamsList(run)); + + if (paramKeysList.isEmpty()) return Collections.emptyMap(); + + Map outputEnvParams = new HashMap<>(); + Set sensitiveBuildVariables =null; + if (run instanceof AbstractBuild) { + sensitiveBuildVariables = ((AbstractBuild) run).getSensitiveBuildVariables(); + } + + String value; + for (String key : paramKeysList) { + if (sensitiveBuildVariables != null && sensitiveBuildVariables.contains(key)) continue; + value = environment.get(key); + if (value != null) { + outputEnvParams.put(key, value); + } + } + return outputEnvParams; + } + } + + private static EnvVars getEnvironment(Run run) { + EnvVars environment = null; + try { + environment = run.getEnvironment(null); + } catch (IOException | InterruptedException e) { + logger.error("Can not get Run(id: " + run.getId() + ") Environment: " + e.getMessage()); + } + return environment; + } + + private static List getGlobalParamsList() { + try { + String paramsStr = RunnerMiscSettingsGlobalConfiguration.getInstance().getOutputEnvironmentParameters(); + return createParamsListFromString(paramsStr); + } catch (NullPointerException ignored) { + return Collections.emptyList(); + } + } + + private static List getJobParamsList(Run run) { + Job job = run.getParent(); + if (job instanceof BuildableItemWithBuildWrappers) { + OutputEnvironmentVariablesBuildWrapper outputEnvVarsBuildWrapper = ((BuildableItemWithBuildWrappers) job) + .getBuildWrappersList().get(OutputEnvironmentVariablesBuildWrapper.class); + if (outputEnvVarsBuildWrapper != null) { + String paramsStr = outputEnvVarsBuildWrapper.getOutputEnvironmentParameters(); + if (!StringUtils.isNullOrEmpty(paramsStr)) { + return createParamsListFromString(paramsStr); + } + } + } + return Collections.emptyList(); + } + + private static List createParamsListFromString(String params) { + return Stream.of(params.split(SPLIT_SYMBOL)).filter(p -> !StringUtils.isNullOrEmpty(p)).collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/SCMListenerOctaneImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/SCMListenerOctaneImpl.java new file mode 100644 index 0000000000..a56f00a8a6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/SCMListenerOctaneImpl.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.scm.SCMData; +import com.microfocus.application.automation.tools.octane.model.processors.scm.SCMProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.scm.SCMUtils; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.model.listeners.SCMListener; +import hudson.scm.ChangeLogSet; +import hudson.scm.SCM; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * Run Listener that handles SCM CI events and dispatches notifications to the Octane server + * Created by gullery on 10/07/2016. + */ + +@Extension +public class SCMListenerOctaneImpl extends SCMListener { + + @Override + public void onChangeLogParsed(Run run, SCM scm, TaskListener listener, ChangeLogSet changelog) throws Exception { + if (!OctaneSDK.hasClients()) { + return; + } + super.onChangeLogParsed(run, scm, listener, changelog); + + String jobCiId = BuildHandlerUtils.getJobCiId(run); + String buildCiId = BuildHandlerUtils.getBuildCiId(run); + + SCMData scmData = SCMUtils.extractSCMData(run, scm, SCMProcessors.getAppropriate(scm.getClass().getName())); + + + if (scmData != null) { + String parents = BuildHandlerUtils.getRootJobCiIds(run); + SCMUtils.persistSCMData(run, jobCiId, buildCiId, scmData); + OctaneSDK.getClients().forEach(octaneClient -> + octaneClient.getSCMDataService().enqueueSCMData(jobCiId, buildCiId, scmData, parents)); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/events/WorkflowListenerOctaneImpl.java b/src/main/java/com/microfocus/application/automation/tools/octane/events/WorkflowListenerOctaneImpl.java new file mode 100644 index 0000000000..b23e990bc6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/events/WorkflowListenerOctaneImpl.java @@ -0,0 +1,259 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.google.inject.Inject; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.causes.CIEventCause; +import com.hp.octane.integrations.dto.causes.CIEventCauseType; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.hp.octane.integrations.dto.events.MultiBranchType; +import com.hp.octane.integrations.dto.events.PhaseType; +import com.hp.octane.integrations.dto.snapshots.CIBuildResult; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.CIEventCausesFactory; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.TestListener; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import hudson.model.Result; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.actions.TimingAction; +import org.jenkinsci.plugins.workflow.actions.WarningAction; +import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode; +import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode; +import org.jenkinsci.plugins.workflow.flow.GraphListener; +import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Octane's listener for WorkflowRun events + * - this listener should handle Pipeline's STARTED and FINISHED events + * - this listener should handle each stage's STARTED and FINISHED events + * + * User: gadiel + * Date: 07/06/2016 + * Time: 17:21 + */ + +@Extension +public class WorkflowListenerOctaneImpl implements GraphListener { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(WorkflowListenerOctaneImpl.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + //After upgrading Pipeline:Groovy plugin to Version 2.64: receive two start events, therefore + // pipeline job shows 2 bars for a single pipeline run. + // Here we add job key during start event and remove key in finished event + private static Set workflowJobStarted = new HashSet<>(); + @Inject + private TestListener testListener; + + @Override + public void onNewHead(FlowNode flowNode) { + if(!OctaneSDK.hasClients()){ + return; + } + try { + if (BuildHandlerUtils.isWorkflowStartNode(flowNode)) { + sendPipelineStartedEvent(flowNode); + } else if (BuildHandlerUtils.isWorkflowEndNode(flowNode)) { + WorkflowRun parentRun = BuildHandlerUtils.extractParentRun(flowNode); + sendPipelineFinishedEvent(parentRun); + BuildLogHelper.enqueueBuildLog(parentRun); + } else if (BuildHandlerUtils.isStageStartNode(flowNode)) { + sendStageStartedEvent((StepStartNode) flowNode); + } else if (BuildHandlerUtils.isStageEndNode(flowNode)) { + sendStageFinishedEvent((StepEndNode) flowNode); + } + } catch (Throwable throwable) { + logger.error("failed to build and/or dispatch STARTED/FINISHED event for " + flowNode, throwable); + } + } + + private void sendPipelineStartedEvent(FlowNode flowNode) { + WorkflowRun parentRun = BuildHandlerUtils.extractParentRun(flowNode); + + //Avoid duplicate start events + String buildKey = getBuildKey(parentRun); + if (workflowJobStarted.contains(buildKey)) { + return; + } else { + workflowJobStarted.add(buildKey); + } + + CIEvent event = dtoFactory.newDTO(CIEvent.class) + .setEventType(CIEventType.STARTED) + .setProjectDisplayName(BuildHandlerUtils.translateFullDisplayName(parentRun.getParent().getFullDisplayName())) + .setProject(BuildHandlerUtils.getJobCiId(parentRun)) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(parentRun)) + .setNumber(String.valueOf(parentRun.getNumber())) + .setParameters(ParameterProcessors.getInstances(parentRun)) + .setStartTime(parentRun.getStartTimeInMillis()) + .setEstimatedDuration(parentRun.getEstimatedDuration()) + .setCauses(CIEventCausesFactory.processCauses(parentRun)); + + if(isInternal(event.getCauses())){ + event.setPhaseType(PhaseType.INTERNAL); + } + if (parentRun.getParent().getParent().getClass().getName().equals(JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME)) { + event + .setParentCiId(BuildHandlerUtils.translateFolderJobName(parentRun.getParent().getParent().getFullName())) + .setMultiBranchType(MultiBranchType.MULTI_BRANCH_CHILD) + .setProjectDisplayName(BuildHandlerUtils.translateFullDisplayName(parentRun.getParent().getFullDisplayName())); + } + + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } + + private boolean isInternal(List causes) { + if (causes != null) { + for (CIEventCause cause : causes) { + if (CIEventCauseType.UPSTREAM.equals(cause.getType())) { + return true; + } + } + } + return false; + } + + private String getBuildKey(WorkflowRun run){ + return run.getFullDisplayName(); + } + + private void sendPipelineFinishedEvent(WorkflowRun parentRun) { + workflowJobStarted.remove(getBuildKey(parentRun)); + boolean hasTests = testListener.processBuild(parentRun); + + CIEvent event = dtoFactory.newDTO(CIEvent.class) + .setEventType(CIEventType.FINISHED) + .setProject(BuildHandlerUtils.getJobCiId(parentRun)) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(parentRun)) + .setNumber(String.valueOf(parentRun.getNumber())) + .setParameters(ParameterProcessors.getInstances(parentRun)) + .setStartTime(parentRun.getStartTimeInMillis()) + .setEstimatedDuration(parentRun.getEstimatedDuration()) + .setDuration(parentRun.getDuration()) + .setResult(BuildHandlerUtils.translateRunResult(parentRun)) + .setCauses(CIEventCausesFactory.processCauses(parentRun)) + .setTestResultExpected(hasTests) + .setEnvironmentOutputtedParameters(OutputEnvironmentParametersHelper.getOutputEnvironmentParams(parentRun)); + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } + + private void sendStageStartedEvent(StepStartNode stepStartNode) { + logger.debug("node " + stepStartNode + " detected as Stage Start node"); + CIEvent event = prepareStageEvent(stepStartNode).setEventType(CIEventType.STARTED); + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } + + private void sendStageFinishedEvent(StepEndNode stepEndNode) { + logger.debug("node " + stepEndNode + " detected as Stage End node"); + StepStartNode stepStartNode = stepEndNode.getStartNode(); + CIEvent event = prepareStageEvent(stepStartNode) + .setEventType(CIEventType.FINISHED) + .setDuration(TimingAction.getStartTime(stepEndNode) - TimingAction.getStartTime(stepStartNode)) + .setResult(extractFlowNodeResult(stepEndNode)); + + CIJenkinsServicesImpl.publishEventToRelevantClients(event); + } + + private CIEvent prepareStageEvent(StepStartNode stepStartNode) { + WorkflowRun parentRun = BuildHandlerUtils.extractParentRun(stepStartNode); + return dtoFactory.newDTO(CIEvent.class) + .setPhaseType(PhaseType.INTERNAL) + .setIsVirtualProject(true) + .setProject(stepStartNode.getDisplayName()) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(parentRun)) + .setNumber(String.valueOf(parentRun.getNumber())) + .setStartTime(TimingAction.getStartTime(stepStartNode)) + .setCauses(CIEventCausesFactory.processCauses(stepStartNode)); + } + + private CIBuildResult extractFlowNodeResult(FlowNode node) { + CIBuildResult result = node.getError() != null ? CIBuildResult.FAILURE : CIBuildResult.SUCCESS; + if (CIBuildResult.SUCCESS.equals(result) && isChildNodeFailed(node, 0)) { + result = CIBuildResult.FAILURE; + } + return result; + } + + /** + * example of script : in this case second stage is failing but in octane its successful;in third case - error converted to warning + * node { + * stage('Build') {} + * stage('Results') { + * uftScenarioLoad archiveTestResultsMode: 'ALWAYS_ARCHIVE_TEST_REPORT',testPaths: '''c:\\dev\\plugins\\_uft\\UftTests\\GeneratedResult\\GUITestWithFail''' + * catchError(stageResult: 'FAILURE') {error 'error message 123'} + * } + * stage('Post Results') { + * warnError('Script failed!') {//convert error to warning + * error 'err 1' + * } + * } + * @param node + * @param iteration + * @return + */ + private boolean isChildNodeFailed(FlowNode node, int iteration) { + if (iteration >= 2) { // drill down upto 2 levels + return false; + } + try { + for (FlowNode temp : node.getParents()) { + if (temp instanceof StepEndNode) { + boolean isFailed = temp.getError() != null; + if (isFailed) {//if failed - validate that maybe error converted to warning of unstable + WarningAction warning = temp.getAction(WarningAction.class); + if (warning != null) { + return warning.getResult().isWorseThan(Result.UNSTABLE); + } + return true; + } else if (isChildNodeFailed(temp, iteration + 1)) { + return true; + } + } + } + } catch (Exception e) { + logger.error("failed in isChildNodeFailed " + e.getMessage()); + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/exceptions/AggregatedMessagesException.java b/src/main/java/com/microfocus/application/automation/tools/octane/exceptions/AggregatedMessagesException.java new file mode 100644 index 0000000000..495b156e95 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/exceptions/AggregatedMessagesException.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.exceptions; + +import java.util.List; + +/** + * Define exception type that receive list of error messages + */ +public class AggregatedMessagesException extends RuntimeException { + private List messages; + + public AggregatedMessagesException(List messages) { + this.messages = messages; + } + + @Override + public String getMessage() { + return String.join(";", getMessages()); + } + + + public List getMessages() { + return messages; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/CheckOutSubDirEnvContributor.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/CheckOutSubDirEnvContributor.java new file mode 100644 index 0000000000..65177853d4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/CheckOutSubDirEnvContributor.java @@ -0,0 +1,92 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginFactory; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginHandler; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.EnvironmentContributor; +import hudson.model.FreeStyleProject; +import hudson.model.Job; +import hudson.model.TaskListener; +import hudson.scm.NullSCM; +import hudson.scm.SCM; +import hudson.tasks.Builder; + +import java.util.List; + +/** + * Add job environment value for CHECKOUT_SUBDIR + */ +@Extension +public class CheckOutSubDirEnvContributor extends EnvironmentContributor { + + public static final String CHECKOUT_SUBDIR_ENV_NAME = "CHECKOUT_SUBDIR"; + + @Override + public void buildEnvironmentFor(Job j, EnvVars envs, TaskListener listener) { + if(!OctaneSDK.hasClients()){ + return; + } + String dir = getSharedCheckOutDirectory(j); + if (dir != null) { + envs.put(CHECKOUT_SUBDIR_ENV_NAME, dir); + } + } + + public static String getSharedCheckOutDirectory(Job j) { + if (j instanceof FreeStyleProject) { + FreeStyleProject proj = (FreeStyleProject) j; + SCM scm = proj.getScm(); + List builders = proj.getBuilders(); + if (scm != null && !(scm instanceof NullSCM) && builders != null) { + for (Builder builder : builders) { + if (builder instanceof RunFromFileBuilder) { + ScmPluginHandler scmPluginHandler = ScmPluginFactory.getScmHandlerByScmPluginName(scm.getClass().getName()); + if (scmPluginHandler != null) { + return scmPluginHandler.getSharedCheckOutDirectory(j); + } + } + } + + } + } + + return null; + } + +} + diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/ExecutorConnectivityService.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/ExecutorConnectivityService.java new file mode 100644 index 0000000000..7e3ab15865 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/ExecutorConnectivityService.java @@ -0,0 +1,213 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.CredentialsScope; +import com.cloudbees.plugins.credentials.CredentialsStore; +import com.cloudbees.plugins.credentials.SystemCredentialsProvider; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.domains.DomainRequirement; +import com.cloudbees.plugins.credentials.impl.BaseStandardCredentials; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.executor.CredentialsInfo; +import com.hp.octane.integrations.dto.executor.TestConnectivityInfo; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginFactory; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginHandler; +import hudson.model.Item; +import hudson.model.User; +import hudson.security.Permission; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Utility for handling connectivity with scm repositories + */ +public class ExecutorConnectivityService { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ExecutorConnectivityService.class); + private static final Map requirePremissions = initRequirePermissions(); + private static final Map credentialsPremissions = initCredentialsPermissions(); + private static final String PLUGIN_NAME = "Application Automation Tools"; + + /** + * Validate that scm repository is valid + * + * @param testConnectivityInfo contains values to check + * @return OctaneResponse return status code and error to show for client + */ + public static OctaneResponse checkRepositoryConnectivity(TestConnectivityInfo testConnectivityInfo) { + logger.info("checkRepositoryConnectivity started to " + testConnectivityInfo.getScmRepository().getUrl()); + OctaneResponse result = DTOFactory.getInstance().newDTO(OctaneResponse.class); + if (testConnectivityInfo.getScmRepository() != null && StringUtils.isNotEmpty(testConnectivityInfo.getScmRepository().getUrl())) { + + boolean needCredentialsPermission = false; + BaseStandardCredentials credentials = null; + if (StringUtils.isNotEmpty(testConnectivityInfo.getUsername()) && testConnectivityInfo.getPassword() != null) { + credentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, null, null, testConnectivityInfo.getUsername(), testConnectivityInfo.getPassword()); + needCredentialsPermission = true; + } else if (StringUtils.isNotEmpty(testConnectivityInfo.getCredentialsId())) { + credentials = getCredentialsById(testConnectivityInfo.getCredentialsId()); + } + + List permissionResult = checkCIPermissions(Jenkins.getInstanceOrNull(), needCredentialsPermission); + + if (!permissionResult.isEmpty()) { + String user = User.current() != null ? User.current().getId() : Jenkins.ANONYMOUS.getPrincipal().toString(); + String error = String.format("Failed : User \'%s\' is missing permissions \'%s\' on CI server", user, permissionResult); + logger.error(error); + result.setStatus(HttpStatus.SC_FORBIDDEN); + result.setBody(error); + return result; + } + + if (!ScmPluginFactory.isPluginInstalled(testConnectivityInfo.getScmRepository().getType())) { + result.setStatus(HttpStatus.SC_BAD_REQUEST); + result.setBody(String.format("%s plugin is not installed.", testConnectivityInfo.getScmRepository().getType().value().toUpperCase())); + } else { + ScmPluginHandler handler = ScmPluginFactory.getScmHandler(testConnectivityInfo.getScmRepository().getType()); + handler.checkRepositoryConnectivity(testConnectivityInfo, credentials, result); + } + + } else { + result.setStatus(HttpStatus.SC_BAD_REQUEST); + result.setBody("Missing input for testing"); + } + if (result.getStatus() != HttpStatus.SC_OK) { + logger.info("checkRepositoryConnectivity failed: " + result.getBody()); + } else { + logger.info("checkRepositoryConnectivity ok"); + } + return result; + } + + /** + * Insert of update(if already exist) of credentials in Jenkins. + * If credentialsInfo contains credentialsId - we update existing credentials with new user/password, otherwise - create new credentials + * + * @param credentialsInfo contains values to insert / update - exist credentials will be updated or recreate if deleted in jenkins + * @return OctaneResponse created/updated credentials with filled credentials id as body + */ + public static OctaneResponse upsertRepositoryCredentials(final CredentialsInfo credentialsInfo) { + + OctaneResponse result = DTOFactory.getInstance().newDTO(OctaneResponse.class); + result.setStatus(HttpStatus.SC_OK); + BaseStandardCredentials jenkinsCredentials = null; + + if (StringUtils.isNotEmpty(credentialsInfo.getUsername()) && credentialsInfo.getPassword() != null) { + jenkinsCredentials = tryGetCredentialsByUsernamePassword(credentialsInfo.getUsername(), credentialsInfo.getPassword()); + if (jenkinsCredentials == null) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + String desc = String.format("Created by the OpenText %s plugin on %s", PLUGIN_NAME, formatter.format(new Date())); + BaseStandardCredentials c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsInfo.getCredentialsId(), desc, credentialsInfo.getUsername(), credentialsInfo.getPassword()); + CredentialsStore store = new SystemCredentialsProvider.StoreImpl(); + try { + if(store.addCredentials(Domain.global(), c)){ + jenkinsCredentials = c; + result.setStatus(HttpStatus.SC_CREATED); + } + } catch (IOException e) { + logger.error("Failed to add credentials " + e.getMessage()); + result.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); + result.setBody("Failed to add credentials " + e.getMessage()); + } + } + } + + if (jenkinsCredentials != null) { + result.setBody(jenkinsCredentials.getId()); + } + + return result; + } + + private static BaseStandardCredentials getCredentialsById(String credentialsId) { + List list = CredentialsProvider.lookupCredentials(BaseStandardCredentials.class, (Item) null, null, (DomainRequirement) null); + for (BaseStandardCredentials cred : list) { + if (cred.getId().equals(credentialsId)) + return cred; + } + return null; + } + + private static UsernamePasswordCredentialsImpl tryGetCredentialsByUsernamePassword(String username, String password) { + List list = CredentialsProvider.lookupCredentials(UsernamePasswordCredentialsImpl.class, (Item) null, null, (DomainRequirement) null); + for (UsernamePasswordCredentialsImpl cred : list) { + if (StringUtils.equalsIgnoreCase(cred.getUsername(), username) + && StringUtils.equals(cred.getPassword().getPlainText(), password) + && cred.getDescription() != null && cred.getDescription().contains(PLUGIN_NAME)) { + return cred; + } + } + return null; + } + + private static List checkCIPermissions(final Jenkins jenkins, boolean checkCredentialsPermissions) { + List result = new ArrayList<>(); + checkPermissions(jenkins, result, requirePremissions); + if (checkCredentialsPermissions) { + checkPermissions(jenkins, result, credentialsPremissions); + } + return result; + } + + private static void checkPermissions(Jenkins jenkins, List result, Map permissions) { + for (Permission permission : permissions.keySet()) { + if (!jenkins.hasPermission(permission)) { + result.add(permissions.get(permission)); + } + } + } + + private static Map initRequirePermissions() { + Map result = new HashMap<>(); + result.put(Item.CREATE, "Job.CREATE"); + result.put(Item.READ, "Job.READ"); + return result; + } + + private static Map initCredentialsPermissions() { + Map result = new HashMap<>(); + result.put(CredentialsProvider.CREATE, "Credentials.CREATE"); + return result; + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/FullSyncRequiredCause.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/FullSyncRequiredCause.java new file mode 100644 index 0000000000..38be7bb814 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/FullSyncRequiredCause.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import hudson.model.Cause; + +/** + * FullSyncRequiredCause + * Informational class for full sync case. + * Used for SVN SCM delete action : in this case we don't receive inforamtion about deleted files, + * therefore full sync required to update ALM Octane entities correctly + */ +public class FullSyncRequiredCause extends Cause { + + private String buildId; + + public FullSyncRequiredCause(String buildId) { + this.buildId = buildId; + } + + public static FullSyncRequiredCause create(String buildId) { + return new FullSyncRequiredCause(buildId); + } + + @Override + public String getShortDescription() { + return String.format("Triggered by build #%s with full sync parameter.", buildId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/TestExecutionJobCreatorService.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/TestExecutionJobCreatorService.java new file mode 100644 index 0000000000..f3fdd2ac87 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/TestExecutionJobCreatorService.java @@ -0,0 +1,393 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import antlr.ANTLRException; +import com.cloudbees.hudson.plugins.folder.Folder; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.executor.DiscoveryInfo; +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.executor.TestsToRunFramework; +import com.hp.octane.integrations.services.configurationparameters.UftTestRunnerFolderParameter; +import com.hp.octane.integrations.utils.SdkConstants; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; +import com.microfocus.application.automation.tools.octane.actions.UFTTestDetectionPublisher; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginFactory; +import com.microfocus.application.automation.tools.octane.executor.scmmanager.ScmPluginHandler; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.testrunner.TestsToRunConverterBuilder; +import com.microfocus.application.automation.tools.results.RunResultRecorder; +import com.microfocus.application.automation.tools.run.RunFromCodelessBuilder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import hudson.model.*; +import hudson.tasks.BuildWrapper; +import hudson.tasks.Builder; +import hudson.triggers.SCMTrigger; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.microfocus.application.automation.tools.octane.executor.UftConstants.*; + +/** + * This service is responsible to create jobs (discovery and execution) for execution process. + */ +public class TestExecutionJobCreatorService { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(TestExecutionJobCreatorService.class); + + private static void setScmRepository(SCMRepository scmRepository, String scmRepositoryCredentialsId, FreeStyleProject proj, boolean executorJob) { + + ScmPluginHandler scmPluginHandler = ScmPluginFactory.getScmHandler(scmRepository.getType()); + try { + scmPluginHandler.setScmRepositoryInJob(scmRepository, scmRepositoryCredentialsId, proj, executorJob); + } catch (IOException e) { + throw new IllegalArgumentException("Failed to set SCM repository : " + e.getMessage()); + } + } + + /** + * Create (if needed) and run test discovery + * + * @param discoveryInfo discovery info + */ + public static void runTestDiscovery(DiscoveryInfo discoveryInfo) { + + /* + { + "scmRepository": { + "type": "git", + "url": "git@github.com:radislavB/UftTests.git" + }, + "executorId": "1", + "executorLogicalName": "ABC", + "workspaceId": "1002", + "testingToolType": "uft", + "forceFullDiscovery": true + } + */ + FreeStyleProject proj = createDiscoveryJob(discoveryInfo); + + //start job + if (proj != null) { + List paramList = new ArrayList<>(); + ParameterValue fullScanParam = new BooleanParameterValue(UftConstants.FULL_SCAN_PARAMETER_NAME, discoveryInfo.isForceFullDiscovery()); + paramList.add(fullScanParam); + + ParametersDefinitionProperty parameters = proj.getProperty(ParametersDefinitionProperty.class); + if (parameters.getParameterDefinitionNames().contains(UftConstants.TEST_RUNNER_ID_PARAMETER_NAME)) { + ParameterValue testRunnerIdParam = new StringParameterValue(UftConstants.TEST_RUNNER_ID_PARAMETER_NAME, discoveryInfo.getExecutorId()); + paramList.add(testRunnerIdParam); + } + + ParametersAction paramAction = new ParametersAction(paramList); + Cause cause = new Cause.UserIdCause(); + CauseAction causeAction = new CauseAction(cause); + proj.scheduleBuild2(0, paramAction, causeAction); + } + } + + private static Folder getParentFolder(String configurationId) { + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(configurationId); + UftTestRunnerFolderParameter uftFolderParameter = (UftTestRunnerFolderParameter) octaneClient.getConfigurationService() + .getConfiguration().getParameter(UftTestRunnerFolderParameter.KEY); + + if (uftFolderParameter != null) { + Item item = Jenkins.getInstanceOrNull().getItemByFullName(uftFolderParameter.getFolder()); + String errorMsg = null; + if (item == null) { + errorMsg = UftTestRunnerFolderParameter.KEY + " parameter is defined with '" + uftFolderParameter.getFolder() + "', the folder is not found. Validate that folder exist and jenkins user has READ permission on the folder."; + } + if (item != null && !JobProcessorFactory.isFolder(item)) { + errorMsg = UftTestRunnerFolderParameter.KEY + " parameter is defined with '" + uftFolderParameter.getFolder() + "', the item is " + item.getClass().getName() + " , but expected to be a folder."; + } + if (errorMsg != null) { + logger.error(errorMsg); + throw new IllegalArgumentException(errorMsg); + } else { + return (Folder) item; + } + } else { + return null; + } + } + + private static FreeStyleProject createProject(String configurationId, String name) throws IOException { + Folder folder = getParentFolder(configurationId); + FreeStyleProject proj; + if (folder == null) { + proj = Jenkins.getInstanceOrNull().createProject(FreeStyleProject.class, name); + } else { + proj = folder.createProject(FreeStyleProject.class, name); + } + return proj; + } + + private static FreeStyleProject createDiscoveryJob(DiscoveryInfo discoveryInfo) { + try { + String discoveryJobPrefix = TestingToolType.UFT.equals(discoveryInfo.getTestingToolType()) ? UFT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW : MBT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW; + String discoveryJobName = String.format("%s-%s-%s", discoveryJobPrefix, discoveryInfo.getExecutorId(), discoveryInfo.getExecutorLogicalName().substring(0,5)); + FreeStyleProject proj = createProject(discoveryInfo.getConfigurationId(), discoveryJobName); + + proj.setDescription(String.format("This job was created by the OpenText Application Automation Tools plugin for discovery of %s tests. It is associated with ALM Octane test runner #%s.", + discoveryInfo.getTestingToolType().toString(), discoveryInfo.getExecutorId())); + + setScmRepository(discoveryInfo.getScmRepository(), discoveryInfo.getScmRepositoryCredentialsId(), proj, false); + addConstantParameter(proj, UftConstants.TEST_RUNNER_ID_PARAMETER_NAME, discoveryInfo.getExecutorId(), "ALM Octane test runner ID"); + addConstantParameter(proj, UftConstants.TEST_RUNNER_LOGICAL_NAME_PARAMETER_NAME, discoveryInfo.getExecutorLogicalName(), "ALM Octane test runner logical name"); + addBooleanParameter(proj, UftConstants.FULL_SCAN_PARAMETER_NAME, false, "Specify whether to synchronize the set of tests on ALM Octane with the whole SCM repository or to update the set of tests on ALM Octane based on the latest commits."); + + //set polling once in two minutes + SCMTrigger scmTrigger = new SCMTrigger("H/2 * * * *");//H/2 * * * * : once in two minutes + proj.addTrigger(scmTrigger); + delayPollingStart(proj, scmTrigger); + addDiscoveryAssignedNode(proj); + addTimestamper(proj); + + //add post-build action - publisher + addUFTTestDetectionPublisherIfNeeded(proj.getPublishersList(), discoveryInfo); + + return proj; + } catch (IOException | ANTLRException e) { + logger.error("Failed to create DiscoveryJob for test runner: " + e.getMessage()); + return null; + } + } + + private static void addUFTTestDetectionPublisherIfNeeded(List publishers, DiscoveryInfo discoveryInfo) { + //add post-build action - publisher + UFTTestDetectionPublisher uftTestDetectionPublisher = null; + for (Object publisher : publishers) { + if (publisher instanceof UFTTestDetectionPublisher) { + uftTestDetectionPublisher = (UFTTestDetectionPublisher) publisher; + } + } + + if (uftTestDetectionPublisher == null) { + uftTestDetectionPublisher = new UFTTestDetectionPublisher(discoveryInfo.getConfigurationId(), discoveryInfo.getWorkspaceId(), discoveryInfo.getScmRepositoryId()); + if(TestingToolType.MBT.equals(discoveryInfo.getTestingToolType())) { + uftTestDetectionPublisher.setTestingToolType(TestingToolType.MBT); + } + publishers.add(uftTestDetectionPublisher); + } + } + + private static void addTimestamper(FreeStyleProject proj) { + try { + Descriptor wrapperDescriptor = Jenkins.getInstanceOrNull().getBuildWrapper("TimestamperBuildWrapper"); + if (wrapperDescriptor != null) { + BuildWrapper wrapper = proj.getBuildWrappersList().get(wrapperDescriptor); + if (wrapper == null) { + wrapper = wrapperDescriptor.newInstance(null, null); + proj.getBuildWrappersList().add(wrapper); + } + + } + } catch (Descriptor.FormException e) { + logger.error("Failed to addTimestamper : " + e.getMessage()); + } + } + + /** + * Delay starting of polling by 5 minutes to allow original clone + * + * @param proj + * @param scmTrigger + */ + private static void delayPollingStart(final FreeStyleProject proj, final SCMTrigger scmTrigger) { + long delayStartPolling = 1000L * 60 * 5;//5 minute + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + scmTrigger.start(proj, false); + } + }, delayStartPolling); + } + + private static ParametersDefinitionProperty getParametersDefinitions(FreeStyleProject proj) throws IOException { + ParametersDefinitionProperty parameters = proj.getProperty(ParametersDefinitionProperty.class); + if (parameters == null) { + parameters = new ParametersDefinitionProperty(new ArrayList<>()); + proj.addProperty(parameters); + } + return parameters; + } + + private static void addConstantParameter(FreeStyleProject proj, String parameterName, String parameterValue, String desc) throws IOException { + ParametersDefinitionProperty parameters = getParametersDefinitions(proj); + if (parameters.getParameterDefinition(parameterName) == null) { + ParameterDefinition param = new ChoiceParameterDefinition(parameterName, new String[]{parameterValue}, desc); + parameters.getParameterDefinitions().add(param); + } + } + + private static void addStringParameter(FreeStyleProject proj, String parameterName, String defaultValue, String desc) throws IOException { + ParametersDefinitionProperty parameters = getParametersDefinitions(proj); + if (parameters.getParameterDefinition(parameterName) == null) { + ParameterDefinition param = new StringParameterDefinition(parameterName, defaultValue, desc); + parameters.getParameterDefinitions().add(param); + } + } + + private static void addBooleanParameter(FreeStyleProject proj, String parameterName, Boolean defaultValue, String desc) throws IOException { + ParametersDefinitionProperty parameters = getParametersDefinitions(proj); + if (parameters.getParameterDefinition(parameterName) == null) { + ParameterDefinition param = new BooleanParameterDefinition(parameterName, defaultValue, desc); + parameters.getParameterDefinitions().add(param); + } + } + + private static void addDiscoveryAssignedNode(FreeStyleProject proj) { + try { + Label joinedLabel = Label.parseExpression(Jenkins.getInstanceOrNull().getSelfLabel() + "||" + Jenkins.getInstanceOrNull().getSelfLabel()); + //why twice Jenkins.getInstance().getSelfLabel()==master? because only one master is not saved in method proj.setAssignedLabel as it is label of Jenkins.getInstance().getSelfLabel() + proj.setAssignedLabel(joinedLabel); + } catch (ANTLRException | IOException e) { + logger.error("Failed to set add DiscoveryAssignedNode : " + e.getMessage()); + } + } + + private static void addExecutionAssignedNode(FreeStyleProject proj) { + Computer[] computers = Jenkins.getInstanceOrNull().getComputers(); + Set labels = new HashSet(); + + //add existing + String assigned = proj.getAssignedLabelString(); + if (assigned != null) { + String[] assignedArr = StringUtils.split(assigned, "||"); + for (String item : assignedArr) { + labels.add(item.trim()); + } + } + + //try to add new + try { + for (Computer computer : computers) { + if (computer instanceof Jenkins.MasterComputer) { + continue; + } + + String label = "" + computer.getNode().getSelfLabel(); + if (label.toLowerCase().contains("uft")) { + label = label.trim(); + Pattern p = Pattern.compile("[^\\w]"); + Matcher m = p.matcher(label); + if (m.find()) { + //if contain non-letter/digit character, wrap with " + label = "\"" + label + "\""; + } + labels.add(label); + } + } + + if (!labels.isEmpty()) { + String joined = StringUtils.join(labels, "||"); + //if there are more than 1 wrapped label (for example : "label 1"), need to wrap it with parentheses + boolean parenthesesRequired = labels.stream().filter(l -> l.startsWith("\"")).count() > 1; + if (parenthesesRequired) { + joined = "(" + joined + ")"; + } + + proj.setAssignedLabel(Label.parseExpression(joined)); + } + + } catch (IOException | ANTLRException e) { + logger.error("Failed to set addExecutionAssignedNode : " + e.getMessage()); + } + } + + public static FreeStyleProject createExecutor(DiscoveryInfo discoveryInfo) { + try { + TestingToolType testingToolType = discoveryInfo.getTestingToolType(); + String exeJobPrefix = TestingToolType.UFT.equals(testingToolType) ? UFT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW : MBT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW; + String projectName = String.format("%s-%s-%s", exeJobPrefix, discoveryInfo.getExecutorId(), discoveryInfo.getExecutorLogicalName().substring(0,5)); + FreeStyleProject proj = createProject(discoveryInfo.getConfigurationId(), projectName); + + proj.setDescription(String.format("This job was created by the OpenText Application Automation Tools plugin for running UFT tests. It is associated with ALM Octane test runner #%s.", + discoveryInfo.getExecutorId())); + + setScmRepository(discoveryInfo.getScmRepository(), discoveryInfo.getScmRepositoryCredentialsId(), proj, true); + addStringParameter(proj, UftConstants.TESTS_TO_RUN_PARAMETER_NAME, "", "Tests to run"); + addStringParameter(proj, UftConstants.CHECKOUT_DIR_PARAMETER_NAME, "${WORKSPACE}\\${CHECKOUT_SUBDIR}", "Shared UFT directory"); + addConstantParameter(proj, UftConstants.TEST_RUNNER_ID_PARAMETER_NAME, discoveryInfo.getExecutorId(), "ALM Octane test runner ID"); + addConstantParameter(proj, UftConstants.TEST_RUNNER_LOGICAL_NAME_PARAMETER_NAME, discoveryInfo.getExecutorLogicalName(), "ALM Octane test runner logical name"); + addStringParameter(proj, SdkConstants.JobParameters.SUITE_ID_PARAMETER_NAME, "", "ALM Octane test suite ID"); + addStringParameter(proj, SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME, "", "The ID of the ALM Octane test suite run to associate with the test run results."); + + addExecutionAssignedNode(proj); + addTimestamper(proj); + addConcurrentBuildFlag(proj); + + //add build action + TestsToRunFramework framework = TestingToolType.UFT.equals(testingToolType) ? TestsToRunFramework.MF_UFT : TestsToRunFramework.MF_MBT; + Builder converterBuilder = new TestsToRunConverterBuilder(framework.value()); // uft or mbt converter + Builder uftRunner = new RunFromFileBuilder("${testsToRunConverted}"); + boolean isMbt = testingToolType.equals(TestingToolType.MBT); + // add steps to project + proj.getBuildersList().add(converterBuilder); + proj.getBuildersList().add(uftRunner); + if(isMbt) { // in case of mbt, add a second runner for codeless + proj.getBuildersList().add(new RunFromCodelessBuilder()); + } + + //add post-build action - publisher + RunResultRecorder runResultRecorder = null; + List publishers = proj.getPublishersList(); + for (Object publisher : publishers) { + if (publisher instanceof RunResultRecorder) { + runResultRecorder = (RunResultRecorder) publisher; + } + } + if (runResultRecorder == null) { + runResultRecorder = new RunResultRecorder(ResultsPublisherModel.alwaysArchiveResults.getValue()); + publishers.add(runResultRecorder); + } + return proj; + } catch (IOException e) { + logger.error("Failed to create executor job : " + e.getMessage()); + return null; + } + } + + private static void addConcurrentBuildFlag(FreeStyleProject proj) throws IOException { + proj.setConcurrentBuild(true); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/TriggeredByOctanePlugin.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/TriggeredByOctanePlugin.java new file mode 100644 index 0000000000..d438765240 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/TriggeredByOctanePlugin.java @@ -0,0 +1,58 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import hudson.model.Cause; + +/** + * Representing job trigger by Octane plugin + */ +public class TriggeredByOctanePlugin extends Cause { + + String identifier; + String identifierType; + + public TriggeredByOctanePlugin(String identifierType, String identifier) { + this.identifier = identifier; + this.identifierType = identifierType; + } + + public static TriggeredByOctanePlugin create(String identifierType, String identifier) { + return new TriggeredByOctanePlugin(identifierType, identifier); + } + + @Override + public String getShortDescription() { + return String.format("Triggered by ALM Octane plugin for %s #%s ", identifierType, identifier); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionCallable.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionCallable.java new file mode 100644 index 0000000000..be75f09641 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionCallable.java @@ -0,0 +1,255 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.hp.octane.integrations.uft.UftTestDiscoveryUtils; +import com.hp.octane.integrations.uft.items.UftTestDiscoveryResult; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.model.ParameterValue; +import hudson.model.ParametersAction; +import hudson.remoting.VirtualChannel; +import hudson.scm.ChangeLogSet; +import hudson.scm.EditType; +import jenkins.MasterToSlaveFileCallable; +import org.apache.commons.lang.reflect.FieldUtils; +import org.jenkinsci.remoting.RoleChecker; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * used to start UFTTestDetectionService.startScanning on slave machine + */ +public class UFTTestDetectionCallable extends MasterToSlaveFileCallable { + private String configurationId; + private String workspaceId; + private String scmRepositoryId; + private BuildListener buildListener; + private TestingToolType testingToolType; + private String testRunnerId; + private boolean fullScan = false; + private ScmChangesWrapper scmChangesWrapper; + + public UFTTestDetectionCallable(AbstractBuild build, String configurationId, String workspaceId, String scmRepositoryId, BuildListener buildListener, TestingToolType testingToolType) { + this.configurationId = configurationId; + this.workspaceId = workspaceId; + this.scmRepositoryId = scmRepositoryId; + this.buildListener = buildListener; + this.testingToolType = testingToolType == null || TestingToolType.UNKNOWN.equals(testingToolType) ? TestingToolType.UFT : testingToolType; + + extractParameterValues(build); + wrapScmChanges(build); + + } + + private void extractParameterValues(AbstractBuild build) { + ParametersAction parameterAction = build.getAction(ParametersAction.class); + if (parameterAction != null) { + ParameterValue testRunnerParameter = parameterAction.getParameter(UftConstants.TEST_RUNNER_ID_PARAMETER_NAME); + if (testRunnerParameter != null && testRunnerParameter.getValue() instanceof String) { + testRunnerId = ((String) testRunnerParameter.getValue()); + } + + + ParameterValue parameterValue = parameterAction.getParameter(UftConstants.FULL_SCAN_PARAMETER_NAME); + if (parameterValue != null) { + fullScan = (Boolean) parameterValue.getValue(); + } + if (!fullScan) { + fullScan = build.getId().equals("1"); + } + } + } + + private void wrapScmChanges(AbstractBuild build) { + ChangeLogSet buildChangeSet = build.getChangeSet(); + switch (buildChangeSet.getClass().getName()) { + case "hudson.plugins.git.GitChangeSetList": + scmChangesWrapper = new ScmChangesWrapper(SCMType.GIT); + break; + case "hudson.scm.SubversionChangeLogSet": + scmChangesWrapper = new ScmChangesWrapper(SCMType.SVN); + break; + default: + } + if (scmChangesWrapper != null) { + Object[] changeSetItems = build.getChangeSet().getItems(); + for (int i = 0; i < changeSetItems.length; i++) { + ChangeLogSet.Entry changeSet = (ChangeLogSet.Entry) changeSetItems[i]; + for (ChangeLogSet.AffectedFile affectedFileChange : changeSet.getAffectedFiles()) { + + //compute edit type + ScmChangeEditTypeWrapper editType; + if (affectedFileChange.getEditType().equals(EditType.ADD)) { + editType = ScmChangeEditTypeWrapper.ADD; + } else if (affectedFileChange.getEditType().equals(EditType.DELETE)) { + editType = ScmChangeEditTypeWrapper.DELETE; + } else if (affectedFileChange.getEditType().equals(EditType.EDIT)) { + editType = ScmChangeEditTypeWrapper.EDIT; + } else { + throw new IllegalArgumentException("Not expected value : " + affectedFileChange.getEditType()); + } + + ScmChangeAffectedFileWrapper fileWrapper = new ScmChangeAffectedFileWrapper(affectedFileChange.getPath(), editType); + + //compute fields related to scm type + if (scmChangesWrapper.getScmType().equals(SCMType.GIT)) { + fileWrapper.setGitDst(getGitDestination(affectedFileChange)); + fileWrapper.setGitSrc(getGitSource(affectedFileChange)); + } else if (scmChangesWrapper.getScmType().equals(SCMType.SVN)) { + fileWrapper.setSvnDirType(isSvnDir(affectedFileChange)); + } + + if(fileWrapper.isSvnDirType()|| + UftTestDiscoveryUtils.isTestMainFilePath(fileWrapper.getPath())|| + (TestingToolType.UFT.equals(testingToolType) && UftTestDiscoveryUtils.isUftDataTableFile(fileWrapper.getPath())) || + (TestingToolType.MBT.equals(testingToolType) && UftTestDiscoveryUtils.isUftActionFile(fileWrapper.getPath()))){ + //add to list + scmChangesWrapper.getAffectedFiles().add(fileWrapper); + } + } + } + } + } + + @Override + public UftTestDiscoveryResult invoke(File file, VirtualChannel virtualChannel) { + UftTestDiscoveryResult results = UFTTestDetectionService.startScanning(file, buildListener, configurationId, workspaceId, scmRepositoryId, testRunnerId, scmChangesWrapper, fullScan, testingToolType); + return results; + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + //no need to check roles as this can be run on master and on slave + } + + private static boolean isSvnDir(ChangeLogSet.AffectedFile path) { + //ONLY for SVN plugin : Check if path is directory + try { + String value = (String) FieldUtils.readDeclaredField(path, "kind", true); + return "dir".equals(value); + } catch (Exception e) { + return false; + } + } + + private static String getGitDestination(ChangeLogSet.AffectedFile path) { + try { + return (String) FieldUtils.readDeclaredField(path, "dst", true); + } catch (Exception e) { + return null; + } + } + + private static String getGitSource(ChangeLogSet.AffectedFile path) { + try { + return (String) FieldUtils.readDeclaredField(path, "src", true); + } catch (Exception e) { + return null; + } + } + + public static class ScmChangesWrapper implements Serializable { + private SCMType scmType; + private List affectedFiles = new ArrayList<>(); + + public ScmChangesWrapper(SCMType scmType) { + this.scmType = scmType; + } + + public SCMType getScmType() { + return scmType; + } + + public List getAffectedFiles() { + return affectedFiles; + } + } + + public enum ScmChangeEditTypeWrapper implements Serializable { + ADD, EDIT, DELETE + } + + public static class ScmChangeAffectedFileWrapper implements Serializable { + + private String path; + + private ScmChangeEditTypeWrapper editType; + private String gitSrc; + private String gitDst; + private boolean svnDirType; + + + public ScmChangeAffectedFileWrapper(String path, ScmChangeEditTypeWrapper editType) { + this.path = path; + this.editType = editType; + } + + public String getPath() { + return path; + } + + public ScmChangeEditTypeWrapper getEditType() { + return editType; + } + + public String getGitDst() { + return gitDst; + } + + public String getGitSrc() { + return gitSrc; + } + + public boolean isSvnDirType() { + return svnDirType; + } + + public void setGitSrc(String gitSrc) { + this.gitSrc = gitSrc; + } + + public void setGitDst(String gitDst) { + this.gitDst = gitDst; + } + + public void setSvnDirType(boolean svnDirType) { + this.svnDirType = svnDirType; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionFinalResultSaverCallable.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionFinalResultSaverCallable.java new file mode 100644 index 0000000000..aa2df03e07 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionFinalResultSaverCallable.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.uft.items.UftTestDiscoveryResult; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.remoting.RoleChecker; + +import java.io.File; +import java.io.IOException; + +/** + * used to save final UFTTestDetection results in slave machine workspace + */ +public class UFTTestDetectionFinalResultSaverCallable extends MasterToSlaveFileCallable { + private UftTestDiscoveryResult results; + private int buildNumber; + + private static final Logger logger = SDKBasedLoggerProvider.getLogger(UFTTestDetectionFinalResultSaverCallable.class); + + public UFTTestDetectionFinalResultSaverCallable(UftTestDiscoveryResult results, int buildNumber) { + this.results = results; + this.buildNumber = buildNumber; + } + + @Override + public String invoke(File file, VirtualChannel virtualChannel) { + //publish final results + File subWorkspace = new File(file, "_Final_Detection_Results"); + try { + if (!subWorkspace.exists()) { + subWorkspace.mkdirs(); + } + File reportXmlFile = new File(subWorkspace, "final_detection_result_build_" + buildNumber + ".json"); + results.writeToFile(reportXmlFile); + } catch (IOException e) { + logger.error("Failed to write final_detection_result file :" + e.getMessage()); + } + + return null; + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + //no need to check roles as this can be run on master and on slave + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionService.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionService.java new file mode 100644 index 0000000000..c3d6b2193c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UFTTestDetectionService.java @@ -0,0 +1,405 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.CIPluginServices; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.services.configurationparameters.factory.ConfigurationParameterFactory; +import com.hp.octane.integrations.uft.UftTestDiscoveryUtils; +import com.hp.octane.integrations.uft.items.*; +import com.hp.octane.integrations.utils.SdkConstants; +import com.hp.octane.integrations.utils.SdkStringUtils; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.FilePath; +import hudson.model.BuildListener; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * Service is responsible to detect changes according to SCM change and to put it to queue of UftTestDiscoveryDispatcher + */ +public class UFTTestDetectionService { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(UFTTestDetectionService.class); + private static final String INITIAL_DETECTION_FILE = "INITIAL_DETECTION_FILE.txt"; + private static final String DETECTION_RESULT_FILE = "detection_result.json"; + + public static UftTestDiscoveryResult startScanning(File rootDir, BuildListener buildListener, String configurationId, String workspaceId, String scmRepositoryId, + String testRunnerId, UFTTestDetectionCallable.ScmChangesWrapper scmChangesWrapper, boolean fullScan, TestingToolType testingToolType) { + UftTestDiscoveryResult result = null; + try { + + boolean myFullScan = fullScan || !initialDetectionFileExist(rootDir); + if (myFullScan) { + printToConsole(buildListener, "Executing full sync"); + // only full scan flow is supported in MBT + result = UftTestDiscoveryUtils.doFullDiscovery(rootDir, testingToolType); + } else { + printToConsole(buildListener, "Executing changeSet sync. For full sync - define in job boolean parameter 'Full sync' with value 'true'."); + result = doChangeSetDetection(scmChangesWrapper, rootDir, testingToolType, configurationId); + removeTestDuplicatedForUpdateTests(result); + removeFalsePositiveDataTables(result, result.getDeletedTests(), result.getDeletedScmResourceFiles()); + removeFalsePositiveDataTables(result, result.getNewTests(), result.getNewScmResourceFiles()); + } + + printResults(buildListener, result); + + if (result.isHasQuotedPaths()) { + printToConsole(buildListener, "This run may not have discovered all updated tests. \n" + + "It seems that the changes in this build included filenames with Unicode characters, which Git did not list correctly.\n" + + "To make sure Git can properly list such file names, configure Git as follows : git config --global core.quotepath false\n" + + "To discover the updated tests that were missed in this run and send them to ALM Octane, run this job manually with the \"Full sync\" parameter selected.\n"); + } + + result.setScmRepositoryId(scmRepositoryId); + result.setConfigurationId(configurationId); + result.setWorkspaceId(workspaceId); + result.setFullScan(fullScan); + + //we add test runner only for discovery jobs that were created for test runners + if (testRunnerId != null) { + result.setTestRunnerId(testRunnerId); + } + + result.sortItems(); + createInitialDetectionFile(rootDir); + + } catch (Exception e) { + logger.error("Fail in startScanning : " + e.getMessage(), e); + } + + return result; + } + + private static void printResults(BuildListener buildListener, UftTestDiscoveryResult result) { + if (TestingToolType.UFT.equals(result.getTestingToolType())) { + // print tables + printByStatus(buildListener, result.getAllTests(), "Found %s tests with status %s"); + // print data tables + printByStatus(buildListener, result.getAllScmResourceFiles(), "Found %s data tables with status %s"); + } else { + // flatten action lists + List actions = result.getAllTests().stream() + .map(AutomatedTest::getActions) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + // print actions + printByStatus(buildListener, actions, "Found %s actions with status %s"); + + // flatten parameters + List parameters = actions.stream() + .filter(action -> !action.getParameters().isEmpty()) + .map(action -> action.getParameters()) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + // print parameters + printByStatus(buildListener, parameters, "Found %s parameters with status %s"); + } + } + + private static void printByStatus(BuildListener buildListener, List entities, String messageTemplate) { + Map testStatusMap = computeStatusMap(entities); + for (Map.Entry entry : testStatusMap.entrySet()) { + printToConsole(buildListener, String.format(messageTemplate, entry.getValue(), entry.getKey())); + } + } + + private static Map computeStatusMap(List entities) { + Map statusMap = new HashMap<>(); + for (SupportsOctaneStatus item : entities) { + if (!statusMap.containsKey(item.getOctaneStatus())) { + statusMap.put(item.getOctaneStatus(), 0); + } + statusMap.put(item.getOctaneStatus(), statusMap.get(item.getOctaneStatus()) + 1); + } + return statusMap; + } + + /** + * Deleted data table might be part of deleted test. During discovery its very hard to know. + * Here we pass through all deleted data tables, if we found data table parent is test folder - we know that the delete was part of test delete + * + * @param tests + * @param scmResourceFiles + */ + private static void removeFalsePositiveDataTables(UftTestDiscoveryResult result, List tests, List scmResourceFiles) { + if (!scmResourceFiles.isEmpty() && !tests.isEmpty()) { + + List falsePositive = new ArrayList<>(); + for (ScmResourceFile item : scmResourceFiles) { + int parentSplitterIndex = item.getRelativePath().lastIndexOf(SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER); + if (parentSplitterIndex != -1) { + String parentName = item.getRelativePath().substring(0, parentSplitterIndex); + for (AutomatedTest test : tests) { + String testPath = SdkStringUtils.isEmpty(test.getPackage()) ? test.getName() : test.getPackage() + SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER + test.getName(); + if (parentName.contains(testPath)) { + falsePositive.add(item); + break; + } + } + } + } + + result.getAllScmResourceFiles().removeAll(falsePositive); + } + } + + private static void removeTestDuplicatedForUpdateTests(UftTestDiscoveryResult result) { + Set keys = new HashSet<>(); + List testsToRemove = new ArrayList<>(); + for (AutomatedTest test : result.getUpdatedTests()) { + String key = test.getPackage() + "_" + test.getName(); + if (keys.contains(key)) { + testsToRemove.add(test); + } + keys.add(key); + + } + result.getAllTests().removeAll(testsToRemove); + } + + public static void printToConsole(BuildListener buildListener, String msg) { + if (buildListener != null) { + buildListener.getLogger().println("UFTTestDetectionService : " + msg); + } + } + + private static UftTestDiscoveryResult doChangeSetDetection(UFTTestDetectionCallable.ScmChangesWrapper scmChangesWrapper, File workspace, TestingToolType testingToolType,String configurationId) { + UftTestDiscoveryResult result = new UftTestDiscoveryResult(); + result.setTestingToolType(testingToolType); + scmChangesWrapper.getAffectedFiles().sort(Comparator.comparing(UFTTestDetectionCallable.ScmChangeAffectedFileWrapper::getPath)); + List dataTableAffectFiles = new LinkedList<>(); + for (UFTTestDetectionCallable.ScmChangeAffectedFileWrapper affectedFileWrapper : scmChangesWrapper.getAffectedFiles()) { + if (affectedFileWrapper.getPath().startsWith("\"")) { + result.setHasQuotedPaths(true); + } + String affectedFileFullPath = workspace + File.separator + affectedFileWrapper.getPath(); + if (!affectedFileWrapper.isSvnDirType()) { + if (UftTestDiscoveryUtils.isTestMainFilePath(affectedFileWrapper.getPath())) { + handleUftTestChanges(workspace, testingToolType, result, affectedFileWrapper, affectedFileFullPath); + } else if (TestingToolType.UFT.equals(testingToolType) && UftTestDiscoveryUtils.isUftDataTableFile(affectedFileWrapper.getPath())) { + handleUftDataTableChanges(workspace, result, affectedFileWrapper, affectedFileFullPath, dataTableAffectFiles); + } else if (TestingToolType.MBT.equals(testingToolType) && UftTestDiscoveryUtils.isUftActionFile(affectedFileWrapper.getPath())) { + handleUftActionChanges(workspace, result, affectedFileWrapper, affectedFileFullPath); + } + } else if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.DELETE.equals(affectedFileWrapper.getEditType())) { //isDir + FilePath filePath = new FilePath(new File(affectedFileWrapper.getPath())); + String deletedFolder = filePath.getRemote().replace(SdkConstants.FileSystem.LINUX_PATH_SPLITTER, SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER); + result.getDeletedFolders().add(deletedFolder); + } + } + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(configurationId); + if (ConfigurationParameterFactory.isUftTestsDeepRenameCheckEnabled(octaneClient.getConfigurationService().getConfiguration())) { + createDataTableHashCodeToTestPath(dataTableAffectFiles, result); + } + return result; + } + + private static void createDataTableHashCodeToTestPath( List dataTableAffectFiles, UftTestDiscoveryResult result) { + Map> combineDataTableHashCodeToTests = new HashMap<>(); + for (AutomatedTest test : result.getAllTests()) { + String testPath = test.getPackage() + "\\" + test.getName(); + String finalTestPath = testPath.replace("\\", "/"); + + + String allDataTableEffected = dataTableAffectFiles.stream().filter(dataTableAffectFile ->dataTableAffectFile.getPath().indexOf(finalTestPath) == 0) + .map(dataTableAffectFile -> dataTableAffectFile.getPath().substring(finalTestPath.length() + 1) + ":" + dataTableAffectFile.getGitDst()) + .collect(Collectors.joining("-")); + + combineDataTableHashCodeToTests.computeIfAbsent(convertToHashCode(allDataTableEffected).toString(),k-> new LinkedList<>()).add(testPath); + } + result.setCombineDataTableHashCodeToTestPathListMap(combineDataTableHashCodeToTests); + } + + + + private static StringBuilder convertToHashCode(String key) { + StringBuilder sb = new StringBuilder(); + StringBuilder returnString = new StringBuilder(); + returnString.append(key); + + try { + byte[] keyByteUTF8 = key.getBytes(StandardCharsets.UTF_8); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + + md.update(keyByteUTF8, 0, keyByteUTF8.length); + byte[] mdbytes = md.digest(); + + //convert the byte to hex format + for (int i = 0; i < mdbytes.length; i++) { + sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); + } + + } catch (Exception e) { + logger.error("failed to calculate hash code: "+ e.getMessage()); + } + if (sb.length() > 0) + return sb; + else + return returnString; + } + + + private static void handleUftTestChanges(File workspace, + TestingToolType testingToolType, + UftTestDiscoveryResult result, + UFTTestDetectionCallable.ScmChangeAffectedFileWrapper affectedFileWrapper, + String affectedFileFullPath) { + + File testFolder = UftTestDiscoveryUtils.getTestFolderForTestMainFile(affectedFileFullPath); + File affectedFile = new File(affectedFileFullPath); + boolean fileExist = affectedFile.exists(); + UftTestType uftTestType = UftTestDiscoveryUtils.getUftTestType(affectedFileWrapper.getPath()); + + AutomatedTest test = UftTestDiscoveryUtils.createAutomatedTest(workspace, testFolder, uftTestType, testingToolType); + test.setChangeSetSrc(affectedFileWrapper.getGitSrc()); + test.setChangeSetDst(affectedFileWrapper.getGitDst()); + + if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.ADD.equals(affectedFileWrapper.getEditType())) { + if (fileExist) { // uft and mbt behave the same + result.getAllTests().add(test); + } + } else if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.DELETE.equals(affectedFileWrapper.getEditType())) { + if (!fileExist) { + test.setOctaneStatus(OctaneStatus.DELETED); + test.setExecutable(false); + result.getAllTests().add(test); + } + } else if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.EDIT.equals(affectedFileWrapper.getEditType())) { + if (fileExist) { + test.setOctaneStatus(OctaneStatus.MODIFIED); + result.getAllTests().add(test); + } + } + } + + private static void handleUftDataTableChanges(File workspace, + UftTestDiscoveryResult result, + UFTTestDetectionCallable.ScmChangeAffectedFileWrapper affectedFileWrapper, + String affectedFileFullPath, + List dataTableAffectFiles) { + dataTableAffectFiles.add(affectedFileWrapper); + File affectedFile = new File(affectedFileFullPath); + ScmResourceFile resourceFile = UftTestDiscoveryUtils.createDataTable(workspace, affectedFile); + resourceFile.setChangeSetSrc(affectedFileWrapper.getGitSrc()); + resourceFile.setChangeSetDst(affectedFileWrapper.getGitDst()); + + if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.ADD.equals(affectedFileWrapper.getEditType())) { + UftTestType testType = UftTestDiscoveryUtils.isUftTestFolder(affectedFile.getParentFile().listFiles()); + if (testType.isNone()) { + if (affectedFile.exists()) { + result.getAllScmResourceFiles().add(resourceFile); + } + } + } else if (UFTTestDetectionCallable.ScmChangeEditTypeWrapper.DELETE.equals(affectedFileWrapper.getEditType())) { + if (!affectedFile.exists()) { + resourceFile.setOctaneStatus(OctaneStatus.DELETED); + result.getAllScmResourceFiles().add(resourceFile); + } + } + } + + private static void handleUftActionChanges(File workspace, UftTestDiscoveryResult result, UFTTestDetectionCallable.ScmChangeAffectedFileWrapper affectedFileWrapper, String affectedFileFullPath) { + // currently do nothing. to be implemented + } + + private static boolean initialDetectionFileExist(File rootFile) { + try { + File file = new File(rootFile, INITIAL_DETECTION_FILE); + return file.exists(); + + } catch (Exception e) { + return false; + } + } + + private static void createInitialDetectionFile(File rootFile) { + try { + File file = new File(rootFile, INITIAL_DETECTION_FILE); + logger.info("Initial detection file path : " + file.getPath()); + file.createNewFile(); + } catch (IOException e) { + logger.error("Failed to createInitialDetectionFile : " + e.getMessage()); + } + } + + /** + * Serialize detectionResult to file in XML format + * + * @param run + * @param taskListenerLog + * @param detectionResult + */ + public static void publishDetectionResults(Run run, TaskListener taskListenerLog, UftTestDiscoveryResult detectionResult) { + + File file = getDetectionResultFile(run); + try { + detectionResult.writeToFile(file); + } catch (Exception e) { + String msg = "Failed to persist detection results : " + e.getMessage(); + if (taskListenerLog != null) { + taskListenerLog.error(msg); + } + logger.error(msg); + } + } + + public static UftTestDiscoveryResult readDetectionResults(Run run) { + File file = getDetectionResultFile(run); + + try { + return UftTestDiscoveryResult.readFromFile(file); + } catch (IOException e) { + logger.error("Failed to read detection results : " + e.getMessage()); + return null; + } + } + + public static File getDetectionResultFile(Run run) { + return new File(run.getRootDir(), DETECTION_RESULT_FILE); + } + +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftConstants.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftConstants.java new file mode 100644 index 0000000000..72cb4b30d0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftConstants.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; + +/** + * Constants for UFT executors jobs + */ +public class UftConstants { + + public static final String BUILD_ID_PARAMETER_NAME = "buildId"; + public static final String FULL_SCAN_PARAMETER_NAME = "Full sync"; + + + public static final String TESTS_TO_RUN_PARAMETER_NAME = "testsToRun"; + public static final String CHECKOUT_DIR_PARAMETER_NAME = "testsToRunCheckoutDirectory"; + public static final String TEST_RUNNER_ID_PARAMETER_NAME = "Test Runner ID"; + public static final String TEST_RUNNER_LOGICAL_NAME_PARAMETER_NAME = "Test Runner logical name"; + + public static final String DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS = "UFT-test-discovery-job-Test-Runner-ID"; + public static final String EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS = "UFT-test-execution-job-Test-Runner-ID"; + + public static final String DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE = "%s-discovery-job"; + public static final String UFT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW = String.format(DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE, TestingToolType.UFT); + public static final String MBT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW = String.format(DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE, TestingToolType.MBT); + public static final String EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE = "%s-test-runner"; + public static final String UFT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW = String.format(EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE, TestingToolType.UFT); + public static final String MBT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW = String.format(EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_TEMPLATE, TestingToolType.MBT); + + public static final String NO_USERNAME_DEFINED = "No username defined in Jenkins Configure System page"; + public static final String NO_CLIENT_ID_DEFINED = "No client ID defined in Jenkins Configure System page"; + + public static final String UFT_CHECKOUT_FOLDER = "UFT_CHECKOUT_FOLDER"; + public static final String CODELESS_FOLDER_TEMPLATE = "codeless_%s"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftJobRecognizer.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftJobRecognizer.java new file mode 100644 index 0000000000..2ed8143ed7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftJobRecognizer.java @@ -0,0 +1,159 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.hp.octane.integrations.utils.CIPluginSDKUtils; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.FreeStyleProject; +import hudson.model.ParameterDefinition; +import hudson.model.ParametersDefinitionProperty; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.List; + + +/*** + * Recognizer for UFT related jobs + */ +public class UftJobRecognizer { + + private static Logger logger = SDKBasedLoggerProvider.getLogger(UftJobRecognizer.class); + + /** + * Check if current job is EXECUTOR job + * + * @param job + * @return + */ + public static boolean isExecutorJob(FreeStyleProject job) { + return (job.getName().startsWith(UftConstants.EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS) || + job.getName().startsWith(UftConstants.UFT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW) || + job.getName().startsWith(UftConstants.MBT_EXECUTION_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW)); + } + + /** + * Check if current job is discovery job + * + * @param job + * @return + */ + public static boolean isDiscoveryJob(FreeStyleProject job) { + return (job.getName().startsWith(UftConstants.DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS) || + job.getName().startsWith(UftConstants.UFT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW) || + job.getName().startsWith(UftConstants.MBT_DISCOVERY_JOB_MIDDLE_NAME_WITH_TEST_RUNNERS_NEW)); + } + + /** + * Extract executor id from the job + * + * @param job + * @return + */ + public static String getExecutorId(FreeStyleProject job) { + ParametersDefinitionProperty parameters = job.getProperty(ParametersDefinitionProperty.class); + ParameterDefinition pd = parameters.getParameterDefinition(UftConstants.TEST_RUNNER_ID_PARAMETER_NAME); + if (pd != null) { + return (String) pd.getDefaultParameterValue().getValue(); + } else { + return null; + } + } + + /** + * Extract executor logical name from the job + * + * @param job + * @return + */ + public static String getExecutorLogicalName(FreeStyleProject job) { + ParametersDefinitionProperty parameters = job.getProperty(ParametersDefinitionProperty.class); + ParameterDefinition pd = parameters.getParameterDefinition(UftConstants.TEST_RUNNER_LOGICAL_NAME_PARAMETER_NAME); + if (pd != null) { + return (String) pd.getDefaultParameterValue().getValue(); + } else { + return null; + } + } + + public static void deleteExecutionJobByExecutorIfNeverExecuted(String executorToDelete) { + List jobs = Jenkins.getInstanceOrNull().getAllItems(FreeStyleProject.class); + for (FreeStyleProject proj : jobs) { + if (UftJobRecognizer.isExecutorJob(proj) && isJobMatchExecutor(executorToDelete, proj) + && proj.getLastBuild() == null && !proj.isBuilding() && !proj.isInQueue()) { + try { + logger.warn(String.format("Job '%s' is going to be deleted since matching executor in Octane was deleted and this job was never executed and has no history.", proj.getName())); + proj.delete(); + } catch (IOException | InterruptedException e) { + logger.error("Failed to delete job " + proj.getName() + " : " + e.getMessage()); + } + } + } + } + + private static Boolean isJobMatchExecutor(String executorToFind, FreeStyleProject proj) { + String executorId = UftJobRecognizer.getExecutorId(proj); + String executorLogicalName = UftJobRecognizer.getExecutorLogicalName(proj); + return (executorId != null && executorId.equals(executorToFind)) || + (executorLogicalName != null && executorLogicalName.equals(executorToFind)); + } + + /** + * Delete discovery job that related to specific executor in Octane + * + * @param executorToDelete + */ + public static void deleteDiscoveryJobByExecutor(String executorToDelete) { + + List jobs = Jenkins.getInstanceOrNull().getAllItems(FreeStyleProject.class); + for (FreeStyleProject proj : jobs) { + if (UftJobRecognizer.isDiscoveryJob(proj) && isJobMatchExecutor(executorToDelete, proj)) { + if (proj.isBuilding()) { + proj.getLastBuild().getExecutor().interrupt(); + CIPluginSDKUtils.doWait(10000); //wait before deleting the job, so Jenkins will be able to complete some IO actions + } else if (proj.isInQueue()) { + Jenkins.getInstanceOrNull().getQueue().cancel(proj); + CIPluginSDKUtils.doWait(10000); //wait before deleting the job, so Jenkins will be able to complete some IO actions + } + + try { + logger.warn(String.format("Job '%s' is going to be deleted since matching executor in Octane was deleted", proj.getName())); + proj.delete(); + } catch (Exception e) { + logger.error("Failed to delete job " + proj.getName() + " : " + e.getMessage()); + } + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryDispatcher.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryDispatcher.java new file mode 100644 index 0000000000..7fca1cf0d7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryDispatcher.java @@ -0,0 +1,233 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.google.inject.Inject; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.exceptions.OctaneRestException; +import com.hp.octane.integrations.services.entities.EntitiesService; +import com.hp.octane.integrations.uft.UftTestDispatchUtils; +import com.hp.octane.integrations.uft.items.JobRunContext; +import com.hp.octane.integrations.uft.items.UftTestDiscoveryResult; +import com.hp.octane.integrations.utils.SdkStringUtils; +import com.microfocus.application.automation.tools.octane.ResultQueue; +import com.microfocus.application.automation.tools.octane.actions.UFTActionDetectionBuildAction; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.AbstractSafeLoggingAsyncPeriodWork; +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.Job; +import hudson.model.TaskListener; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * This class is responsible to send discovered uft tests to Octane. + * Class uses file-based queue so if octane or jenkins will be down before sending, + * after connection is up - this dispatcher will send tests to Octane. + *

+ * Actually list of discovered tests are persisted in job run directory. Queue contains only reference to that job run. + */ +@Extension +public class UftTestDiscoveryDispatcher extends AbstractSafeLoggingAsyncPeriodWork { + + private static final Logger logger = SDKBasedLoggerProvider.getLogger(UftTestDiscoveryDispatcher.class); + + private static final int MAX_DISPATCH_TRIALS = 5; + + private UftTestDiscoveryQueue queue; + + private volatile boolean stopped = false; + + public UftTestDiscoveryDispatcher() { + super("Uft Test Discovery Dispatcher"); + } + + private static void dispatchDetectionResults(ResultQueue.QueueItem item, EntitiesService entitiesService, UftTestDiscoveryResult result, AbstractBuild build) { + //Check if there is diff in discovery and server status + //for example : discovery found new test , but it already exist in server , instead of create new tests we will do update test + UftTestDispatchUtils.prepareDiscoveryResultForDispatch(entitiesService, result); + + try { + build.getWorkspace().act(new UFTTestDetectionFinalResultSaverCallable(result, build.getNumber())); + } catch (Exception e) { + logger.info("Failed to save final result : " + e.getMessage()); + } + + //dispatch + JobRunContext jobRunContext = JobRunContext.create(item.getProjectName(), item.getBuildNumber()); + UftTestDispatchUtils.dispatchDiscoveryResult(entitiesService, result, jobRunContext, null); + if (result.getTestingToolType().equals(TestingToolType.MBT)) { + UFTActionDetectionBuildAction action = build.getAction(UFTActionDetectionBuildAction.class); + action.setResults(result); + try { + build.save(); // save build in order to update the discovery report (build.xml in jenkins) + } catch (IOException e) { + logger.info("Failed to save build: " + e.getMessage()); + } + } + } + + @Override + protected void doExecute(TaskListener listener) { + if (stopped) { + return; + } + + if (queue.peekFirst() == null) { + return; + } + + if (OctaneSDK.getClients().isEmpty()) { + logger.warn("There are pending discovered UFT tests, but no Octane configuration is found, results can't be submitted"); + return; + } + + ResultQueue.QueueItem item = null; + try { + while ((item = queue.peekFirst()) != null) { + if (queueContainsPostponedItems(item)) { + logger.warn("Project [" + item.getProjectName() + "] has postpone items"); + //all postponed items are in the end of queue, so it we encountered one postponed item, other postponed items will come after it, so we do break + break; + } + + Job project = (Job) Jenkins.get().getItemByFullName(item.getProjectName()); + if (project == null) { + logger.warn("Project [" + item.getProjectName() + "] no longer exists, pending discovered tests can't be submitted"); + queue.remove(); + continue; + } + + AbstractBuild build = (AbstractBuild) project.getBuildByNumber(item.getBuildNumber()); + if (build == null) { + logger.warn("Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] no longer exists, pending discovered tests can't be submitted"); + queue.remove(); + continue; + } + + UftTestDiscoveryResult result = UFTTestDetectionService.readDetectionResults(build); + if (result == null) { + logger.warn("Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] no longer contains valid detection result file"); + queue.remove(); + continue; + } + + OctaneClient client; + try { + client = OctaneSDK.getClientByInstanceId(result.getConfigurationId()); + } catch (Exception e) { + logger.error("Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] does not have valid configuration " + result.getConfigurationId() + " : " + e.getMessage()); + queue.remove(); + continue; + } + + if (!client.getConfigurationService().isConnected()) { + logger.info(client.getConfigurationService().getConfiguration().getLocationForLog() + + " - Build [" + item.getProjectName() + "#" + item.getBuildNumber() + "] - octane is down , postponing sending UFT tests "); + //if octane is down - put current item to the end of queue and try wth other items (that might be from another octane) + item.setSendAfter(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(1)); + queue.remove(); + queue.add(item); + continue; + } + + logger.warn("Persistence [" + item.getProjectName() + "#" + item.getBuildNumber() + "]"); + dispatchDetectionResults(item, client.getEntitiesService(), result, build); + queue.remove(); + } + } catch (OctaneRestException e) { + String reasonDesc = StringUtils.isNotEmpty(e.getData().getDescriptionTranslated()) ? e.getData().getDescriptionTranslated() : e.getData().getDescription(); + if (e.getResponseStatus() == HttpStatus.SC_FORBIDDEN) { + logger.error("Failed to persist discovery of [" + item.getProjectName() + "#" + item.getBuildNumber() + "] because of lacking Octane permission : " + reasonDesc); + } else { + logger.error("Failed to persist discovery of [" + item.getProjectName() + "#" + item.getBuildNumber() + "] : " + reasonDesc); + } + queue.remove(); + } catch (Exception e) { + if (item != null) { + item.incrementFailCount(); + if (item.incrementFailCount() > MAX_DISPATCH_TRIALS) { + queue.remove(); + logger.error("Failed to persist discovery of [" + item.getProjectName() + "#" + item.getBuildNumber() + "] after " + MAX_DISPATCH_TRIALS + " trials"); + } + } + } + } + + private boolean queueContainsPostponedItems(ResultQueue.QueueItem queueItem) { + if (queueItem.getSendAfter() > 0 && queueItem.getSendAfter() > System.currentTimeMillis()) { + //all postponed items are in the end of queue, so it we encountered one postponed item, other postponed items will come after it, so we do break + return true; + } + return false; + } + + public void close() { + logger.info("stopping the UFT dispatcher and closing its queue"); + stopped = true; + queue.close(); + } + + @Override + public long getRecurrencePeriod() { + String value = System.getProperty("UftTestDiscoveryDispatcher.Period"); // let's us config the recurrence period. default is 30 seconds. + if (!SdkStringUtils.isEmpty(value)) { + return Long.parseLong(value); + } + return TimeUnit.SECONDS.toMillis(30); + } + + @Inject + public void setTestResultQueue(UftTestDiscoveryQueue queue) { + this.queue = queue; + } + + /** + * Queue that current run contains discovered tests + * + * @param projectName jobs name + * @param buildNumber build number + */ + public void enqueueResult(String instanceId, String projectName, int buildNumber, String workspace) { + queue.add(instanceId, projectName, buildNumber, workspace); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryQueue.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryQueue.java new file mode 100644 index 0000000000..450e225c50 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/UftTestDiscoveryQueue.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor; + +import com.microfocus.application.automation.tools.octane.AbstractResultQueueImpl; +import jenkins.model.Jenkins; + +import java.io.File; +import java.io.IOException; + +/** + * Queue for uft test discovery before dispatching + */ +public class UftTestDiscoveryQueue extends AbstractResultQueueImpl { + + public UftTestDiscoveryQueue() throws IOException { + File queueFile = new File(Jenkins.getInstanceOrNull().getRootDir(), "octane-uft-tests-queue.dat"); + init(queueFile); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/GitPluginHandler.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/GitPluginHandler.java new file mode 100644 index 0000000000..76edbf2b95 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/GitPluginHandler.java @@ -0,0 +1,207 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor.scmmanager; + +import com.cloudbees.hudson.plugins.folder.Folder; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.executor.TestConnectivityInfo; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.EnvVars; +import hudson.model.*; +import hudson.plugins.git.*; +import hudson.plugins.git.extensions.GitSCMExtension; +import hudson.plugins.git.extensions.impl.RelativeTargetDirectory; +import hudson.scm.SCM; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.gitclient.Git; +import org.jenkinsci.plugins.gitclient.GitClient; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class GitPluginHandler implements ScmPluginHandler { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(GitPluginHandler.class); + + @Override + public void setScmRepositoryInJob(SCMRepository scmRepository, String scmRepositoryCredentialsId, FreeStyleProject proj, boolean executorJob) throws IOException { + + List repoLists = Collections.singletonList(new UserRemoteConfig(scmRepository.getUrl(), null, null, scmRepositoryCredentialsId)); + List extensions = null; + + if (executorJob) { + String folder = buildRepoFolder(proj); + String repoName = buildRepoName(scmRepository.getUrl()); + String relativeCheckOut = folder + repoName; + RelativeTargetDirectory targetDirectory = new RelativeTargetDirectory(relativeCheckOut); + extensions = Collections.singletonList(targetDirectory); + } + + String branch = "*/master"; + if (proj.getScm() != null && proj.getScm() instanceof GitSCM) { + List branches = ((GitSCM) proj.getScm()).getBranches(); + if (branches.size() > 0) { + String existingBrName = branches.get(0).getName(); + boolean emptyBrName = (existingBrName == null || existingBrName.isEmpty() || existingBrName.equals("**")); + if (!emptyBrName) { + branch = existingBrName; + } + } + } + + GitSCM scm = new GitSCM(repoLists, Collections.singletonList(new BranchSpec(branch)), false, Collections.emptyList(), null, null, extensions); + proj.setScm(scm); + } + + private String buildRepoFolder(FreeStyleProject proj) { + String pathPrefix = "";//its required if job is created in some folder + ItemGroup parent = proj.getParent(); + while (Jenkins.get() != null && !parent.equals(Jenkins.get())) { + pathPrefix += "..\\"; + if (parent instanceof Folder) { + parent = ((Folder) parent).getParent(); + } else { + break; + } + } + return pathPrefix + "..\\..\\_test_sources\\"; + } + + private String buildRepoName(String scmRepoUrl) { + String temp = scmRepoUrl.replaceAll("[<>:\"/\\|?*]", "_").trim(); + String GIT_SUFFIX = ".git"; + String HTTP_PREFIX = "http_"; + String HTTPS_PREFIX = "https_"; + String GIT_PREFIX = "git@"; + + //remove .git from end + if (temp.toLowerCase().endsWith(GIT_SUFFIX)) { + temp = temp.substring(0, temp.length() - GIT_SUFFIX.length()); + } + //remove git_,https_,http_ from beginning + if (temp.toLowerCase().startsWith(GIT_PREFIX)) { + temp = temp.substring(GIT_PREFIX.length()); + } else if (temp.toLowerCase().startsWith(HTTPS_PREFIX)) { + temp = temp.substring(HTTPS_PREFIX.length()); + } else if (temp.toLowerCase().startsWith(HTTP_PREFIX)) { + temp = temp.substring(HTTP_PREFIX.length()); + } + temp = StringUtils.strip(temp, "_"); + + //restrict size by + int CHECK_SIZE = 40; + int SPLIT_SIZE = CHECK_SIZE - 4; + if (temp.length() > CHECK_SIZE) { + String split1 = temp.substring(0, temp.length() - SPLIT_SIZE); + String split2 = temp.substring(temp.length() - SPLIT_SIZE); + temp = "_" + Math.abs(split1.hashCode() % 1000) + split2; + } + return temp; + } + + @Override + public String getSharedCheckOutDirectory(Job j) { + SCM scm = ((AbstractProject) j).getScm(); + + GitSCM gitScm = (GitSCM) scm; + RelativeTargetDirectory sharedCheckOutDirectory = gitScm.getExtensions().get(RelativeTargetDirectory.class); + if (sharedCheckOutDirectory != null) { + return sharedCheckOutDirectory.getRelativeTargetDir(); + } + return null; + } + + @Override + public void checkRepositoryConnectivity(TestConnectivityInfo testConnectivityInfo, StandardCredentials credentials, OctaneResponse result) { + + try { + EnvVars environment = new EnvVars(System.getenv()); + GitClient git = Git.with(TaskListener.NULL, environment).using(GitTool.getDefaultInstallation().getGitExe()).getClient(); + git.addDefaultCredentials(credentials); + git.getHeadRev(testConnectivityInfo.getScmRepository().getUrl(), "HEAD"); + + result.setStatus(HttpStatus.SC_OK); + + } catch (IOException | InterruptedException e) { + logger.error("Failed to connect to git : " + e.getMessage()); + result.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); + result.setBody(e.getMessage()); + } catch (GitException e) { + logger.error("Failed to execute getHeadRev : " + e.getMessage()); + result.setStatus(HttpStatus.SC_NOT_FOUND); + result.setBody(e.getMessage()); + } + + } + + @Override + public String getScmRepositoryUrl(SCM scm) { + return ((GitSCM) scm).getUserRemoteConfigs().get(0).getUrl(); + } + + @Override + public String getScmRepositoryCredentialsId(SCM scm) { + return ((GitSCM) scm).getUserRemoteConfigs().get(0).getCredentialsId(); + } + + @Override + public SCMType getScmType() { + return SCMType.GIT; + } + + @Override + public String tryExtractUrlShortName(String url) { + /* + Use Reg-ex pattern which covers both formats: + git@github.com:MicroFocus/hpaa-octane-dev.git + https://github.houston.softwaregrp.net/Octane/syncx.git + */ + + String patternStr = "^.*[/:](.*/.*)$"; + Pattern pattern = Pattern.compile(patternStr); + Matcher matcher = pattern.matcher(url); + if (matcher.find() && matcher.groupCount() == 1) { + return matcher.group(1); + } else { + return url; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginFactory.java new file mode 100644 index 0000000000..2c4bd1297e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginFactory.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor.scmmanager; + +import com.hp.octane.integrations.dto.scm.SCMType; +import hudson.PluginWrapper; +import jenkins.model.Jenkins; + +public class ScmPluginFactory { + + private static ScmPluginHandler gitPluginHandler = null; + private static ScmPluginHandler svnPluginHandler = null; + + + public static ScmPluginHandler getScmHandler(SCMType scmType) { + if (SCMType.GIT.equals(scmType)) { + if (gitPluginHandler == null) { + gitPluginHandler = new GitPluginHandler(); + } + return gitPluginHandler; + } else if (SCMType.SVN.equals(scmType)) { + if (svnPluginHandler == null) { + svnPluginHandler = new SvnPluginHandler(); + } + return svnPluginHandler; + } + throw new IllegalArgumentException("SCM repository " + scmType + " isn't supported."); + } + + public static ScmPluginHandler getScmHandlerByScmPluginName(String pluginName) { + SCMType scmType = null; + + if ("hudson.plugins.git.GitSCM".equals(pluginName)) { + scmType = SCMType.GIT; + } else if ("hudson.scm.SubversionSCM".equals(pluginName)) { + scmType = SCMType.SVN; + } else { + return null; + } + return getScmHandler(scmType); + } + + public static boolean isPluginInstalled(SCMType scmType) { + String shortName; + if (SCMType.GIT.equals(scmType)) { + shortName = "git"; + } else if (SCMType.SVN.equals(scmType)) { + shortName = "subversion"; + } else { + throw new IllegalArgumentException("SCM repository " + scmType + " isn't supported."); + } + + PluginWrapper plugin = Jenkins.getInstanceOrNull().pluginManager.getPlugin(shortName); + return plugin != null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginHandler.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginHandler.java new file mode 100644 index 0000000000..ac1563a55f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/ScmPluginHandler.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor.scmmanager; + +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.executor.TestConnectivityInfo; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import hudson.model.FreeStyleProject; +import hudson.model.Job; +import hudson.scm.SCM; + +import java.io.IOException; + +public interface ScmPluginHandler { + + void setScmRepositoryInJob(SCMRepository scmRepository, String scmRepositoryCredentialsId, FreeStyleProject proj, boolean executorJob) throws IOException; + + String getSharedCheckOutDirectory(Job j); + + void checkRepositoryConnectivity(TestConnectivityInfo testConnectivityInfo, StandardCredentials credentials, OctaneResponse result); + + String getScmRepositoryUrl(SCM scm); + + String getScmRepositoryCredentialsId(SCM scm); + + SCMType getScmType(); + + String tryExtractUrlShortName(String url); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/SvnPluginHandler.java b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/SvnPluginHandler.java new file mode 100644 index 0000000000..e3de7946d5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/executor/scmmanager/SvnPluginHandler.java @@ -0,0 +1,118 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.executor.scmmanager; + +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.hp.octane.integrations.dto.connectivity.OctaneResponse; +import com.hp.octane.integrations.dto.executor.TestConnectivityInfo; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import hudson.model.FreeStyleProject; +import hudson.model.Item; +import hudson.model.Job; +import hudson.scm.SCM; +import hudson.scm.SubversionSCM; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.tmatesoft.svn.core.SVNException; + +import java.io.File; +import java.io.IOException; + +public class SvnPluginHandler implements ScmPluginHandler { + + @Override + public void setScmRepositoryInJob(SCMRepository scmRepository, String scmRepositoryCredentialsId, FreeStyleProject proj, boolean executorJob) throws IOException { + + String relativeCheckOut; + if (executorJob) { + String url = StringUtils.stripEnd(scmRepository.getUrl(), "/").replaceAll("[<>:\"/\\|?*]", "_"); + relativeCheckOut = "a\\..\\..\\..\\_test_sources\\" + url; + } else { + relativeCheckOut = "a" + File.separator + "..";//it doesn't has any affect on checkout folder. Without it, svn do checkout to folder of svn repository name + //for example for URL https://myd-vm00812.hpeswlab.net/svn/uft_tests/ - tests will be cloned to "uft_tests" subfolder + //adding a\.. will clone as is - Why we need it - subfolder is part of "package" reported to Octane + } + + SubversionSCM svn = new SubversionSCM(scmRepository.getUrl(), scmRepositoryCredentialsId, relativeCheckOut); + proj.setScm(svn); + } + + @Override + public String getSharedCheckOutDirectory(Job j) { + SCM scm = ((FreeStyleProject) j).getScm(); + + SubversionSCM svnScm = (SubversionSCM) scm; + for (SubversionSCM.ModuleLocation location : svnScm.getLocations()) { + if (StringUtils.isNotEmpty(location.getLocalDir())) { + return location.getLocalDir(); + } + } + + return null; + } + + @Override + public void checkRepositoryConnectivity(TestConnectivityInfo testConnectivityInfo, StandardCredentials credentials, OctaneResponse result) { + + String credentialsId = (credentials != null ? credentials.getId() : null); + SubversionSCM svn = new SubversionSCM(testConnectivityInfo.getScmRepository().getUrl(), credentialsId); + try { + svn.getDescriptor().checkRepositoryPath((Item) null, svn.getLocations()[0].getSVNURL(), credentials); + result.setStatus(HttpStatus.SC_OK); + } catch (Exception e) { + result.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); + result.setBody("Failed to connect to SVN : " + e.getMessage()); + } + } + + @Override + public String getScmRepositoryUrl(SCM scm) { + return ((SubversionSCM) scm).getLocations()[0].remote; + } + + @Override + public String getScmRepositoryCredentialsId(SCM scm) { + return ((SubversionSCM) scm).getLocations()[0].credentialsId; + } + + @Override + public SCMType getScmType() { + return SCMType.SVN; + } + + @Override + public String tryExtractUrlShortName(String url) { + return url; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/CIEventCausesFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/CIEventCausesFactory.java new file mode 100644 index 0000000000..0ee99408ba --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/CIEventCausesFactory.java @@ -0,0 +1,232 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.causes.CIEventCause; +import com.hp.octane.integrations.dto.causes.CIEventCauseType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.Cause; +import hudson.model.InvisibleAction; +import hudson.model.Run; +import hudson.triggers.SCMTrigger; +import hudson.triggers.TimerTrigger; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.actions.LabelAction; +import org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode; +import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode; +import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.jenkinsci.plugins.workflow.steps.StepDescriptor; + +import java.io.IOException; +import java.util.*; + +/** + * Causes Factory is a collection of static stateless methods to extract/traverse/transform causes chains of the runs + * User: gullery + * Date: 20/10/14 + */ + +public final class CIEventCausesFactory { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(CIEventCausesFactory.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + private CIEventCausesFactory() { + } + + public static List processCauses(Run run) { + if (run == null) { + throw new IllegalArgumentException("run MUST NOT be null"); + } + + Map result = new LinkedHashMap();//LinkedHashMap - save order of insertion + List causes = run.getCauses(); + CIEventCause tmpResultCause; + Cause.UserIdCause tmpUserCause; + Cause.UpstreamCause tmpUpstreamCause; + + for (Cause cause : causes) { + tmpResultCause = dtoFactory.newDTO(CIEventCause.class); + if (cause instanceof SCMTrigger.SCMTriggerCause) { + tmpResultCause.setType(CIEventCauseType.SCM); + result.put(tmpResultCause.generateKey(), tmpResultCause); + } else if (cause instanceof TimerTrigger.TimerTriggerCause) { + tmpResultCause.setType(CIEventCauseType.TIMER); + result.put(tmpResultCause.generateKey(), tmpResultCause); + } else if (cause instanceof Cause.UserIdCause) { + tmpUserCause = (Cause.UserIdCause) cause; + tmpResultCause.setType(CIEventCauseType.USER); + tmpResultCause.setUser(tmpUserCause.getUserId()); + result.put(tmpResultCause.generateKey(), tmpResultCause); + } else if (cause instanceof Cause.UpstreamCause) { + if("RebuildCause".equals(cause.getClass().getSimpleName())){ + continue;//rebuild reason have upstream of previous build - its confusing octane.(Part of rebuild plugin) + } + tmpUpstreamCause = (Cause.UpstreamCause) cause; + + boolean succeededToBuildFlowCauses = false; + Run upstreamRun = tmpUpstreamCause.getUpstreamRun(); + if (upstreamRun != null && JobProcessorFactory.WORKFLOW_RUN_NAME.equals(upstreamRun.getClass().getName())) { + + // for the child of the Workflow - break aside and calculate the causes chain of the stages + WorkflowRun rootWFRun = (WorkflowRun) upstreamRun; + if (rootWFRun.getExecution() != null && rootWFRun.getExecution().getCurrentHeads() != null) { + FlowNode enclosingNode = lookupJobEnclosingNode(run, rootWFRun); + if (enclosingNode != null) { + List flowCauses = processCauses(enclosingNode); + flowCauses.forEach(fc -> result.put(fc.generateKey(), fc)); + succeededToBuildFlowCauses = true; + } + } + } + + if (upstreamRun != null && !succeededToBuildFlowCauses) { + // proceed with regular UPSTREAM calculation logic as usual + tmpResultCause.setType(CIEventCauseType.UPSTREAM); + tmpResultCause.setProject(resolveJobCiId(tmpUpstreamCause.getUpstreamProject())); + tmpResultCause.setBuildCiId(String.valueOf(tmpUpstreamCause.getUpstreamBuild())); + tmpResultCause.setCauses(processCauses(upstreamRun)); + result.put(tmpResultCause.generateKey(), tmpResultCause); + } + } else { // TODO: add support to Cause.RemoteCause execution in SDK/DTOs/Octane + tmpResultCause.setType(CIEventCauseType.UNDEFINED); + result.put(tmpResultCause.generateKey(), tmpResultCause); + } + } + return new ArrayList<>(result.values()); + } + + public static List processCauses(FlowNode flowNode) { + List causes = new LinkedList<>(); + processCauses(flowNode, causes, new LinkedHashSet<>(),new HashSet<>()); + return causes; + } + + private static void processCauses(FlowNode flowNode, List causes, Set startStagesToSkip,Set visitedParents) { + // we reached the start of the flow - add WorkflowRun as an initial UPSTREAM cause + if (flowNode.getParents().isEmpty() && !visitedParents.contains(flowNode)) { + WorkflowRun parentRun = BuildHandlerUtils.extractParentRun(flowNode); + CIEventCause cause = dtoFactory.newDTO(CIEventCause.class) + .setType(CIEventCauseType.UPSTREAM) + .setProject(BuildHandlerUtils.getJobCiId(parentRun)) + .setBuildCiId(BuildHandlerUtils.getBuildCiId(parentRun)) + .setCauses(CIEventCausesFactory.processCauses((parentRun))); + visitedParents.add(flowNode); + causes.add(cause); + } + + // if we are calculating causes for the END STEP - exclude it's own START STEP from calculation + if (BuildHandlerUtils.isStageEndNode(flowNode)) { + startStagesToSkip.add(((StepEndNode) flowNode).getStartNode()); + } + + for (FlowNode parent : flowNode.getParents()) { + if (BuildHandlerUtils.isStageEndNode(parent)) { + startStagesToSkip.add(((StepEndNode) parent).getStartNode()); + processCauses(parent, causes, startStagesToSkip,visitedParents); + } else if (BuildHandlerUtils.isStageStartNode(parent)) { + if (!startStagesToSkip.contains(parent) && !visitedParents.contains(parent)) { + visitedParents.add(parent); + CIEventCause cause = dtoFactory.newDTO(CIEventCause.class) + .setType(CIEventCauseType.UPSTREAM) + .setProject(parent.getDisplayName()) + .setBuildCiId(String.valueOf(BuildHandlerUtils.extractParentRun(parent).getNumber())); + causes.add(cause); + processCauses(parent, cause.getCauses(), startStagesToSkip, visitedParents); + } else if (startStagesToSkip.contains(parent)){ + startStagesToSkip.remove(parent); + processCauses(parent, causes, startStagesToSkip, visitedParents); + } + } else { + processCauses(parent, causes, startStagesToSkip, visitedParents); + } + } + } + + private static String resolveJobCiId(String jobPlainName) { + if (!jobPlainName.contains(",")) { + return BuildHandlerUtils.translateFolderJobName(jobPlainName); + } + return jobPlainName; + } + + private static FlowNode lookupJobEnclosingNode(Run targetRun, WorkflowRun parentRun) { + if (parentRun.getExecution() == null) { + return null; + } + + FlowNode result = null; + + OctaneParentNodeAction octaneParentNodeAction = targetRun.getAction(OctaneParentNodeAction.class); + if (octaneParentNodeAction != null) { + // finished event case - we do expect an action OctaneParentNodeAction to be present with the relevant info + try { + result = parentRun.getExecution().getNode(octaneParentNodeAction.parentFlowNodeId); + } catch (IOException ioe) { + logger.error("failed to extract parent flow node for " + targetRun, ioe); + } + } else { + // started event case - we expect a strict bond here since the parent FlowNode MUST be among the current heads + // the only case for potential break here is if the same JOB will be running concurrently by 2 distinct FlowNodes + List potentialAncestors = parentRun.getExecution().getCurrentHeads(); + if (potentialAncestors != null) { + for (FlowNode head : potentialAncestors) { + if (head instanceof StepAtomNode && head.getAction(LabelAction.class) != null) { + StepDescriptor descriptor = ((StepAtomNode) head).getDescriptor(); + LabelAction labelAction = head.getAction(LabelAction.class); + String label = labelAction != null ? labelAction.getDisplayName() : null; + if (descriptor != null && descriptor.getId().endsWith("BuildTriggerStep") && + label != null && label.endsWith(targetRun.getParent().getFullDisplayName())) { + result = head; + targetRun.addAction(new OctaneParentNodeAction(result.getId())); + break; + } + } + } + } + } + + return result; + } + + private final static class OctaneParentNodeAction extends InvisibleAction { + private final String parentFlowNodeId; + + private OctaneParentNodeAction(String parentFlowNodeId) { + this.parentFlowNodeId = parentFlowNodeId; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/ModelFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/ModelFactory.java new file mode 100644 index 0000000000..85c5c62ad2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/ModelFactory.java @@ -0,0 +1,183 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.model.processors.projects.AbstractProjectProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.*; +import org.apache.logging.log4j.Logger; + +import java.util.*; + +/** + * Created by lazara on 26/01/2016. + */ +public class ModelFactory { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ModelFactory.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + public static PipelineNode createStructureItem(Job job) { + return createStructureItem(job, new HashSet<>()); + } + + public static PipelinePhase createStructurePhase(String name, boolean blocking, List items, Set processedJobs) { + PipelinePhase pipelinePhase = dtoFactory.newDTO(PipelinePhase.class); + pipelinePhase.setName(name); + pipelinePhase.setBlocking(blocking); + + PipelineNode[] tmp = new PipelineNode[items.size()]; + for (int i = 0; i < tmp.length; i++) { + if (items.get(i) != null) { + tmp[i] = ModelFactory.createStructureItem(items.get(i), processedJobs); + + } else { + logger.warn("One of referenced jobs is null, your Jenkins config probably broken, skipping this job..."); + } + } + + pipelinePhase.setJobs(Arrays.asList(tmp)); + + return pipelinePhase; + } + + private static PipelineNode createStructureItem(Job job, Set processedJobs) { + AbstractProjectProcessor projectProcessor = JobProcessorFactory.getFlowProcessor(job); + projectProcessor.buildStructure(processedJobs); + PipelineNode pipelineNode = dtoFactory.newDTO(PipelineNode.class); + pipelineNode.setJobCiId(projectProcessor.getTranslatedJobName()); + pipelineNode.setName(BuildHandlerUtils.translateFullDisplayName(job.getFullDisplayName())); + pipelineNode.setParameters(ParameterProcessors.getConfigs(job)); + pipelineNode.setPhasesInternal(projectProcessor.getInternals()); + pipelineNode.setPhasesPostBuild(projectProcessor.getPostBuilds()); + + return pipelineNode; + } + + public static CIParameter createParameterConfig(ParameterDefinition pd) { + return createParameterConfig(pd, CIParameterType.UNKNOWN, null, null); + } + + public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type) { + return createParameterConfig( + pd, + type, + pd.getDefaultParameterValue() == null ? null : pd.getDefaultParameterValue().getValue(), + null); + } + + public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type, Object defaultValue) { + return createParameterConfig(pd, type, defaultValue, null); + } + + public static CIParameter createParameterConfig(String name, CIParameterType type, List choices) { + CIParameter ciParameter = dtoFactory.newDTO(CIParameter.class); + ciParameter.setName(name); + ciParameter.setType(type); + ciParameter.setDescription(""); + ciParameter.setChoices(choices.toArray()); + return ciParameter; + } + + public static CIParameter createParameterConfig(ParameterDefinition pd, CIParameterType type, Object defaultValue, List choices) { + CIParameter ciParameter = dtoFactory.newDTO(CIParameter.class); + ciParameter.setName(pd.getName()); + ciParameter.setType(type); + ciParameter.setDescription(pd.getDescription()); + ParameterValue tmp; + if (type != CIParameterType.UNKNOWN && type != CIParameterType.PASSWORD) { + if (defaultValue != null) { + ciParameter.setDefaultValue(defaultValue); + } else { + try { //computing getDefaultParameterValue may throw exception(for example ChoiceParameterDefinition.getDefaultParameterValue may throw exception of ArrayIndexOutOfBoundsException) + tmp = pd.getDefaultParameterValue(); + } catch (Throwable e) { + tmp = null; + } + ciParameter.setDefaultValue(tmp == null ? "" : tmp.getValue()); + } + if (choices != null) { + ciParameter.setChoices(choices.toArray()); + } + } + + return ciParameter; + } + + public static CIParameter createParameterInstance(CIParameter pc, Object rawValue) { + String value = rawValue == null ? null : rawValue.toString(); + return dtoFactory.newDTO(CIParameter.class) + .setName(pc.getName()) + .setType(pc.getType()) + .setDescription(pc.getDescription()) + .setChoices(pc.getChoices()) + .setDescription(pc.getDescription()) + .setDefaultValue(pc.getDefaultValue()) + .setValue(value); + } + + public static String generateSubBuildName(List parameters) { + List sortedList = new ArrayList<>(); + for (CIParameter p : parameters) { + if (p.getType() == CIParameterType.AXIS) { + sortedList.add(p); + } + } + + sortedList.sort(Comparator.comparing(CIParameter::getName)); + + StringBuilder subBuildName = new StringBuilder(); + if (sortedList.size() > 0) { + int i = 0; + for (; i < sortedList.size() - 1; i++) { + subBuildName + .append(sortedList.get(i).getName()) + .append("=") + .append(sortedList.get(i).getValue().toString()) + .append(","); + } + subBuildName + .append(sortedList.get(i).getName()) + .append("=") + .append(sortedList.get(i).getValue().toString()); + } + return subBuildName.toString(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/SonarHelper.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/SonarHelper.java new file mode 100644 index 0000000000..86b442d122 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/SonarHelper.java @@ -0,0 +1,159 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.EnvVars; +import hudson.maven.MavenModuleSet; +import hudson.model.*; +import hudson.plugins.sonar.SonarGlobalConfiguration; +import hudson.plugins.sonar.SonarInstallation; +import hudson.plugins.sonar.SonarRunnerBuilder; +import hudson.tasks.Builder; +import hudson.util.DescribableList; +import hudson.util.Secret; +import jenkins.model.GlobalConfiguration; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Optional; + +/** + * the adapter enables usage of sonar classes and interfaces without adding a full dependency on + * sonar plugin. + * this class is only dependent on sonar plugin for compile time. + */ + +public class SonarHelper { + + public enum DataType {VULNERABILITIES, COVERAGE} + + public static final String SONAR_GLOBAL_CONFIG = "hudson.plugins.sonar.SonarGlobalConfiguration"; + private static final String SONAR_ACTION_ID = "hudson.plugins.sonar.SonarRunnerBuilder"; + private static final String SONAR_SERVER_HOST_VARIABLE = "SONAR_HOST_URL"; + private static final String SONAR_SERVER_TOKEN_VARIABLE = "SONAR_AUTH_TOKEN"; + + private String serverUrl; + private String serverToken; + + public SonarHelper(Run run, TaskListener listener) { + DescribableList> postbuilders = null; + if (run instanceof AbstractBuild) { + AbstractBuild abstractBuild = (AbstractBuild) run; + setSonarDetailsFromMavenEnvironment(abstractBuild, listener); + AbstractProject project = abstractBuild.getProject(); + + // for jobs that does not use new sonar approach for maven jobs, + // extract data for old approach which used post build step + if (StringUtils.isNullOrEmpty(this.getServerUrl()) || StringUtils.isNullOrEmpty(this.getServerToken())) { + if (project instanceof MavenModuleSet) { + postbuilders = ((MavenModuleSet) project).getPostbuilders(); + } else if (project instanceof Project) { + postbuilders = ((Project) project).getBuildersList(); + } + if (postbuilders != null){ + setDataFromSonarBuilder(postbuilders, run); + } + } + } + } + + public String getServerUrl() { + return serverUrl; + } + + public String getServerToken() { + return serverToken; + } + + // used by the web hook + public static String getSonarInstallationTokenByUrl(GlobalConfiguration sonarConfiguration, String sonarUrl, Run run) { + if (sonarConfiguration instanceof SonarGlobalConfiguration) { + SonarGlobalConfiguration sonar = (SonarGlobalConfiguration) sonarConfiguration; + Optional installation = Arrays.stream(sonar.getInstallations()) + .filter(sonarInstallation -> sonarInstallation.getServerUrl().equals(sonarUrl)) + .findFirst(); + if (installation.isPresent()) { + return extractAuthenticationToken(installation.get(), run); + } + } + return ""; + } + + private static String extractAuthenticationToken(SonarInstallation sonarInstallation, Run run) { + return sonarInstallation.getServerAuthenticationToken(run); + } + + private void setSonarDetailsFromMavenEnvironment(AbstractBuild build, TaskListener listener) { + EnvVars environment; + try { + environment = build.getEnvironment(listener); + if (environment != null) { + this.serverUrl = environment.get(SONAR_SERVER_HOST_VARIABLE, ""); + this.serverToken = environment.get(SONAR_SERVER_TOKEN_VARIABLE, ""); + } + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + private void setDataFromSonarBuilder(DescribableList> postBuilders, Run run) { + Builder sonarBuilder = postBuilders.getDynamic(SONAR_ACTION_ID); + if (sonarBuilder != null) { + SonarRunnerBuilder builder = (SonarRunnerBuilder) sonarBuilder; + this.serverUrl = extractSonarUrl(builder); + this.serverToken = extractSonarToken(builder, run); + } + } + + /** + * get sonar URL address + * + * @return Sonar's URL + */ + private String extractSonarUrl(SonarRunnerBuilder builder) { + return builder != null ? builder.getSonarInstallation().getServerUrl() : ""; + } + + /** + * get sonar server token + * + * @return Sonar's auth token + */ + private String extractSonarToken(SonarRunnerBuilder builder, Run run) { + String result = builder != null ? extractAuthenticationToken(builder.getSonarInstallation(), run) : ""; + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java new file mode 100644 index 0000000000..2bf0b8aebc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/AbstractBuilderProcessor.java @@ -0,0 +1,107 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.model.AbstractProject; +import hudson.model.Job; +import hudson.tasks.Builder; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Base class for discovery/provisioning of an internal phases/steps of the specific Job + */ +public abstract class AbstractBuilderProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(AbstractBuilderProcessor.class); + protected ArrayList phases = new ArrayList<>(); + + /** + * Retrieves previously processed and prepared phases of the specific Builder (Jenkins' internal Job invoker) + * + * @return list of phases + */ + public List getPhases() { + return phases; + } + + public static void processInternalBuilders(Builder builder, Job job, String phasesName, List internalPhases, Set processedJobs) { + processedJobs.add(job); + AbstractBuilderProcessor builderProcessor = null; + try { + switch (builder.getClass().getName()) { + case JobProcessorFactory.CONDITIONAL_BUILDER_NAME: + builderProcessor = new ConditionalBuilderProcessor(builder, job, phasesName, internalPhases, processedJobs); + break; + case JobProcessorFactory.SINGLE_CONDITIONAL_BUILDER_NAME: + builderProcessor = new SingleConditionalBuilderProcessor(builder, job, phasesName, internalPhases, processedJobs); + break; + case JobProcessorFactory.PARAMETRIZED_TRIGGER_BUILDER: + builderProcessor = new ParameterizedTriggerProcessor(builder, job, phasesName, processedJobs); + break; + case JobProcessorFactory.MULTIJOB_BUILDER: + builderProcessor = new MultiJobBuilderProcessor(builder, job, processedJobs); + break; + default: + logger.debug("not yet supported build (internal) action: " + builder.getClass().getName()); + break; + } + } catch (Throwable e) { + logger.info("Failed to load build processor for build " + builder.getClass().getName() + ", " + e.getClass().getName() + " : " + e.getMessage()); + } + + if (builderProcessor != null) { + internalPhases.addAll(builderProcessor.getPhases()); + } + processedJobs.remove(job); + } + + protected void eliminateIllegalItems(Job job, Set processedJobs, List items) { + for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { + AbstractProject next = iterator.next(); + if (next == null) { + iterator.remove(); + logger.warn("encountered null project reference; considering it as corrupted configuration and skipping"); + } else if (processedJobs.contains(next)) { + iterator.remove(); + logger.warn(String.format("encountered circular reference from %s to %s", job.getFullName(), next.getFullName())); + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java new file mode 100644 index 0000000000..f9ecaba275 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/BuildTriggerProcessor.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.AbstractProject; +import hudson.model.Job; +import hudson.tasks.BuildTrigger; +import hudson.tasks.Publisher; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of BuildTrigger + */ +public class BuildTriggerProcessor extends AbstractBuilderProcessor { + + public BuildTriggerProcessor(Publisher publisher, AbstractProject project, Set processedJobs) { + BuildTrigger t = (BuildTrigger) publisher; + super.phases = new ArrayList<>(); + List items = t.getChildProjects(project.getParent()); + eliminateIllegalItems(project, processedJobs, items); + super.phases.add(ModelFactory.createStructurePhase("downstream", false, items, processedJobs)); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ConditionalBuilderProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ConditionalBuilderProcessor.java new file mode 100644 index 0000000000..1d60813bae --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ConditionalBuilderProcessor.java @@ -0,0 +1,55 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import hudson.model.Job; +import hudson.tasks.BuildStep; +import hudson.tasks.Builder; +import org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of Conditional Plugin (parent definitions) + */ +class ConditionalBuilderProcessor extends AbstractBuilderProcessor { + + ConditionalBuilderProcessor(Builder builder, Job job, String phasesName, List internalPhases, Set processedJobs) { + ConditionalBuilder conditionalBuilder = (ConditionalBuilder) builder; + for (BuildStep currentBuildStep : conditionalBuilder.getConditionalbuilders()) { + processInternalBuilders((Builder) currentBuildStep, job, phasesName, internalPhases, processedJobs); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java new file mode 100644 index 0000000000..6d22cdde51 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/MultiJobBuilderProcessor.java @@ -0,0 +1,82 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import com.tikal.jenkins.plugins.multijob.MultiJobBuilder; +import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig; +import hudson.model.AbstractProject; +import hudson.model.Item; +import hudson.model.Job; +import hudson.tasks.Builder; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of MultiJob Plugin + */ +class MultiJobBuilderProcessor extends AbstractBuilderProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(MultiJobBuilderProcessor.class); + + MultiJobBuilderProcessor(Builder builder, Job job, Set processedJobs) { + MultiJobBuilder b = (MultiJobBuilder) builder; + super.phases = new ArrayList<>(); + List items = new ArrayList<>(); + AbstractProject tmpProject; + for (PhaseJobsConfig config : b.getPhaseJobs()) { + if(StringUtils.isEmpty(config.getJobName())){ + continue; + } + Item item = Jenkins.get().getItemByFullName(config.getJobName()); + if (item == null) { + logger.debug(job.getFullName() + "' contains phase job '" + config.getJobName() + "' that is not found."); + } else if (item instanceof AbstractProject) { + tmpProject = (AbstractProject) item; + if (processedJobs.contains(tmpProject)) { + logger.warn(String.format("encountered circular reference from %s to %s", job.getFullName(), tmpProject.getFullName())); + } else { + items.add(tmpProject); + } + } else { + logger.warn(job.getFullName() + "' contains phase job '" + config.getJobName() + "' that is not AbstractProject"); + } + } + super.phases.add(ModelFactory.createStructurePhase(b.getPhaseName(), true, items, processedJobs)); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java new file mode 100644 index 0000000000..35b073da67 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/ParameterizedTriggerProcessor.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.AbstractProject; +import hudson.model.Job; +import hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig; +import hudson.plugins.parameterizedtrigger.BuildTrigger; +import hudson.plugins.parameterizedtrigger.BuildTriggerConfig; +import hudson.plugins.parameterizedtrigger.TriggerBuilder; +import hudson.tasks.Builder; +import hudson.tasks.Publisher; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of ParameterizedTrigger Plugin + */ +public class ParameterizedTriggerProcessor extends AbstractBuilderProcessor { + + ParameterizedTriggerProcessor(Builder builder, Job job, String phasesName, Set processedJobs) { + TriggerBuilder b = (TriggerBuilder) builder; + super.phases = new ArrayList<>(); + List items; + for (BlockableBuildTriggerConfig config : b.getConfigs()) { + items = config.getProjectList(job.getParent(), null); + eliminateIllegalItems(job, processedJobs, items); + super.phases.add(ModelFactory.createStructurePhase(phasesName, config.getBlock() != null, items, processedJobs)); + } + } + + public ParameterizedTriggerProcessor(Publisher publisher, AbstractProject project, String phasesName, Set processedJobs) { + BuildTrigger t = (BuildTrigger) publisher; + super.phases = new ArrayList<>(); + List items; + for (BuildTriggerConfig config : t.getConfigs()) { + items = config.getProjectList(project.getParent(), null); + eliminateIllegalItems(project, processedJobs, items); + super.phases.add(ModelFactory.createStructurePhase(phasesName, false, items, processedJobs)); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/SingleConditionalBuilderProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/SingleConditionalBuilderProcessor.java new file mode 100644 index 0000000000..fbc25f3689 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/builders/SingleConditionalBuilderProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.builders; + +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import hudson.model.Job; +import hudson.tasks.Builder; +import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of Conditional Plugin (internal step) + */ +class SingleConditionalBuilderProcessor extends AbstractBuilderProcessor { + + SingleConditionalBuilderProcessor(Builder builder, Job job, String phasesName, List internalPhases, Set processedJobs) { + SingleConditionalBuilder singleConditionalBuilder = (SingleConditionalBuilder) builder; + processInternalBuilders((Builder) singleConditionalBuilder.getBuildStep(), job, phasesName, internalPhases, processedJobs); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java new file mode 100644 index 0000000000..5a1ccd063d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/AbstractParametersProcessor.java @@ -0,0 +1,46 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; + +/** + * Created by gullery on 19/02/2015. + */ +public abstract class AbstractParametersProcessor { + public abstract CIParameter createParameterConfig(ParameterDefinition pd); + + public abstract CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ActiveChoiceParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ActiveChoiceParameterProcessor.java new file mode 100644 index 0000000000..d076e980e8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ActiveChoiceParameterProcessor.java @@ -0,0 +1,55 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; + +public class ActiveChoiceParameterProcessor extends AbstractParametersProcessor { + ActiveChoiceParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, ""); + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + Object value = pv == null ? null : pv.getValue(); + return ModelFactory.createParameterInstance(createParameterConfig(pd), value); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java new file mode 100644 index 0000000000..d145c93436 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ExtendedChoiceParameterProcessor.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterDefinition; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by gullery on 19/02/2015. + */ + +public class ExtendedChoiceParameterProcessor extends AbstractParametersProcessor { + ExtendedChoiceParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + ExtendedChoiceParameterDefinition extChoice = (ExtendedChoiceParameterDefinition) pd; + Map choicesMap; + List choices = new ArrayList<>(); + try { + choicesMap = extChoice.getChoicesByDropdownId(); + } catch (Exception e) { + choicesMap = null; + } + if (choicesMap != null) { + choices = new ArrayList<>(choicesMap.values()); + } + return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, null, choices); + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + Object value = pv == null ? null : pv.getValue(); + return ModelFactory.createParameterInstance(createParameterConfig(pd), value); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java new file mode 100644 index 0000000000..9a090ffc13 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/InherentParameterProcessor.java @@ -0,0 +1,111 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.*; + +import java.util.ArrayList; + +/** + * Created by gullery on 19/02/2015. + */ + +public class InherentParameterProcessor extends AbstractParametersProcessor { + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + InherentParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + CIParameter result; + if (pd instanceof BooleanParameterDefinition) { + result = ModelFactory.createParameterConfig(pd, CIParameterType.BOOLEAN); + } else if (pd instanceof TextParameterDefinition) { + result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING); + } else if (pd instanceof StringParameterDefinition) { + result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING); + } else if (pd instanceof ChoiceParameterDefinition) { + ChoiceParameterDefinition choicePd = (ChoiceParameterDefinition) pd; + result = ModelFactory.createParameterConfig(pd, CIParameterType.STRING, null, new ArrayList<>(choicePd.getChoices())); + } else if (pd instanceof PasswordParameterDefinition) { + PasswordParameterDefinition passPd = (PasswordParameterDefinition) pd; + result = ModelFactory.createParameterConfig(pd, CIParameterType.PASSWORD, passPd.getDefaultValue()); + } else if (pd instanceof FileParameterDefinition) { + result = ModelFactory.createParameterConfig(pd, CIParameterType.FILE); + } else { + result = new UnsupportedParameterProcessor().createParameterConfig(pd); + } + return result; + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + CIParameter result; + CIParameter pc = createParameterConfig(pd); + Object value = pv == null ? null : pv.getValue(); + if (pd instanceof BooleanParameterDefinition) { + result = ModelFactory.createParameterInstance(pc, value); + } else if (pd instanceof TextParameterDefinition) { + result = ModelFactory.createParameterInstance(pc, value); + } else if (pd instanceof StringParameterDefinition) { + result = ModelFactory.createParameterInstance(pc, value); + } else if (pd instanceof ChoiceParameterDefinition) { + result = ModelFactory.createParameterInstance(pc, value); + } else if (pd instanceof PasswordParameterDefinition) { + result = dtoFactory.newDTO(CIParameter.class) + .setType(pc.getType()) + .setName(pc.getName()) + .setDescription(pc.getDescription()) + .setChoices(pc.getChoices()) + .setDefaultValue(pc.getDefaultValue()) + .setValue(null); + } else if (pd instanceof FileParameterDefinition) { + FileParameterValue filePv = (FileParameterValue) pv; + result = dtoFactory.newDTO(CIParameter.class) + .setType(pc.getType()) + .setName(pc.getName()) + .setDescription(pc.getDescription()) + .setChoices(pc.getChoices()) + .setDefaultValue(pc.getDefaultValue()) + .setValue(filePv != null ? filePv.getOriginalFileName() : null); + } else { + result = new UnsupportedParameterProcessor().createParameterInstance(pd, pv); + } + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java new file mode 100644 index 0000000000..d4f0a51018 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/NodeLabelParameterProcessor.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; +import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition; +import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue; +import org.jvnet.jenkins.plugins.nodelabelparameter.NodeParameterDefinition; +import org.jvnet.jenkins.plugins.nodelabelparameter.NodeParameterValue; + +import java.util.ArrayList; + +/** + * Created by gullery on 19/02/2015. + */ + +public class NodeLabelParameterProcessor extends AbstractParametersProcessor { + NodeLabelParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + if (pd instanceof NodeParameterDefinition) { + NodeParameterDefinition nodePd = (NodeParameterDefinition) pd; + return ModelFactory.createParameterConfig(pd, CIParameterType.STRING, new ArrayList(nodePd.allowedSlaves)); + } else if (pd instanceof LabelParameterDefinition) { + LabelParameterDefinition labelPd = (LabelParameterDefinition) pd; + return ModelFactory.createParameterConfig(pd, CIParameterType.STRING); + } else { + return ModelFactory.createParameterConfig(pd); + } + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + Object value = null; + if (pv instanceof NodeParameterValue) { + value = ((NodeParameterValue) pv).getLabel(); + } else if (pv instanceof LabelParameterValue) { + value = ((LabelParameterValue) pv).getLabel(); + } + return ModelFactory.createParameterInstance(createParameterConfig(pd), value); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java new file mode 100644 index 0000000000..e32f295537 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/ParameterProcessors.java @@ -0,0 +1,202 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.matrix.*; +import hudson.model.*; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Created by gullery on 26/03/2015. + * + * This class incorporates helper methods for handling Jenkins job parameters. + */ + +public enum ParameterProcessors { + EXTENDED("com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterDefinition", ExtendedChoiceParameterProcessor.class), + INHERENT("hudson.model", InherentParameterProcessor.class), + NODE_LABEL("org.jvnet.jenkins.plugins.nodelabelparameter", NodeLabelParameterProcessor.class), + RANDOM_STRING("hudson.plugins.random_string_parameter.RandomStringParameterDefinition", RandomStringParameterProcessor.class), + ACTIVE_CHOICE("org.biouno.unochoice", ActiveChoiceParameterProcessor.class); + + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ParameterProcessors.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + private String targetPluginClassName; + private Class processorClass; + + ParameterProcessors(String targetPluginClassName, Class processorClass) { + this.targetPluginClassName = targetPluginClassName; + this.processorClass = processorClass; + } + + public static List getConfigs(Job job) { + List result = new ArrayList<>(); + List paramDefinitions; + ParameterDefinition pd; + String className; + AbstractParametersProcessor processor; + if (job.getProperty(ParametersDefinitionProperty.class) != null) { + paramDefinitions = ((ParametersDefinitionProperty) job.getProperty(ParametersDefinitionProperty.class)).getParameterDefinitions(); + for (int i = 0; paramDefinitions != null && i < paramDefinitions.size(); i++) { + pd = paramDefinitions.get(i); + if (pd instanceof PasswordParameterDefinition) { + continue; + } + className = pd.getClass().getName(); + processor = getAppropriate(className); + result.add(processor.createParameterConfig(pd)); + } + } + + if (job instanceof MatrixProject) { + AxisList axisList = ((MatrixProject) job).getAxes(); + for (Axis axis : axisList) { + result.add(ModelFactory.createParameterConfig(axis.getName(), CIParameterType.AXIS, new ArrayList<>(axis.getValues()))); + } + } + + return result; + } + + // TODO: the below mapping between param configs and values based on param name uniqueness, beware! + public static List getInstances(Run run) { + List result = new ArrayList<>(); + + try { + CIParameter tmp; + Job job = run.getParent(); + List paramDefinitions; + String className; + Map parametersValues; + ParametersAction parametersAction = run.getAction(ParametersAction.class); + if (parametersAction != null) { + parametersValues = parametersAction.getAllParameters().stream().collect( + Collectors.toMap(ParameterValue::getName, Function.identity(), (v1, v2) -> v1)); + } else { + parametersValues = new HashMap<>(); + } + ParameterValue pv; + + // TODO: should be moved to the Matrix Project processor + if (job instanceof MatrixConfiguration) { + Combination combination = ((MatrixConfiguration) job).getCombination(); + for (Map.Entry entry : combination.entrySet()) { + tmp = dtoFactory.newDTO(CIParameter.class) + .setType(CIParameterType.AXIS) + .setName(entry.getKey()) + .setValue(entry.getValue()); + result.add(tmp); + } + } + + if (job.getProperty(ParametersDefinitionProperty.class) != null) { + paramDefinitions = ((ParametersDefinitionProperty) job.getProperty(ParametersDefinitionProperty.class)).getParameterDefinitions(); + for (ParameterDefinition pd : paramDefinitions) { + className = pd.getClass().getName(); + pv = parametersValues.remove(pd.getName()); + + try { + AbstractParametersProcessor processor = getAppropriate(className); + result.add(processor.createParameterInstance(pd, pv)); + } catch (Exception e) { + logger.error("failed to process instance of parameter or type '" + className + "', adding as unsupported", e); + result.add(new UnsupportedParameterProcessor().createParameterInstance(pd, pv)); + } + } + } + //go over parameters that are not defined in definitions + for (ParameterValue notDefinedParameter : parametersValues.values()) { + if (notDefinedParameter.getValue() != null) { + CIParameter param = dtoFactory.newDTO(CIParameter.class) + .setType(CIParameterType.STRING) + .setName(notDefinedParameter.getName()) + .setValue(notDefinedParameter.getValue()); + result.add(param); + } + } + } catch (Exception e) { + logger.error("failed to process parameters of " + run, e); + } + + return result; + } + + public static List getInstances(ParametersAction parametersAction) { + List result = new ArrayList<>(); + + try { + Map parametersValues = parametersAction.getAllParameters().stream().collect( + Collectors.toMap(ParameterValue::getName, Function.identity(), (v1, v2) -> v1)); + + //go over parameters that are not defined in definitions + for (ParameterValue notDefinedParameter : parametersValues.values()) { + if (notDefinedParameter.getValue() != null) { + CIParameter param = dtoFactory.newDTO(CIParameter.class) + .setType(CIParameterType.STRING) + .setName(notDefinedParameter.getName()) + .setValue(notDefinedParameter.getValue()); + result.add(param); + } + } + } catch (Exception e) { + logger.error("failed to process parameters :" + e.getMessage(), e); + } + + return result; + } + + private static AbstractParametersProcessor getAppropriate(String className) { + for (ParameterProcessors p : values()) { + if (className.startsWith(p.targetPluginClassName)) { + try { + return p.processorClass.newInstance(); + } catch (InstantiationException | IllegalAccessException ie) { + logger.error("failed to instantiate instance of parameters processor of type " + className, ie); + } + } + } + return new UnsupportedParameterProcessor(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java new file mode 100644 index 0000000000..ddedd4f7c0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/RandomStringParameterProcessor.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; + +/** + * Created by gullery on 19/02/2015. + */ + +public class RandomStringParameterProcessor extends AbstractParametersProcessor { + RandomStringParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + return ModelFactory.createParameterConfig(pd, CIParameterType.STRING); + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + Object value = pv == null ? null : pv.getValue(); + return ModelFactory.createParameterInstance(createParameterConfig(pd), value); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java new file mode 100644 index 0000000000..e55d207224 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/parameters/UnsupportedParameterProcessor.java @@ -0,0 +1,65 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.parameters; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import hudson.model.ParameterDefinition; +import hudson.model.ParameterValue; + +/** + * Created by gullery on 19/02/2015. + */ + +public class UnsupportedParameterProcessor extends AbstractParametersProcessor { + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + UnsupportedParameterProcessor() { + } + + @Override + public CIParameter createParameterConfig(ParameterDefinition pd) { + return ModelFactory.createParameterConfig(pd); + } + + @Override + public CIParameter createParameterInstance(ParameterDefinition pd, ParameterValue pv) { + return dtoFactory.newDTO(CIParameter.class) + .setType(CIParameterType.UNKNOWN) + .setName(pd.getName()) + .setDescription(pd.getDescription()) + .setDefaultValue(pd.getDefaultParameterValue() != null ? pd.getDefaultParameterValue().getValue() : null); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java new file mode 100644 index 0000000000..14378890bf --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/AbstractProjectProcessor.java @@ -0,0 +1,365 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.general.CIBuildStatusInfo; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; +import com.hp.octane.integrations.utils.SdkConstants; +import com.hp.octane.integrations.utils.SdkStringUtils; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.events.OutputEnvironmentParametersHelper; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.octane.model.processors.builders.AbstractBuilderProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.builders.BuildTriggerProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.builders.ParameterizedTriggerProcessor; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.*; +import hudson.tasks.Builder; +import hudson.tasks.Publisher; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 09/01/15 + * Time: 00:59 + * To change this template use File | Settings | File Templates. + */ + +@SuppressWarnings({"squid:S1132", "squid:S1872"}) +public abstract class AbstractProjectProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(AbstractProjectProcessor.class); + private final List internals = new ArrayList<>(); + private final List postBuilds = new ArrayList<>(); + private boolean isProcessed = false; + T job; + + AbstractProjectProcessor(T job) { + this.job = job; + } + + /** + * Attempt to retrieve an [internal] build phases of the Job + * + * @return list of builders + */ + public List tryGetBuilders() { + return new ArrayList<>(); + } + + /** + * Enqueue Job's run with the specified parameters + */ + public void scheduleBuild(Cause cause, ParametersAction parametersAction) { + if (job instanceof AbstractProject) { + AbstractProject project = (AbstractProject) job; + int delay = project.getQuietPeriod(); + project.scheduleBuild(delay, cause, parametersAction); + } else { + throw new IllegalStateException("unsupported job CAN NOT be run"); + } + } + + public void cancelBuild(Cause cause, ParametersAction parametersAction) { + String buildId = getParameterValueIfExist(parametersAction, UftConstants.BUILD_ID_PARAMETER_NAME); + + String suiteId = getParameterValueIfExist(parametersAction, SdkConstants.JobParameters.SUITE_ID_PARAMETER_NAME); + String suiteRunId = getParameterValueIfExist(parametersAction, SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME); + + String releaseExecutionId = getParameterValueIfExist(parametersAction, SdkConstants.JobParameters.OCTANE_AUTO_ACTION_EXECUTION_ID_PARAMETER_NAME); + + if (buildId != null) { + logger.info(String.format("cancelBuild for %s, buildId=%s", job.getFullName(), buildId)); + Run aBuild = (job).getBuild(buildId); + logger.info(String.format("cancelBuild for %s, buildId=%s - is done", job.getFullName(), buildId)); + if (aBuild == null) { + logger.warn(String.format("Cannot stop : build %s is not found", buildId)); + return; + } + stopBuild(aBuild); + } else { + FoundInfo foundInfo = new FoundInfo(); + String paramToSearch; + String paramValueToSearch; + if (SdkStringUtils.isNotEmpty(releaseExecutionId)) { + paramToSearch = SdkConstants.JobParameters.OCTANE_AUTO_ACTION_EXECUTION_ID_PARAMETER_NAME; + paramValueToSearch = releaseExecutionId; + } else if (SdkStringUtils.isNotEmpty(suiteRunId)) { + paramToSearch = SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME; + paramValueToSearch = suiteRunId; + } else { + throw new IllegalArgumentException("Cannot cancel job as no identification parameters was passed"); + } + + logger.info(String.format("cancelBuild for %s, %s=%s", job.getFullName(), paramToSearch, paramValueToSearch)); + Queue queue = Jenkins.get().getQueue(); + Queue.Task queueTaskJob = (Queue.Task) job; + queue.getItems(queueTaskJob).forEach(item -> { + item.getActions(ParametersAction.class).forEach(action -> { + if (!foundInfo.found && checkIfParamExistAndEqual(action, paramToSearch, paramValueToSearch)) { + try { + logger.info("canceling item in queue : " + item); + queue.cancel(item); + logger.info("Item in queue is cancelled item : " + item); + foundInfo.found = true; + } catch (Exception e) { + logger.warn("Failed to cancel '" + item + "' in queue : " + e.getMessage(), e); + } + } + }); + }); + + job.getBuilds().forEach(build -> { + if (!foundInfo.found) { + Run run = (Run)build; + run.getActions(ParametersAction.class).forEach(action -> { + if (checkIfParamExistAndEqual(action, paramToSearch, paramValueToSearch)) { + stopBuild(run); + foundInfo.found = true; + } + }); + } + }); + } + } + + public CIBuildStatusInfo getBuildStatus(String paramName, String paramValue) { + CIBuildStatusInfo status = DTOFactory.getInstance().newDTO(CIBuildStatusInfo.class) + .setBuildStatus(CIBuildStatus.UNAVAILABLE) + .setJobCiId(this.getTranslatedJobName()) + .setParamName(paramName) + .setParamValue(paramValue); + String buildId = UftConstants.BUILD_ID_PARAMETER_NAME.equals(paramName) ? paramValue : null; + + if (buildId != null) { + try { + int buildNum = Integer.parseInt(buildId); + Run aBuild = job.getBuildByNumber(buildNum); + if (aBuild == null) { + status.setBuildStatus(CIBuildStatus.UNAVAILABLE); + } else { + status.setBuildCiId(BuildHandlerUtils.getBuildCiId(aBuild)); + status.setAllBuildParams(ParameterProcessors.getInstances(aBuild)); + if (aBuild.isBuilding()) { + status.setBuildStatus(CIBuildStatus.RUNNING); + } else { + status.setBuildStatus(CIBuildStatus.FINISHED); + status.setResult(BuildHandlerUtils.translateRunResult(aBuild)); + } + } + } catch (NumberFormatException e) { + throw new RuntimeException("Failed to parse build id " + buildId); + } + } else { + FoundInfo foundInfo = new FoundInfo(); + if (job instanceof Queue.Task) { + Queue.Task queueTaskJob = (Queue.Task) job; + Queue queue = Jenkins.get().getQueue(); + queue.getItems(queueTaskJob).forEach(item -> { + item.getActions(ParametersAction.class).forEach(action -> { + if (!foundInfo.found && checkIfParamExistAndEqual(action, paramName, paramValue)) { + status.setBuildStatus(CIBuildStatus.QUEUED); + foundInfo.found = true; + } + }); + }); + } + + job.getBuilds().forEach(build -> { + if (!foundInfo.found) { + Run aBuild = (Run) build; + aBuild.getActions(ParametersAction.class).forEach(action -> { + if (checkIfParamExistAndEqual(action, paramName, paramValue)) { + if (aBuild.isBuilding()) { + status.setBuildStatus(CIBuildStatus.RUNNING); + } else { + status.setBuildStatus(CIBuildStatus.FINISHED); + status.setResult(BuildHandlerUtils.translateRunResult(aBuild)); + status.setEnvironmentOutputtedParameters(OutputEnvironmentParametersHelper.getOutputEnvironmentParams(aBuild)); + } + status.setAllBuildParams(ParameterProcessors.getInstances(aBuild)); + status.setBuildCiId(BuildHandlerUtils.getBuildCiId(aBuild)); + foundInfo.found = true; + } + }); + } + }); + } + + return status; + } + + private String getParameterValueIfExist(ParametersAction parametersAction, String paramName) { + ParameterValue pv = parametersAction.getParameter(paramName); + if (pv != null) { + return (String) pv.getValue(); + } else { + return null; + } + } + + protected void stopBuild(Run run) { + AbstractBuild aBuild = (AbstractBuild)run; + try { + aBuild.doStop(); + logger.info("Build is stopped : " + aBuild.getProject().getDisplayName() + aBuild.getDisplayName()); + } catch (Exception e) { + logger.warn("Failed to stop build '" + aBuild.getDisplayName() + "' :" + e.getMessage(), e); + } + } + + private boolean checkIfParamExistAndEqual(ParametersAction parametersAction, String paramName, String expectedValue) { + ParameterValue pv = parametersAction.getParameter(paramName); + return (SdkStringUtils.isNotEmpty(expectedValue) && pv != null && pv.getValue().equals(expectedValue)); + } + + /** + * Retrieve Job's CI ID + * return the job name, in case of a folder job, this method returns the refactored + * name that matches the required pattern. + * + * @return Job's CI ID + */ + public String getTranslatedJobName() { + if (JobProcessorFactory.FOLDER_JOB_NAME.equals(job.getParent().getClass().getName())) { + String jobPlainName = job.getFullName(); // e.g: myFolder/myJob + return BuildHandlerUtils.translateFolderJobName(jobPlainName); + } else { + return job.getName(); + } + } + + public void buildStructure(Set processedJobs) { + processedJobs.add(job); + buildStructureInternal(processedJobs); + processedJobs.remove(job); + isProcessed = true; + } + + protected void buildStructureInternal(Set processedJobs){ + } + + /** + * Discover an internal phases of the Job + * + * @return list of phases + */ + public List getInternals() { + if (!isProcessed) { + buildStructure(new HashSet<>()); + } + return internals; + } + + /** + * Discover a post build phases of the Job + * + * @return list of phases + */ + public List getPostBuilds() { + if (!isProcessed) { + buildStructure(new HashSet<>()); + } + return postBuilds; + } + + /** + * Internal API + * Processes and prepares Job's children for future use - internal flow + * + * @param builders Job's builders + * @param job Job to process + * @param processedJobs previously processed Jobs in this Job's hierarchical chain in order to break the recursive flows + */ + void processBuilders(List builders, Job job, Set processedJobs) { + this.processBuilders(builders, job, "", processedJobs); + } + + /** + * Internal API + * Processes and prepares Job's children for future use - internal flow + * + * @param builders Job's builders + * @param job Job to process + * @param phasesName Targeted phase name in case of available one + * @param processedJobs previously processed Jobs in this Job's hierarchical chain in order to break the recursive flows + */ + void processBuilders(List builders, Job job, String phasesName, Set processedJobs) { + for (Builder builder : builders) { + AbstractBuilderProcessor.processInternalBuilders(builder, job, phasesName, internals, processedJobs); + } + } + + /** + * Internal API + * Processes and prepares Job's children for future use - post build flow + * + * @param job Job to process + * @param processedJobs previously processed Jobs in this Job's hierarchical chain in order to break the recursive flows + */ + @SuppressWarnings("unchecked") + void processPublishers(Job job, Set processedJobs) { + if (job instanceof AbstractProject) { + AbstractProject project = (AbstractProject) job; + processedJobs.add(job); + AbstractBuilderProcessor builderProcessor; + List publishers = project.getPublishersList(); + for (Publisher publisher : publishers) { + builderProcessor = null; + if (publisher.getClass().getName().equals(JobProcessorFactory.SIMPLE_BUILD_TRIGGER)) { + builderProcessor = new BuildTriggerProcessor(publisher, project, processedJobs); + } else if (publisher.getClass().getName().equals(JobProcessorFactory.PARAMETRIZED_BUILD_TRIGGER)) { + builderProcessor = new ParameterizedTriggerProcessor(publisher, project, "", processedJobs); + } + if (builderProcessor != null) { + postBuilds.addAll(builderProcessor.getPhases()); + } else { + logger.debug("not yet supported publisher (post build) action: " + publisher.getClass().getName()); + } + } + processedJobs.remove(job); + } + } + private static class FoundInfo{ + public boolean found; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java new file mode 100644 index 0000000000..07dd95ef74 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/FreeStyleProjectProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import hudson.model.FreeStyleProject; +import hudson.model.Job; +import hudson.tasks.Builder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific FreeStyleProject + */ +class FreeStyleProjectProcessor extends AbstractProjectProcessor { + + FreeStyleProjectProcessor(Job job) { + super((FreeStyleProject) job); + } + + @Override + protected void buildStructureInternal(Set processedJobs) { + // Internal phases + // + super.processBuilders(this.job.getBuilders(), this.job, processedJobs); + + // Post build phases + // + super.processPublishers(this.job, processedJobs); + } + + @Override + public List tryGetBuilders() { + return job.getBuilders(); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java new file mode 100644 index 0000000000..1fc22b8c27 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/JobProcessorFactory.java @@ -0,0 +1,125 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import hudson.model.Item; +import hudson.model.Job; + +/** + * Created by gadiel on 30/11/2016. + *

+ * Job processors factory - should be used as a 'static' class, no instantiation, only static method/s + */ + +public class JobProcessorFactory { + // native + public static final String FREE_STYLE_JOB_NAME = "hudson.model.FreeStyleProject"; + public static final String SIMPLE_BUILD_TRIGGER = "hudson.tasks.BuildTrigger"; + public static final String PARAMETRIZED_BUILD_TRIGGER = "hudson.plugins.parameterizedtrigger.BuildTrigger"; + public static final String PARAMETRIZED_TRIGGER_BUILDER = "hudson.plugins.parameterizedtrigger.TriggerBuilder"; + + // workflow + public static final String WORKFLOW_JOB_NAME = "org.jenkinsci.plugins.workflow.job.WorkflowJob"; + public static final String WORKFLOW_RUN_NAME = "org.jenkinsci.plugins.workflow.job.WorkflowRun"; + public static final String WORKFLOW_MULTI_BRANCH_JOB_NAME = "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"; + + // multijob + public static final String MULTIJOB_JOB_NAME = "com.tikal.jenkins.plugins.multijob.MultiJobProject"; + public static final String MULTIJOB_BUILDER = "com.tikal.jenkins.plugins.multijob.MultiJobBuilder"; + + // matrix + public static final String MATRIX_JOB_NAME = "hudson.matrix.MatrixProject"; + public static final String MATRIX_CONFIGURATION_NAME = "hudson.matrix.MatrixConfiguration"; + + // conditional + public static final String CONDITIONAL_BUILDER_NAME = "org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuilder"; + public static final String SINGLE_CONDITIONAL_BUILDER_NAME = "org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder"; + + // maven + public static final String MAVEN_JOB_NAME = "hudson.maven.MavenModuleSet"; + public static final String MAVEN_MODULE_NAME = "hudson.maven.MavenModule"; + + // folders + public static final String FOLDER_JOB_NAME = "com.cloudbees.hudson.plugins.folder.Folder"; + public static final String GITHUB_ORGANIZATION_FOLDER = "jenkins.branch.OrganizationFolder"; + + private JobProcessorFactory() { + } + + public static AbstractProjectProcessor getFlowProcessor(T job) { + AbstractProjectProcessor flowProcessor; + + switch (job.getClass().getName()) { + case FREE_STYLE_JOB_NAME: + flowProcessor = new FreeStyleProjectProcessor(job); + break; + case MATRIX_JOB_NAME: + flowProcessor = new MatrixProjectProcessor(job); + break; + case MATRIX_CONFIGURATION_NAME: + flowProcessor = new MatrixConfigurationProcessor(job); + break; + case MAVEN_JOB_NAME: + flowProcessor = new MavenProjectProcessor(job); + break; + case MULTIJOB_JOB_NAME: + flowProcessor = new MultiJobProjectProcessor(job); + break; + case WORKFLOW_JOB_NAME: + flowProcessor = new WorkFlowJobProcessor(job); + break; + default: + flowProcessor = new UnsupportedProjectProcessor(job); + break; + } + + return flowProcessor; + } + + public static boolean isFolder(Item item) { + return JobProcessorFactory.FOLDER_JOB_NAME.equals(item.getClass().getName()); + } + + public static boolean isMultibranch(Item item) { + return JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME.equals(item.getClass().getName()); + } + + public static boolean isJob(Item item) { + return item instanceof Job; + } + + public static boolean isMultibranchChild(Item item) { + return JobProcessorFactory.WORKFLOW_JOB_NAME.equals(item.getClass().getName()) && + JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME.equals(item.getParent().getClass().getName()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixConfigurationProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixConfigurationProcessor.java new file mode 100644 index 0000000000..a7b85e96cb --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixConfigurationProcessor.java @@ -0,0 +1,77 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.matrix.MatrixConfiguration; +import hudson.model.Job; +import hudson.tasks.Builder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific MatrixConfiguration Job in context of Matrix Plugin + */ +class MatrixConfigurationProcessor extends AbstractProjectProcessor { + + MatrixConfigurationProcessor(Job project) { + super((MatrixConfiguration) project); + } + + @Override + protected void buildStructureInternal(Set processedJobs) { + // Internal phases + // + super.processBuilders(this.job.getBuilders(), this.job, processedJobs); + + // Post build phases + // + super.processPublishers(this.job, processedJobs); + } + + @Override + public List tryGetBuilders() { + return job.getBuilders(); + } + + @Override + public String getTranslatedJobName() { + if (job.getParent().getParent().getClass().getName().equals(JobProcessorFactory.FOLDER_JOB_NAME)) { + String parentJobName = job.getParent().getFullName(); // e.g: myFolder/myJob + return BuildHandlerUtils.translateFolderJobName(parentJobName) + "/" + job.getName(); + } else { + return job.getFullName(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java new file mode 100644 index 0000000000..636ade6587 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MatrixProjectProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import hudson.matrix.MatrixProject; +import hudson.model.Job; +import hudson.tasks.Builder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of MatrixProject Plugin + */ +class MatrixProjectProcessor extends AbstractProjectProcessor { + + MatrixProjectProcessor(Job project) { + super((MatrixProject) project); + } + + @Override + protected void buildStructureInternal(Set processedJobs) { + // Internal phases + // + super.processBuilders(this.job.getBuilders(), this.job, processedJobs); + + // Post build phases + // + super.processPublishers(this.job, processedJobs); + } + + @Override + public List tryGetBuilders() { + return job.getBuilders(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java new file mode 100644 index 0000000000..4bf6cfa779 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MavenProjectProcessor.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import hudson.maven.MavenModuleSet; +import hudson.model.Job; + +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of Maven Plugin + */ +class MavenProjectProcessor extends AbstractProjectProcessor { + + MavenProjectProcessor(Job mavenJob) { + super((MavenModuleSet) mavenJob); + } + + @Override + protected void buildStructureInternal(Set processedJobs) { + // Internal phases - pre maven phases + // + super.processBuilders(this.job.getPrebuilders(), this.job, "pre-maven", processedJobs); + + // Internal phases - post maven phases + // + super.processBuilders(this.job.getPostbuilders(), this.job, "post-maven", processedJobs); + + // Post build phases + // + super.processPublishers(this.job, processedJobs); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java new file mode 100644 index 0000000000..a4430fe255 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/MultiJobProjectProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import com.tikal.jenkins.plugins.multijob.MultiJobProject; +import hudson.model.Job; +import hudson.tasks.Builder; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for discovery/provisioning of an internal phases/steps of the specific Job in context of MultiJob Plugin + */ +class MultiJobProjectProcessor extends AbstractProjectProcessor { + + MultiJobProjectProcessor(Job job) { + super((MultiJobProject) job); + } + + @Override + protected void buildStructureInternal(Set processedJobs) { + // Internal phases + // + super.processBuilders(this.job.getBuilders(), this.job, processedJobs); + + // Post build phases + // + super.processPublishers(this.job, processedJobs); + } + + @Override + public List tryGetBuilders() { + return job.getBuilders(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java new file mode 100644 index 0000000000..66b262a3c9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/UnsupportedProjectProcessor.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import hudson.model.Job; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 24/12/14 + * Time: 13:47 + * To change this template use File | Settings | File Templates. + */ + +class UnsupportedProjectProcessor extends AbstractProjectProcessor { + UnsupportedProjectProcessor(Job job) { + super(job); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java new file mode 100644 index 0000000000..ce98f6703a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/projects/WorkFlowJobProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.projects; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.*; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 24/12/14 + * Time: 13:40 + * To change this template use File | Settings | File Templates. + */ + +public class WorkFlowJobProcessor extends AbstractProjectProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(WorkFlowJobProcessor.class); + WorkFlowJobProcessor(Job job) { + super((WorkflowJob) job); + } + + public void scheduleBuild(Cause cause, ParametersAction parametersAction) { + int delay = this.job.getQuietPeriod(); + CauseAction causeAction = new CauseAction(cause); + this.job.scheduleBuild2(delay, parametersAction, causeAction); + } + + @Override + public String getTranslatedJobName() { + if (JobProcessorFactory.WORKFLOW_MULTI_BRANCH_JOB_NAME.equals(job.getParent().getClass().getName())) { + return BuildHandlerUtils.translateFolderJobName(job.getFullName()); + } else { + return super.getTranslatedJobName(); + } + } + + protected void stopBuild(Run run) { + WorkflowRun aBuild = (WorkflowRun)run; + try { + aBuild.doStop(); + logger.info("Build is stopped : " + aBuild.getParent().getDisplayName() + aBuild.getDisplayName()); + } catch (Exception e) { + logger.warn("Failed to stop build '" + aBuild.getDisplayName() + "' :" + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/CommonOriginRevision.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/CommonOriginRevision.java new file mode 100644 index 0000000000..7631cb3c85 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/CommonOriginRevision.java @@ -0,0 +1,40 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import java.io.Serializable; + +public class CommonOriginRevision implements Serializable { + public String branch; + public String revision; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java new file mode 100644 index 0000000000..762787b0d2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GenericSCMProcessor.java @@ -0,0 +1,136 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.scm.SCMChange; +import com.hp.octane.integrations.dto.scm.SCMCommit; +import com.hp.octane.integrations.dto.scm.SCMData; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.model.User; +import hudson.model.UserProperty; +import hudson.scm.ChangeLogSet; +import hudson.scm.SCM; +import hudson.tasks.Mailer; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by benmeior on 9/8/2016. + */ + +class GenericSCMProcessor implements SCMProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(GenericSCMProcessor.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + @Override + public SCMData getSCMData(AbstractBuild build, SCM scm) { + List> changes = new ArrayList<>(); + changes.add(build.getChangeSet()); + return extractSCMData(scm, changes); + } + + @Override + public SCMData getSCMData(WorkflowRun run, SCM scm) { + return extractSCMData(scm, run.getChangeSets()); + } + + @Override + public CommonOriginRevision getCommonOriginRevision(Run run) { + return null; + } + + private SCMData extractSCMData(SCM scm, List> changes) { + logger.info("building generic scm data for SCM of type " + scm.getType()); + + SCMRepository repository = buildScmRepository(); + List tmpCommits = extractCommits(changes); + + return dtoFactory.newDTO(SCMData.class) + .setRepository(repository) + .setCommits(tmpCommits); + } + + private List extractCommits(List> changes) { + List tmpCommits = new ArrayList<>(); + List tmpChanges; + SCMChange tmpChange; + + for (ChangeLogSet set : changes) { + for (ChangeLogSet.Entry change : set) { + User user = change.getAuthor(); + String userEmail = null; + + tmpChanges = new ArrayList<>(); + + for (ChangeLogSet.AffectedFile item : change.getAffectedFiles()) { + tmpChange = dtoFactory.newDTO(SCMChange.class) + .setType(item.getEditType().getName()) + .setFile(item.getPath()); + tmpChanges.add(tmpChange); + } + + for (UserProperty property : user.getAllProperties()) { + if (property instanceof Mailer.UserProperty) { + userEmail = ((Mailer.UserProperty) property).getAddress(); + } + } + SCMCommit tmpCommit = buildScmCommit(tmpChanges, change, userEmail); + tmpCommits.add(tmpCommit); + } + } + return tmpCommits; + } + + private SCMCommit buildScmCommit(List tmpChanges, ChangeLogSet.Entry commit, String userEmail) { + return dtoFactory.newDTO(SCMCommit.class) + .setTime(commit.getTimestamp()) + .setUser(commit.getAuthor().getId()) + .setUserEmail(userEmail) + .setRevId(commit.getCommitId()) + .setComment(commit.getMsg().trim()) + .setChanges(tmpChanges); + } + + private SCMRepository buildScmRepository() { + return dtoFactory.newDTO(SCMRepository.class) + .setType(SCMType.UNKNOWN); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java new file mode 100644 index 0000000000..21aa17af56 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/GitSCMProcessor.java @@ -0,0 +1,514 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.scm.*; +import com.hp.octane.integrations.dto.scm.impl.LineRange; +import com.hp.octane.integrations.dto.scm.impl.RevisionsMap; +import com.hp.octane.integrations.dto.scm.impl.SCMFileBlameImpl; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.FilePath; +import hudson.model.*; +import hudson.plugins.git.Branch; +import hudson.plugins.git.BranchSpec; +import hudson.plugins.git.GitChangeSet; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.extensions.GitSCMExtension; +import hudson.plugins.git.extensions.GitSCMExtensionDescriptor; +import hudson.plugins.git.extensions.impl.RelativeTargetDirectory; +import hudson.plugins.git.util.BuildData; +import hudson.remoting.VirtualChannel; +import hudson.scm.ChangeLogSet; +import hudson.scm.SCM; +import hudson.tasks.Mailer; +import hudson.util.DescribableList; +import jenkins.MasterToSlaveFileCallable; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.reflect.FieldUtils; +import org.apache.logging.log4j.Logger; +import org.eclipse.jgit.api.BlameCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.blame.BlameResult; +import org.eclipse.jgit.diff.*; +import org.eclipse.jgit.errors.NoMergeBaseException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.eclipse.jgit.util.io.DisabledOutputStream; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.*; + +/** + * Created by gullery on 31/03/2015. + */ + +class GitSCMProcessor implements SCMProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(GitSCMProcessor.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + private static final String MASTER = "refs/remotes/origin/master"; + + @Override + public SCMData getSCMData(AbstractBuild build, SCM scm) { + List> changes = new ArrayList<>(); + changes.add(build.getChangeSet()); + SCMData scmData = extractSCMData(build, scm, changes); + scmData = enrichLinesOnSCMData(scmData, build); + return scmData; + } + + /** + * this method go over each of the changed files and enrich line changes + * into existing scm events, so that the new enriched events will have line ranges. + * in addition, for each renamed file, we enrich inside delete event the 'renamed to' file + * + * @param scmData SCM data as an input + * @param build build context + */ + private SCMData enrichLinesOnSCMData(SCMData scmData, AbstractBuild build) { + long startTime = System.currentTimeMillis(); + try { + FilePath workspace = build.getWorkspace(); + if (workspace != null) { + scmData = workspace.act(new LineEnricherCallable(getCheckoutDir(build), scmData)); + logger.debug("Line enricher: process took: " + ((System.currentTimeMillis() - startTime) / 1000) + " seconds"); + } else { + logger.warn("Line enricher: workspace is null"); + } + } catch (Exception e1) { + logger.error("Line enricher: FAILED. could not enrich lines on SCM Data : " + e1.getMessage()); + } + return scmData; + } + + @Override + public SCMData getSCMData(WorkflowRun run, SCM scm) { + return extractSCMData(run, scm, run.getChangeSets()); + } + + @Override + public CommonOriginRevision getCommonOriginRevision(final Run run) { + //for phase 1 this is hard coded since its not possible to calculate it, and configuration from outside will complicate the feature + //so for this phase we keep it hardcoded. + CommonOriginRevision commonOriginRevision = new CommonOriginRevision(); + commonOriginRevision.branch = getBranchName(run); + + try { + final AbstractBuild abstractBuild = (AbstractBuild) run; + FilePath workspace = ((AbstractBuild) run).getWorkspace(); + if (workspace != null) { + commonOriginRevision.revision = workspace.act(new FileContentCallable(getCheckoutDir(abstractBuild))); + + } + logger.debug("most recent common revision resolved to " + commonOriginRevision.revision + " (branch: " + commonOriginRevision.branch + ")"); + } catch (Exception e) { + logger.error("failed to resolve most recent common revision : " + e.getClass().getName() + " - " + e.getMessage()); + return commonOriginRevision; + } + return commonOriginRevision; + } + + private SCMData extractSCMData(Run run, SCM scm, List> changes) { + if (!(scm instanceof GitSCM)) { + throw new IllegalArgumentException("GitSCM type of SCM was expected here, found '" + scm.getClass().getName() + "'"); + } + + GitSCM gitData = (GitSCM) scm; + SCMRepository repository; + List tmpCommits; + String builtRevId = null; + + repository = getRepository(run, gitData); + + BuildData buildData = gitData.getBuildData(run); + if (buildData != null && buildData.getLastBuiltRevision() != null) { + builtRevId = buildData.getLastBuiltRevision().getSha1String(); + } + + tmpCommits = extractCommits(changes); + return dtoFactory.newDTO(SCMData.class) + .setRepository(repository) + .setBuiltRevId(builtRevId) + .setCommits(tmpCommits); + } + + private String getBranchName(Run r) { + try { + SCM scm = ((AbstractBuild) r).getProject().getScm(); + GitSCM git = (GitSCM) scm; + List branches = git.getBranches(); + String rawBranchName = branches.get(0).toString(); + if (rawBranchName != null && rawBranchName.startsWith("${") && rawBranchName.endsWith("}")) { + String param = rawBranchName.substring(2, rawBranchName.length() - 1); + if (((AbstractBuild) r).getBuildVariables().get(param) != null) { + return ((AbstractBuild) r).getBuildVariables().get(param).toString(); + } else { + return param; + } + } + if (rawBranchName != null && rawBranchName.startsWith("*/")) { + return rawBranchName.substring(2); + } + return rawBranchName; //trunk the '*/' from the '*/' in order to get clean branch name + } catch (Exception e) { + logger.error("failed to extract branch name", e); + } + return null; + } + + private static String getCheckoutDir(AbstractBuild r) { + final DescribableList extensions = ((GitSCM) (r.getProject()).getScm()).getExtensions(); + if (extensions != null) { + final RelativeTargetDirectory relativeTargetDirectory = extensions.get(RelativeTargetDirectory.class); + if (relativeTargetDirectory != null && relativeTargetDirectory.getRelativeTargetDir() != null) { + return relativeTargetDirectory.getRelativeTargetDir(); + } + } + return ""; + } + + private SCMRepository getRepository(Run run, GitSCM gitData) { + SCMRepository result = null; + String url = null; + String branch = null; + if (gitData != null && gitData.getBuildData(run) != null) { + BuildData buildData = gitData.getBuildData(run); + if (buildData != null) { + if (buildData.getRemoteUrls() != null && !buildData.getRemoteUrls().isEmpty()) { + url = (String) buildData.getRemoteUrls().toArray()[0]; + } + if (buildData.getLastBuiltRevision() != null && !buildData.getLastBuiltRevision().getBranches().isEmpty()) { + branch = ((Branch) buildData.getLastBuiltRevision().getBranches().toArray()[0]).getName(); + } + result = dtoFactory.newDTO(SCMRepository.class) + .setType(SCMType.GIT) + .setUrl(url) + .setBranch(branch); + } else { + logger.warn("failed to obtain BuildData; no SCM repository info will be available"); + } + } + return result; + } + + private List extractCommits(List> changes) { + List commits = new LinkedList<>(); + for (ChangeLogSet set : changes) { + for (ChangeLogSet.Entry change : set) { + if (change instanceof GitChangeSet) { + GitChangeSet commit = (GitChangeSet) change; + List tmpChanges = new ArrayList<>(); + for (GitChangeSet.Path item : commit.getAffectedFiles()) { + SCMChange tmpChange = dtoFactory.newDTO(SCMChange.class) + .setType(item.getEditType().getName()) + .setFile(item.getPath()); + tmpChanges.add(tmpChange); + } + + SCMCommit tmpCommit = dtoFactory.newDTO(SCMCommit.class) + .setTime(commit.getTimestamp()) + .setRevId(commit.getCommitId()) + .setParentRevId(commit.getParentCommit()) + .setComment(commit.getComment().trim()) + .setChanges(tmpChanges); + + setUserInCommit(commit,tmpCommit); + commits.add(tmpCommit); + } + } + } + return commits; + } + + private void setUserInCommit(GitChangeSet commit, SCMCommit dtoCommit) { + User user = commit.getAuthor(); + String userName = user.getId(); + String userEmail = null; + for (UserProperty property : user.getAllProperties()) { + if (property instanceof Mailer.UserProperty) { + userEmail = ((Mailer.UserProperty) property).getAddress(); + } + } + + try { + //commits in github UI - returns with user "noreply" + if ("noreply".equals(userName)) { + String authorEmail = (String) FieldUtils.readField(commit, "authorEmail", true); + if (StringUtils.isNotEmpty(authorEmail) && authorEmail.contains("@")) { + userEmail = authorEmail; + userName = authorEmail.substring(0, authorEmail.indexOf('@')); + } + } + } catch (Exception e) { + logger.info("Failed to extract authorEmail : " + e.getMessage()); + } + + dtoCommit + .setUser(userName) + .setUserEmail(userEmail); + } + + private static final class FileContentCallable extends MasterToSlaveFileCallable { + private final String checkoutDir; + + private FileContentCallable(String checkoutDir) { + this.checkoutDir = checkoutDir; + } + + @Override + public String invoke(File rootDir, VirtualChannel channel) throws IOException { + File repoDir = new File(rootDir, checkoutDir + File.separator + ".git"); + try (Git git = Git.open(repoDir); + Repository repo = git.getRepository()) { + if (repo == null) { + return ""; + } + + try (RevWalk walk = new RevWalk(repo)) { + ObjectId resolveForCurrentBranch = repo.resolve(Constants.HEAD); + if (resolveForCurrentBranch == null) { + return ""; + } + + RevCommit currentBranchCommit = walk.parseCommit(resolveForCurrentBranch); + if (currentBranchCommit == null) { + return ""; + } + + ObjectId resolveForMaster = repo.resolve(MASTER); + if (resolveForMaster == null) { + return ""; + } + + RevCommit masterCommit = walk.parseCommit(resolveForMaster); + walk.reset(); + walk.setRevFilter(RevFilter.MERGE_BASE); + walk.markStart(currentBranchCommit); + walk.markStart(masterCommit); + RevCommit base = walk.next(); + if (base == null) { + return ""; + } + final RevCommit base2 = walk.next(); + if (base2 != null) { + throw new NoMergeBaseException(NoMergeBaseException.MergeBaseFailureReason.MULTIPLE_MERGE_BASES_NOT_SUPPORTED, + MessageFormat.format(JGitText.get().multipleMergeBasesFor, currentBranchCommit.name(), masterCommit.name(), base.name(), base2.name())); + } + + //in order to return actual revision and not merge commit + while (base.getParents().length > 1) { + RevCommit base_1 = base.getParent(0); + RevCommit base_2 = base.getParent(1); + if (base_1.getParents().length == 1) { + base = base_1; + } else { + base = base_2; + } + } + return base.getId().getName(); + } + } + } + } + + /*line enricher running on the same jenkins node that the job is running in it*/ + private static final class LineEnricherCallable extends MasterToSlaveFileCallable { + private final String checkoutDir; + private final SCMData scmData; + + private LineEnricherCallable(String checkoutDir, SCMData scmData) { + this.checkoutDir = checkoutDir; + this.scmData = scmData; + } + + @Override + public SCMData invoke(File rootDir, VirtualChannel channel) throws IOException { + File repoDir = new File(rootDir, checkoutDir + File.separator + ".git"); + try (Git git = Git.open(repoDir); + Repository repo = git.getRepository()) { + if (repo == null) { + return null; + } + + try (RevWalk rw = new RevWalk(repo); + DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE)) { + df.setDiffComparator(RawTextComparator.DEFAULT); + df.setRepository(repo); + df.setDetectRenames(true); + + //add blame data to scm data + Set committedFiles = getAddedOrEditedFiles(scmData); + List fileBlameList = getBlameData(repo, committedFiles); + scmData.setFileBlameList(fileBlameList); + + for (SCMCommit curCommit : scmData.getCommits()) { + Map fileChanges = new HashMap<>(); + curCommit.getChanges().forEach(change -> fileChanges.put(change.getFile(), change)); + RevCommit commit = rw.parseCommit(repo.resolve(curCommit.getRevId())); // Any ref will work here (HEAD, a sha1, tag, branch) + RevCommit parent = rw.parseCommit(commit.getParent(0).getId()); + + List diffs = df.scan(parent.getTree(), commit.getTree()); + // FOR EACH FILE + for (DiffEntry diff : diffs) { // each file change will be in seperate diff + EditList fileEdits = df.toFileHeader(diff).toEditList(); + switch (diff.getChangeType()) { + case ADD: + // old path == null, need to use new path + handleAddLinesDiff(fileEdits, fileChanges.get(diff.getNewPath())); + break; + case COPY: + // need to validate this type + handleModifyDiff(fileEdits, fileChanges.get(diff.getNewPath())); + break; + case DELETE: + // new path == null, need to use old path + handleDeleteLinesDiff(fileEdits, fileChanges.get(diff.getOldPath())); + break; + case MODIFY: + handleModifyDiff(fileEdits, fileChanges.get(diff.getNewPath())); + break; + case RENAME: + // enrich delete event with 'rename to' data + SCMChange deletedChange = fileChanges.get(diff.getOldPath()); + SCMChange newRenamedFile = fileChanges.get(diff.getNewPath()); + deletedChange.setRenamedToFile(newRenamedFile.getFile()); + // handle changes + handleModifyDiff(fileEdits, fileChanges.get(diff.getNewPath())); + break; + default: + break; + } + } + } + return scmData; + } + } + } + } + + private static Set getAddedOrEditedFiles(SCMData scmData) { + Set filesCommittedInPPR = new HashSet<>(); + for (SCMCommit curCommit : scmData.getCommits()) { + curCommit.getChanges().stream().filter(change -> !change.getType().equals("delete")).forEach(change -> filesCommittedInPPR.add(change.getFile())); + } + return filesCommittedInPPR; + } + + private static List getBlameData(Repository repo, Set files) { + BlameCommand blamer = new BlameCommand(repo); + List fileBlameList = new ArrayList<>(); + ObjectId commitID; + try { + commitID = repo.resolve(Constants.HEAD); + for (String filePath : files) { + blamer.setStartCommit(commitID); + blamer.setFilePath(filePath); + BlameResult blameResult = blamer.call(); + if (blameResult == null) { + continue; + } + RawText rawText = blameResult.getResultContents(); + int fileSize = rawText.size(); + + RevisionsMap revisionsMap = new RevisionsMap(); + + if (fileSize > 0) { + String startRangeRevision = blameResult.getSourceCommit(0).getName(); + int startRange = 1; + for (int i = 1; i < fileSize; i++) { + String currentRevision = blameResult.getSourceCommit(i).getName(); + if (!currentRevision.equals(startRangeRevision)) { + LineRange range = new LineRange(startRange, i);//line numbers starting from 1 not from 0. + revisionsMap.addRangeToRevision(startRangeRevision, range); + startRange = i + 1; + startRangeRevision = currentRevision; + } + } + } + fileBlameList.add(new SCMFileBlameImpl(filePath, revisionsMap)); + } + } catch (IOException e) { + logger.error("failed to resolve repo head", e); + } catch (GitAPIException e) { + logger.error("failed to get blame result from git", e); + } + return fileBlameList; + } + + private static void handleModifyDiff(EditList fileEdits, SCMChange scmChange) { + if (scmChange != null) { + for (Edit edit : fileEdits) { + switch (edit.getType()) { + case INSERT: + scmChange.insertAddedLines(new LineRange(edit.getBeginB() + 1, edit.getEndB())); + break; + case DELETE: + scmChange.insertDeletedLines(new LineRange(edit.getBeginA() + 1, edit.getEndA())); + break; + case REPLACE: + scmChange.insertDeletedLines(new LineRange(edit.getBeginA() + 1, edit.getEndA())); + scmChange.insertAddedLines(new LineRange(edit.getBeginB() + 1, edit.getEndB())); + break; + default: + break; + } + } + } + } + + // probably it's useless to track deleted lines (inside scm change), consider removing it later. + private static void handleDeleteLinesDiff(EditList fileEdits, SCMChange scmChange) { + if (scmChange != null) { + for (Edit edit : fileEdits) { + scmChange.insertDeletedLines(new LineRange(edit.getBeginA() + 1, edit.getEndA())); + } + } + } + + private static void handleAddLinesDiff(EditList fileEdits, SCMChange scmChange) { + if (scmChange != null) { + for (Edit edit : fileEdits) { + scmChange.insertAddedLines(new LineRange(edit.getBeginB() + 1, edit.getEndB())); + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessor.java new file mode 100644 index 0000000000..ac3be4bfb7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessor.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.hp.octane.integrations.dto.scm.SCMData; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.scm.SCM; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +/** + * API definition for SCM content processor/transformer for an Octane context + * Created by gullery on 31/03/2015. + */ + +public interface SCMProcessor { + SCMData getSCMData(AbstractBuild build, SCM scm); + + SCMData getSCMData(WorkflowRun run, SCM scm); + + CommonOriginRevision getCommonOriginRevision(Run run); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessors.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessors.java new file mode 100644 index 0000000000..86a0d441c7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMProcessors.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import org.apache.logging.log4j.Logger; + +/** + * Created by gullery on 31/03/2015. + */ + +public enum SCMProcessors { + NONE("hudson.scm.NullSCM", null), + GIT("hudson.plugins.git.GitSCM", GitSCMProcessor.class), + SVN("hudson.scm.SubversionSCM", SvnSCMProcessor.class), + STARTEAM("hudson.plugins.starteam.StarTeamSCM", StarTeamSCMProcessor.class); + + private static Logger logger = SDKBasedLoggerProvider.getLogger(SCMProcessors.class); + private String targetSCMPluginClassName; + private Class processorClass; + + SCMProcessors(String targetSCMPluginClassName, Class processorClass) { + this.targetSCMPluginClassName = targetSCMPluginClassName; + this.processorClass = processorClass; + } + + public static SCMProcessor getAppropriate(String className) { + SCMProcessor result = null; + + // skip any processing if NULL SCM declared + if (!className.startsWith(NONE.targetSCMPluginClassName)) { + for (SCMProcessors p : values()) { + if (className.startsWith(p.targetSCMPluginClassName)) + try { + result = p.processorClass.newInstance(); + break; + } catch (InstantiationException | IllegalAccessException e) { + logger.error("failed to instantiate SCM processor of type '" + p.targetSCMPluginClassName, e); + } + } + if (result == null) { + result = getGenericSCMProcessor(className); + } + } + + return result; + } + + private static SCMProcessor getGenericSCMProcessor(String className) { + SCMProcessor genericSCMProcessor = null; + try { + genericSCMProcessor = (GenericSCMProcessor.class).newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + logger.error("failed to instantiate SCM processor of type '" + className, e); + } + return genericSCMProcessor; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMUtils.java new file mode 100644 index 0000000000..06ff538ac4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SCMUtils.java @@ -0,0 +1,96 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.scm.SCMData; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.FilePath; +import hudson.matrix.MatrixConfiguration; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.scm.SCM; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class SCMUtils { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(SCMUtils.class); + + private static final String SCM_DATA_FILE = "scmdata.json"; + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + private SCMUtils() { + //code climate : Add a private constructor to hide the implicit public one + } + + public static SCMData extractSCMData(Run run, SCM scm, SCMProcessor scmProcessor) { + SCMData result = null; + if (run.getParent() instanceof MatrixConfiguration || run instanceof AbstractBuild) { + AbstractBuild build = (AbstractBuild) run; + if (!build.getChangeSet().isEmptySet()) { + result = scmProcessor.getSCMData(build, scm); + } + } else if (run instanceof WorkflowRun) { + WorkflowRun wRun = (WorkflowRun) run; + if (!wRun.getChangeSets().isEmpty()) { + result = scmProcessor.getSCMData(wRun, scm); + } + } + return result; + } + + public static void persistSCMData(Run run, String jobCiId, String buildCiId, SCMData scmData) throws IOException, InterruptedException { + FilePath resultFile = new FilePath(run.getRootDir()).child(SCM_DATA_FILE); + List scmDataList = new ArrayList<>(); + scmDataList.add(scmData); + String scmDataContent = dtoFactory.dtoCollectionToJson(scmDataList); + + try { + resultFile.write(scmDataContent, "UTF-8"); + } catch (IOException | InterruptedException e) { + logger.error("Failed to persist SCMData for jobCiId " + jobCiId + " buildCiId " + buildCiId, e); + throw e; + } + } + + public static InputStream getSCMData(Run run) throws IOException, InterruptedException { + FilePath resultFile = new FilePath(run.getRootDir()).child(SCM_DATA_FILE); + return resultFile.read(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/StarTeamSCMProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/StarTeamSCMProcessor.java new file mode 100644 index 0000000000..b84e5ec8e2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/StarTeamSCMProcessor.java @@ -0,0 +1,266 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.scm.SCMChange; +import com.hp.octane.integrations.dto.scm.SCMCommit; +import com.hp.octane.integrations.dto.scm.SCMData; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.model.User; +import hudson.model.UserProperty; +import hudson.scm.ChangeLogSet; +import hudson.scm.EditType; +import hudson.scm.SCM; +import hudson.scm.ChangeLogSet.Entry; +import hudson.tasks.Mailer; + +class StarTeamSCMProcessor implements SCMProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(StarTeamSCMProcessor.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + @Override + public SCMData getSCMData(AbstractBuild build, SCM scm) { + List> changes = new ArrayList<>(); + changes.add(build.getChangeSet()); + return extractSCMData(build, scm, changes); + } + + @Override + public SCMData getSCMData(WorkflowRun run, SCM scm) { + return extractSCMData(run, scm, run.getChangeSets()); + } + + @Override + public CommonOriginRevision getCommonOriginRevision(final Run run) { + return null; + } + + private SCMData extractSCMData(Run run, SCM scm, List> changes) { + if (!(scm.getClass().getName().equals("hudson.plugins.starteam.StarTeamSCM"))) { + throw new IllegalArgumentException("SCM type of StarTeamSCM was expected here, found '" + scm.getClass().getName() + "'"); + } + + SCMRepository repository = getRepository(scm); + List commits = extractCommits(changes); + + return dtoFactory.newDTO(SCMData.class) + .setRepository(repository) + .setCommits(commits); + } + + private SCMRepository getRepository(SCM starTeamSCM) { + SCMRepository result = null; + if (starTeamSCM != null) { + try { + String url = getSCMRepositoryURL(starTeamSCM); + String branch = getSCMRepositoryBranch(starTeamSCM); + result = dtoFactory.newDTO(SCMRepository.class).setType(SCMType.STARTEAM).setUrl(url).setBranch(branch); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + logger.warn(e.getClass().getSimpleName() + " unable to extract data from starTeamSCM, no SCM repository info will be available.", e); + } + } else { + logger.warn("starTeamSCM is null, no SCM repository info will be available."); + } + return result; + } + + private List extractCommits(List> changes) { + LinkedList tmpCommits = new LinkedList<>(); + + for (ChangeLogSet set : changes) { + for (ChangeLogSet.Entry change : set) { + if (change.getClass().getName().equals("hudson.plugins.starteam.changelog.StarTeamChangeLogEntry")) { + List tmpChanges = new ArrayList<>(); + User user = change.getAuthor(); + String userEmail = null; + + SCMChange tmpChange; + try { + tmpChange = dtoFactory.newDTO(SCMChange.class) + .setType(getCommitType(change)) + .setFile(getFileName(change)); + tmpChanges.add(tmpChange); + + for (UserProperty property : user.getAllProperties()) { + if (property instanceof Mailer.UserProperty) { + userEmail = ((Mailer.UserProperty) property).getAddress(); + } + } + + SCMCommit tmpCommit = dtoFactory.newDTO(SCMCommit.class) + .setTime(getDate(change).getTime()) + .setUserEmail(userEmail) + .setUser(change.getAuthor().getId()) + .setRevId(getRevision(change)) + .setComment(getComment(change)) + .setChanges(tmpChanges); + + tmpCommits.add(tmpCommit); + } catch (Exception e) { + logger.warn("failed to obtain commit information", e); + } + } + } + } + return tmpCommits; + } + + private Object callMethodViaReflection(Object object, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Class cls = object.getClass(); + Method methodTocall = cls.getDeclaredMethod(methodName); + Object returnValue = methodTocall.invoke(object); + return returnValue; + } + + private String getSCMRepositoryBranch(SCM starTeamSCM) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { + String branch; + if (usingStarTeamURL(starTeamSCM)) + branch = ""; + else { + branch = getViewName(starTeamSCM); + } + return branch; + } + + private String getViewName(SCM starTeamSCM) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(starTeamSCM, "getViewName"); + return (String) returnValue; + } + + private String getSCMRepositoryURL(SCM starTeamSCM) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + String url; + if (usingStarTeamURL(starTeamSCM)) { + Object returnValue = callMethodViaReflection(starTeamSCM, "getStFolderUrl"); + url = (String) returnValue; + } + else { + String hostname = getHostName(starTeamSCM); + String port = getPort(starTeamSCM); + String projectName = getProjectNamer(starTeamSCM); + url = hostname + ":" + port + "/" + projectName; + } + return url; + } + + private String getProjectNamer(SCM starTeamSCM) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(starTeamSCM, ("getProjectName")); + return (String) returnValue; + } + + private String getPort(SCM starTeamSCM) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(starTeamSCM, ("getPort")); + return (String) returnValue; + } + + private String getHostName(SCM starTeamSCM) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(starTeamSCM, ("getHostName")); + return (String) returnValue; + } + + private boolean usingStarTeamURL(SCM starTeamSCM) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Object returnValue = callMethodViaReflection(starTeamSCM, ("getStFolderUrl")); + String getStFolderUrl = (String) returnValue; + return getStFolderUrl != null && !getStFolderUrl.isEmpty(); + } + + private String getFileName(Entry change) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { + Object returnValue = callMethodViaReflection(change, ("getFileName")); + return (String) returnValue; + } + + private Date getDate(Entry change) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { + Object returnValue = callMethodViaReflection(change, ("getDate")); + return (Date) returnValue; + } + + private String getRevision(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException { + Integer viewMemberID = getViewMemberID(commit); + Integer revisionNumber = getRevisionNumber(commit); + String changeType = getChangeType(commit); + String revID = "VMID: " + viewMemberID + " " + "Rev: " + revisionNumber; + + if (changeType.equals("DELETE")) { + revID = revID + " (deleted)"; + } + return revID; + } + + private String getChangeType(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException { + Object changeType = callMethodViaReflection(commit, ("getChangeType")); + return changeType.toString(); + } + + private Integer getRevisionNumber(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(commit, ("getRevisionNumber")); + return (Integer) returnValue; + } + + private Integer getViewMemberID(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Object returnValue = callMethodViaReflection(commit, ("getViewMemberId")); + return (Integer) returnValue; + } + + private String getComment(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException { + String changeType = getChangeType(commit); + if (changeType.equals("DELETE")) { + return "File deleted"; + } else + return commit.getMsg(); + } + + private String getCommitType(ChangeLogSet.Entry commit) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, SecurityException { + String changeType = getChangeType(commit); + if ("ADD".equals(changeType)) { + return EditType.ADD.getName(); + } else if ("DELETE".equals(changeType)) { + return EditType.DELETE.getName(); + } else if ("MODIFIED".equals(changeType)) { + return EditType.EDIT.getName(); + } + return null; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java new file mode 100644 index 0000000000..4a5894ab44 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/model/processors/scm/SvnSCMProcessor.java @@ -0,0 +1,184 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model.processors.scm; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.scm.SCMChange; +import com.hp.octane.integrations.dto.scm.SCMCommit; +import com.hp.octane.integrations.dto.scm.SCMData; +import com.hp.octane.integrations.dto.scm.SCMRepository; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.*; +import hudson.scm.ChangeLogSet; +import hudson.scm.SCM; +import hudson.scm.SVNRevisionState; +import hudson.scm.SubversionChangeLogSet; +import hudson.scm.SubversionSCM; +import hudson.tasks.Mailer; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by benmeior on 5/15/2016. + */ + +class SvnSCMProcessor implements SCMProcessor { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(SvnSCMProcessor.class); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + private static final int PARENT_COMMIT_INDEX = 1; + + @Override + public SCMData getSCMData(AbstractBuild build, SCM scm) { + List> changes = new ArrayList<>(); + changes.add(build.getChangeSet()); + return extractSCMData(build, scm, changes); + } + + @Override + public SCMData getSCMData(WorkflowRun run, SCM scm) { + return extractSCMData(run, scm, run.getChangeSets()); + } + + @Override + public CommonOriginRevision getCommonOriginRevision(Run run) { + return null; + } + + private SCMData extractSCMData(Run run, SCM scm, List> changes) { + if (!(scm instanceof SubversionSCM)) { + throw new IllegalArgumentException("SubversionSCM type of SCM was expected here, found '" + scm.getClass().getName() + "'"); + } + + SubversionSCM svnData = (SubversionSCM) scm; + SCMRepository repository; + List tmpCommits; + String builtRevId; + + repository = getSCMRepository(svnData); + builtRevId = getBuiltRevId(run, svnData, repository.getUrl()); + tmpCommits = extractCommits(changes); + + return dtoFactory.newDTO(SCMData.class) + .setRepository(repository) + .setBuiltRevId(builtRevId) + .setCommits(tmpCommits); + } + + private List extractCommits(List> changes) { + List tmpCommits; + List tmpChanges; + SCMChange tmpChange; + tmpCommits = new LinkedList<>(); + for (ChangeLogSet set : changes) { + for (ChangeLogSet.Entry change : set) { + if (change instanceof SubversionChangeLogSet.LogEntry) { + SubversionChangeLogSet.LogEntry commit = (SubversionChangeLogSet.LogEntry) change; + User user = commit.getAuthor(); + String userEmail = null; + + tmpChanges = new ArrayList<>(); + for (SubversionChangeLogSet.Path item : commit.getAffectedFiles()) { + tmpChange = dtoFactory.newDTO(SCMChange.class) + .setType(item.getEditType().getName()) + .setFile(item.getValue()); + tmpChanges.add(tmpChange); + } + + for (UserProperty property : user.getAllProperties()) { + if (property instanceof Mailer.UserProperty) { + userEmail = ((Mailer.UserProperty) property).getAddress(); + } + } + + String parentRevId = getParentRevId(commit); + + SCMCommit tmpCommit = dtoFactory.newDTO(SCMCommit.class) + .setTime(commit.getTimestamp()) + .setUser(commit.getAuthor().getId()) + .setUserEmail(userEmail) + .setRevId(commit.getCommitId()) + .setParentRevId(parentRevId) + .setComment(commit.getMsg().trim()) + .setChanges(tmpChanges); + tmpCommits.add(tmpCommit); + } + } + } + return tmpCommits; + } + + private String getBuiltRevId(Run run, SubversionSCM svnData, String svnRepositoryUrl) { + String builtRevId = null; + try { + SVNRevisionState revisionState = (SVNRevisionState) svnData.calcRevisionsFromBuild(run, null, null, null); + if (revisionState != null) { + builtRevId = String.valueOf(revisionState.getRevision(svnRepositoryUrl)); + } + } catch (IOException | InterruptedException e) { + logger.error("failed to get revision state", e); + } + return builtRevId; + } + + private static String getParentRevId(SubversionChangeLogSet.LogEntry commit) { + String parentRevId = null; + + try { + if (commit.getParent() != null && commit.getParent().getLogs() != null && commit.getParent().getLogs().size() > PARENT_COMMIT_INDEX) { + parentRevId = commit.getParent().getLogs().get(PARENT_COMMIT_INDEX).getCommitId(); + } else { + logger.info("parent rev ID is not available in the commit's logs"); + } + } catch (Exception e) { + logger.error("failed to retrieve parentRevId", e); + } + + return parentRevId; + } + + private static SCMRepository getSCMRepository(SubversionSCM svnData) { + String url = null; + if (svnData.getLocations().length > 0 && svnData.getLocations()[0] != null) { + url = svnData.getLocations()[0].getURL(); + } + return dtoFactory.newDTO(SCMRepository.class) + .setType(SCMType.SVN) + .setUrl(url); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder.java b/src/main/java/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder.java new file mode 100644 index 0000000000..c95434c661 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder.java @@ -0,0 +1,345 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.octaneExecution; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.parameters.CIParameters; +import com.hp.octane.integrations.exceptions.ConfigurationException; +import com.hp.octane.integrations.exceptions.PermissionException; +import com.hp.octane.integrations.octaneExecution.ExecutionMode; +import com.hp.octane.integrations.services.SupportsConsoleLog; +import com.hp.octane.integrations.services.testexecution.TestExecutionContext; +import com.hp.octane.integrations.services.testexecution.TestExecutionService; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.ImpersonationUtil; +import com.microfocus.application.automation.tools.octane.JellyUtils; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.testrunner.TestsToRunConverterBuilder; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.model.queue.QueueTaskFuture; +import hudson.security.ACLContext; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.ListBoxModel; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Execute tests in Octane + */ +public class ExecuteTestsInOctaneBuilder extends Builder implements SimpleBuildStep { + + private String configurationId; + private String executionMode; + private String ids; + private String workspaceId; + + @DataBoundConstructor + public ExecuteTestsInOctaneBuilder(String configurationId, String workspaceId, String executionMode, String ids) { + this.configurationId = JellyUtils.NONE.equalsIgnoreCase(configurationId) ? null : configurationId; + this.workspaceId = JellyUtils.NONE.equalsIgnoreCase(workspaceId) ? null : workspaceId; + this.executionMode = executionMode; + this.ids = ids; + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { + SupportsConsoleLog supportsConsoleLog = new SupportsConsoleLogImpl(listener); + supportsConsoleLog.println("Start **********************************************************************************************"); + supportsConsoleLog.println(""); + if (configurationId == null) { + throw new IllegalArgumentException("ALM Octane configuration is not defined."); + } + if (workspaceId == null) { + throw new IllegalArgumentException("ALM Octane workspace is not defined."); + } + + + String myConfigurationId = configurationId; + String myWorkspaceId = workspaceId; + String myExecutionMode = executionMode; + String myIds = ids; + try { + EnvVars env = build.getEnvironment(listener); + myConfigurationId = env.expand(configurationId); + myWorkspaceId = env.expand(workspaceId); + myExecutionMode = env.expand(executionMode); + myIds = env.expand(ids); + } catch (IOException | InterruptedException e) { + listener.error("Failed loading build environment " + e); + } + + Long myWorkspaceIdAsLong; + try { + myWorkspaceIdAsLong = Long.parseLong(myWorkspaceId); + } catch (Exception e) { + throw new RuntimeException("Failed to convert workspace to long : " + myWorkspaceId); + } + + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(myConfigurationId); + TestExecutionService testExecutionService = octaneClient.getTestExecutionService(); + List suiteIds = Arrays.stream(myIds.split(",")) + .map(str -> str.trim()).filter(str -> StringUtils.isNotEmpty(str) && StringUtils.isNumeric(str)) + .map(str -> Long.parseLong(str.trim())).distinct().collect(Collectors.toList()); + try { + testExecutionService.validateAllSuiteIdsExistAndReturnSuiteNames(myWorkspaceIdAsLong, suiteIds); + } catch (IllegalArgumentException e) { + listener.error(e.getMessage()); + build.setResult(Result.FAILURE); + return; + } + ParametersAction parameterAction = build.getAction(ParametersAction.class); + + switch (ExecutionMode.fromValue(myExecutionMode)) { + case SUITE_RUNS_IN_OCTANE: + + Long optionalReleaseId = getLongValueParameter(parameterAction, "octane_release_id"); + String optionalSuiteRunName = getStringValueParameter(parameterAction, "octane_new_suite_run_name"); + testExecutionService.executeSuiteRuns(myWorkspaceIdAsLong, suiteIds, optionalReleaseId, optionalSuiteRunName, supportsConsoleLog); + break; + + case SUITE_IN_CI: + List testExecutions = testExecutionService.prepareTestExecutionForSuites(myWorkspaceIdAsLong, suiteIds, supportsConsoleLog); + ACLContext securityContext = ImpersonationUtil.startImpersonation(myConfigurationId, null); + Map> futures = new HashMap<>(); + try { + + testExecutions.forEach(testExecution -> { + AbstractProject project = getJobFromTestRunner(testExecution); + try { + supportsConsoleLog.print(String.format("%s %s, triggering test runner '%s' (%s tests): " + , testExecution.getIdentifierType().getName() + , testExecution.getIdentifier() + , testExecution.getTestRunner().getName() + , testExecution.getTests().size() + )); + listener.hyperlink("/job/" + project.getFullName().replace("/", "/job/"), project.getFullName()); + supportsConsoleLog.newLine(); + } catch (IOException e) { + throw new RuntimeException("Failed to print link to triggered job : " + e.getMessage()); + } + int delay = 0; + + Cause cause = new Cause.UpstreamCause(build); + CIParameter testsToRunParam = DTOFactory.getInstance().newDTO(CIParameter.class) + .setName(TestsToRunConverterBuilder.TESTS_TO_RUN_PARAMETER) + .setValue(testExecution.getTestsToRun()) + .setType(CIParameterType.STRING); + CIParameters ciParams = DTOFactory.getInstance().newDTO(CIParameters.class); + ciParams.setParameters(Collections.singletonList(testsToRunParam)); + ParametersAction parametersAction = new ParametersAction(CIJenkinsServicesImpl.createParameters(project, ciParams)); + + QueueTaskFuture future = project.scheduleBuild2(delay, cause, parametersAction); + futures.put(testExecution, future); + }); + } finally { + ImpersonationUtil.stopImpersonation(securityContext); + } + + //WAIT UNTIL ALL JOBS ARE FINISHED and set build result based on worse result + supportsConsoleLog.println("Waiting for test runners to finish ... "); + Result buildResult = Result.SUCCESS; + for (Map.Entry> entry : futures.entrySet()) { + try { + + //TODO check status + AbstractBuild buildFromFuture = entry.getValue().get(); + try { + supportsConsoleLog.print("Build "); + String url = "/job/" + buildFromFuture.getProject().getFullName().replace("/", "/job/") + "/" + buildFromFuture.getNumber(); + listener.hyperlink(url, buildFromFuture.getProject().getFullName() + " " + buildFromFuture.getDisplayName()); + supportsConsoleLog.append(" - " + buildFromFuture.getResult()); + supportsConsoleLog.newLine(); + } catch (IOException e) { + throw new RuntimeException("Failed to print link to triggered job : " + e.getMessage()); + } + + if (buildFromFuture.getResult().isWorseThan(buildResult)) { + buildResult = buildFromFuture.getResult(); + } + + } catch (Exception e) { + //TODO CHECK WHAT TO DO HERE + throw new RuntimeException("Failed in waiting for job finishing : " + e.getMessage()); + } + } + if (buildResult.isWorseThan(Result.SUCCESS)) { + build.setResult(buildResult); + } + break; + default: + throw new RuntimeException("not supported execution mode"); + } + } + + private AbstractProject getJobFromTestRunner(TestExecutionContext testExecution) { + String ciJobName = testExecution.getTestRunner().getEntityValue("ci_job").getName(); + Job job = (Job) Jenkins.get().getItemByFullName(ciJobName); + if (job != null) { + if (job instanceof AbstractProject && ((AbstractProject) job).isDisabled()) { + //disabled job is not runnable and in this context we will handle it as 404 + throw new ConfigurationException("Job is disabled " + ciJobName, HttpStatus.SC_NOT_FOUND); + } + boolean hasBuildPermission = job.hasPermission(Item.BUILD); + if (!hasBuildPermission) { + throw new PermissionException("No permission to run job " + ciJobName, HttpStatus.SC_FORBIDDEN); + } + if (job instanceof AbstractProject || job.getClass().getName().equals(JobProcessorFactory.WORKFLOW_JOB_NAME)) { + + } + } else { + throw new ConfigurationException("Job is not found " + ciJobName, HttpStatus.SC_NOT_FOUND); + } + + return (AbstractProject) job; + } + + private Long getLongValueParameter(ParametersAction parameterAction, String paramName) { + if (parameterAction == null) { + return null; + } + ParameterValue pv = parameterAction.getParameter(paramName); + if (pv != null && pv.getValue() instanceof String) { + try { + return Long.valueOf((String) pv.getValue()); + } catch (Exception e) { + return null; + } + } + return null; + } + + private String getStringValueParameter(ParametersAction parameterAction, String paramName) { + if (parameterAction == null) { + return null; + } + ParameterValue pv = parameterAction.getParameter(paramName); + if (pv != null && pv.getValue() instanceof String) { + return (String) pv.getValue(); + } + return null; + } + + public String getConfigurationId() { + return configurationId; + } + + public String getWorkspaceId() { + return workspaceId; + } + + public String getExecutionMode() { + return executionMode; + } + + public String getIds() { + return ids; + } + + public static class SupportsConsoleLogImpl implements SupportsConsoleLog { + TaskListener listener; + + public SupportsConsoleLogImpl(TaskListener listener) { + this.listener = listener; + } + + public void println(String msg) { + listener.getLogger().println(ExecuteTestsInOctaneBuilder.class.getSimpleName() + " : " + msg); + } + + public void print(String msg) { + listener.getLogger().print(ExecuteTestsInOctaneBuilder.class.getSimpleName() + " : " + msg); + } + + public void append(String msg) { + listener.getLogger().print(msg); + } + + public void newLine() { + listener.getLogger().println(); + } + } + + @Symbol("executeTestsFromAlmOctane") + @Extension + public static class Descriptor extends BuildStepDescriptor { + + @Override + public boolean isApplicable(Class jobType) { + return true;//FreeStyleProject.class.isAssignableFrom(jobType); + } + + @Override + public String getDisplayName() { + return "Execute tests from ALM Octane (Tech Preview)"; + } + + + public ListBoxModel doFillExecutionModeItems() { + ListBoxModel m = new ListBoxModel(); + for (ExecutionMode mode : ExecutionMode.values()) { + m.add(mode.description(), mode.value()); + } + + return m; + } + + public ListBoxModel doFillConfigurationIdItems() { + return JellyUtils.fillConfigurationIdModel(); + } + + public ListBoxModel doFillWorkspaceIdItems(@QueryParameter String configurationId, @QueryParameter(value = "workspaceId") String workspaceId) { + return JellyUtils.fillWorkspaceModel(configurationId, workspaceId); + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction.java new file mode 100644 index 0000000000..0557bfa3bd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction.java @@ -0,0 +1,140 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.pullrequests; + +import com.hp.octane.integrations.dto.scm.PullRequest; +import com.hp.octane.integrations.dto.scm.SCMCommit; +import com.microfocus.application.automation.tools.octane.GitFetchUtils; +import com.microfocus.application.automation.tools.octane.Messages; +import hudson.model.Action; +import hudson.model.Run; + +import javax.annotation.CheckForNull; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +public class PullRequestBuildAction implements Action { + + private final Run build; + + private final List pullRequests; + private final long minUpdateTime; + private final String sourceBranchFilter; + private final String targetBranchFilter; + private final String repositoryUrl; + private final Long index; + + private SimpleDateFormat dateFormat = null; + + @CheckForNull + @Override + public String getIconFileName() { + return "notepad.png"; + } + + public PullRequestBuildAction(final Run build, List pullRequests, String repositoryUrl, long minUpdateTime, + String sourceBranchFilter, String targetBranchFilter, long index) { + this.build = build; + this.index = index; + this.pullRequests = pullRequests; + this.minUpdateTime = minUpdateTime; + this.sourceBranchFilter = sourceBranchFilter; + this.targetBranchFilter = targetBranchFilter; + this.repositoryUrl = repositoryUrl; + } + + @CheckForNull + @Override + public String getDisplayName() { + return Messages.PullRequestActionConfigurationLabel(); + } + + @CheckForNull + @Override + public String getUrlName() { + return "pull-request-report" + (index == null || index.equals(0l) ? "" : "-" + index); + } + + public List getPullRequests() { + return pullRequests; + } + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + public String getFormattedDate(long longTime) { + if (dateFormat == null) { + dateFormat = GitFetchUtils.generateDateFormat(); + } + return dateFormat.format(new Date(longTime)); + } + + public String getTopCommits(PullRequest p) { + StringBuilder sb = new StringBuilder(); + int counter = 0; + int max_detailed_count = 10; + int max_commit_message_size = 50; + for (SCMCommit commit : p.getCommits()) { + sb.append(commit.getComment(), 0, Math.min(max_commit_message_size, commit.getComment().length())); + if (commit.getComment().length() > max_commit_message_size) { + sb.append("..."); + } + sb.append("\n"); + counter++; + if (counter >= max_detailed_count) { + sb.append("And other " + (p.getCommits().size() - max_detailed_count) + " commits"); + break; + } + } + return sb.toString(); + } + + public long getMinUpdateTime() { + return minUpdateTime; + } + + public String getSourceBranchFilter() { + return sourceBranchFilter; + } + + public String getTargetBranchFilter() { + return targetBranchFilter; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher.java b/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher.java new file mode 100644 index 0000000000..8bf914e57a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher.java @@ -0,0 +1,346 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.pullrequests; + +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.scm.PullRequest; +import com.hp.octane.integrations.exceptions.OctaneValidationException; +import com.hp.octane.integrations.exceptions.ResourceNotFoundException; +import com.hp.octane.integrations.services.pullrequestsandbranches.PullRequestAndBranchService; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.FetchFactory; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.FetchHandler; +import com.hp.octane.integrations.services.pullrequestsandbranches.factory.PullRequestFetchParameters; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.ScmTool; +import com.hp.octane.integrations.services.pullrequestsandbranches.rest.authentication.AuthenticationStrategy; +import com.microfocus.application.automation.tools.octane.GitFetchUtils; +import com.microfocus.application.automation.tools.octane.JellyUtils; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.ListBoxModel; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; +import java.util.function.Consumer; + +/** + * Post-build action of Uft test detection + */ + +public class PullRequestPublisher extends Recorder implements SimpleBuildStep { + private String configurationId; + private String workspaceId; + private String repositoryUrl; + private String credentialsId; + private String sourceBranchFilter; + private String targetBranchFilter; + private String scmTool; + private String useSSHFormat; + + // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" + @DataBoundConstructor + public PullRequestPublisher(String configurationId, String workspaceId, String scmTool, String repositoryUrl, String credentialsId, String sourceBranchFilter, String targetBranchFilter) { + this.configurationId = JellyUtils.NONE.equalsIgnoreCase(configurationId) ? null : configurationId; + this.workspaceId = JellyUtils.NONE.equalsIgnoreCase(workspaceId) ? null : workspaceId; + this.repositoryUrl = repositoryUrl; + this.credentialsId = credentialsId; + this.sourceBranchFilter = sourceBranchFilter; + this.targetBranchFilter = targetBranchFilter; + this.scmTool = JellyUtils.NONE.equalsIgnoreCase(scmTool) ? null : scmTool; + } + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) throws InterruptedException, IOException { + performInternal(run, taskListener); + } + + @Override + public boolean perform(AbstractBuild build, @Nonnull Launcher launcher, BuildListener listener) { + performInternal(build, listener); + return build.getResult() == Result.SUCCESS; + } + + public void performInternal(@Nonnull Run run, @Nonnull TaskListener taskListener) { + LogConsumer logConsumer = new LogConsumer(taskListener.getLogger()); + logConsumer.printLog("PullRequestPublisher is started ***********************************************************************"); + if (configurationId == null) { + throw new IllegalArgumentException("ALM Octane configuration is not defined."); + } + if (workspaceId == null) { + throw new IllegalArgumentException("ALM Octane workspace is not defined."); + } + if (scmTool == null) { + throw new IllegalArgumentException("SCM Tool is not defined."); + } + + String myCredentialsId = credentialsId; + String myConfigurationId = configurationId; + String myWorkspaceId = workspaceId; + String myScmTool = scmTool; + String myUseSshFormat = useSSHFormat; + try { + EnvVars env = run.getEnvironment(taskListener); + myCredentialsId = env.expand(credentialsId); + myConfigurationId = env.expand(configurationId); + myWorkspaceId = env.expand(workspaceId); + myScmTool = env.expand(scmTool); + myUseSshFormat = env.expand(useSSHFormat); + } catch (IOException | InterruptedException e) { + taskListener.error("Failed loading build environment " + e); + } + + PullRequestFetchParameters fp = createFetchParameters(run, taskListener, myConfigurationId, myWorkspaceId, myUseSshFormat, logConsumer::printLog); + //fp.set + + StandardCredentials credentials = GitFetchUtils.getCredentialsById(myCredentialsId, run, taskListener.getLogger()); + AuthenticationStrategy authenticationStrategy = GitFetchUtils.getAuthenticationStrategy(credentials); + + FetchHandler fetchHandler = FetchFactory.getHandler(ScmTool.fromValue(myScmTool), authenticationStrategy); + try { + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(myConfigurationId); + logConsumer.printLog("ALM Octane " + octaneClient.getConfigurationService().getConfiguration().getLocationForLog() + ", workspace - " + myWorkspaceId); + octaneClient.validateOctaneIsActiveAndSupportVersion(PullRequestAndBranchService.PULL_REQUEST_COLLECTION_SUPPORTED_VERSION); + List pullRequests = fetchHandler.fetchPullRequests(fp, GitFetchUtils::getUserIdForCommit, logConsumer::printLog); + + synchronized (PullRequestBuildAction.class) { + long index = run.getActions(PullRequestBuildAction.class).size(); + PullRequestBuildAction buildAction = new PullRequestBuildAction(run, pullRequests, fp.getRepoUrl(), fp.getMinUpdateTime(), + fp.getSourceBranchFilter(), fp.getTargetBranchFilter(), index); + run.addAction(buildAction); + } + + if (!pullRequests.isEmpty()) { + octaneClient.getPullRequestAndBranchService().sendPullRequests(pullRequests, myWorkspaceId, fp, logConsumer::printLog); + } + //update templates + String repoUrlForOctane = fp.isUseSSHFormat() ? fp.getRepoUrlSsh() : fp.getRepoUrl(); + GitFetchUtils.updateRepoTemplates(octaneClient.getPullRequestAndBranchService(), fetchHandler, fp.getRepoUrl(), repoUrlForOctane, + Long.parseLong(myWorkspaceId), logConsumer::printLog); + } catch (OctaneValidationException e) { + logConsumer.printLog("ALM Octane pull request collector failed on validation : " + e.getMessage()); + run.setResult(Result.FAILURE); + } catch (ResourceNotFoundException e) { + logConsumer.printLog(e.getMessage()); + run.setResult(Result.FAILURE); + } catch (Exception e) { + logConsumer.printLog("ALM Octane pull request collector failed : " + e.getMessage()); + e.printStackTrace(taskListener.getLogger()); + run.setResult(Result.FAILURE); + } + } + + private PullRequestFetchParameters createFetchParameters(@Nonnull Run run, @Nonnull TaskListener taskListener, String myConfigurationId, String myWorkspaceId, String myUseSshFormat, Consumer logConsumer) { + + PullRequestFetchParameters fp; + try { + EnvVars env = run.getEnvironment(taskListener); + fp = new PullRequestFetchParameters() + .setRepoUrl(env.expand(repositoryUrl)) + .setSourceBranchFilter(env.expand(sourceBranchFilter)) + .setTargetBranchFilter(env.expand(targetBranchFilter)) + .setUseSSHFormat(Boolean.parseBoolean(env.expand(myUseSshFormat))); + + } catch (IOException | InterruptedException e) { + taskListener.error("Failed loading build environment " + e); + fp = new PullRequestFetchParameters() + .setRepoUrl(repositoryUrl) + .setSourceBranchFilter(sourceBranchFilter) + .setTargetBranchFilter(targetBranchFilter) + .setUseSSHFormat(Boolean.parseBoolean(myUseSshFormat)); + } + + ParametersAction parameterAction = run.getAction(ParametersAction.class); + if (parameterAction != null) { + fp.setPageSize(getIntegerValueParameter(parameterAction, "pullrequests_page_size")); + fp.setMaxPRsToFetch(getIntegerValueParameter(parameterAction, "pullrequests_max_pr_to_collect")); + fp.setMaxCommitsToFetch(getIntegerValueParameter(parameterAction, "pullrequests_max_commits_to_collect")); + fp.setMinUpdateTime(getLongValueParameter(parameterAction, "pullrequests_min_update_time")); + } + if (fp.getMinUpdateTime() == PullRequestFetchParameters.DEFAULT_MIN_UPDATE_DATE) { + long lastUpdateTime = OctaneSDK.getClientByInstanceId(myConfigurationId).getPullRequestAndBranchService().getPullRequestLastUpdateTime(myWorkspaceId, fp.getRepoUrl()); + fp.setMinUpdateTime(lastUpdateTime); + } + + logConsumer.accept("Repository URL : " + fp.getRepoUrl()); + logConsumer.accept("Min update date : " + fp.getMinUpdateTime()); + logConsumer.accept("Source branch filter : " + fp.getSourceBranchFilter()); + logConsumer.accept("Target branch filter : " + fp.getTargetBranchFilter()); + logConsumer.accept("Max PRs to collect : " + fp.getMaxPRsToFetch()); + logConsumer.accept("Max commits to collect: " + fp.getMaxCommitsToFetch()); + logConsumer.accept("Use ssh format : " + fp.isUseSSHFormat()); + return fp; + } + + private Integer getIntegerValueParameter(ParametersAction parameterAction, String paramValue) { + ParameterValue pv = parameterAction.getParameter(paramValue); + if (pv != null && pv.getValue() instanceof String) { + try { + return Integer.valueOf((String) pv.getValue()); + } catch (Exception e) { + return null; + } + } + return null; + } + + private Long getLongValueParameter(ParametersAction parameterAction, String paramValue) { + ParameterValue pv = parameterAction.getParameter(paramValue); + if (pv != null && pv.getValue() instanceof String) { + try { + return Long.valueOf((String) pv.getValue()); + } catch (Exception e) { + return null; + } + } + return null; + } + + public String getConfigurationId() { + return configurationId; + } + + public String getWorkspaceId() { + return workspaceId; + } + + @DataBoundSetter + public void setUseSSHFormat(boolean useSSHFormat) { + this.useSSHFormat = Boolean.toString(useSSHFormat); + } + + public boolean getUseSSHFormat() { + return Boolean.parseBoolean(useSSHFormat); + } + + private static class LogConsumer { + + private final PrintStream ps; + + public LogConsumer(PrintStream ps) { + this.ps = ps; + } + + public void printLog(String msg) { + ps.println("PullRequestPublisher : " + msg); + } + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } + + public String getCredentialsId() { + return credentialsId; + } + + public String getSourceBranchFilter() { + return sourceBranchFilter; + } + + public String getTargetBranchFilter() { + return targetBranchFilter; + } + + public String getScmTool() { + return scmTool; + } + + @Symbol("collectPullRequestsToAlmOctane") + @Extension // This indicates to Jenkins that this is an implementation of an extension point. + public static final class DescriptorImpl extends BuildStepDescriptor { + + static final CredentialsMatcher CREDENTIALS_MATCHER = CredentialsMatchers.anyOf(new CredentialsMatcher[]{ + CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class), + CredentialsMatchers.instanceOf(StringCredentials.class)}); + + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + return JellyUtils.fillCredentialsIdItems(project, credentialsId, CREDENTIALS_MATCHER); + } + + public ListBoxModel doFillScmToolItems() { + ListBoxModel m = JellyUtils.createComboModelWithNoneValue(); + for (ScmTool tool : ScmTool.values()) { + m.add(tool.getDesc(), tool.getValue()); + } + + return m; + } + + public boolean isApplicable(Class aClass) { + return true; + } + + public ListBoxModel doFillConfigurationIdItems() { + return JellyUtils.fillConfigurationIdModel(); + } + + public ListBoxModel doFillWorkspaceIdItems(@QueryParameter String configurationId, @QueryParameter(value = "workspaceId") String workspaceId) { + return JellyUtils.fillWorkspaceModel(configurationId, workspaceId); + } + + public String getDisplayName() { + return "ALM Octane pull-request collector"; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder.java b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder.java new file mode 100644 index 0000000000..d89eb2406f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder.java @@ -0,0 +1,619 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.testrunner; + +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.dto.general.MbtUnitParameter; +import com.hp.octane.integrations.executor.*; +import com.hp.octane.integrations.executor.converters.*; +import com.hp.octane.integrations.utils.SdkConstants; +import com.hp.octane.integrations.utils.SdkStringUtils; +import com.microfocus.application.automation.tools.AlmToolsUtils; +import com.microfocus.application.automation.tools.model.TestsFramework; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationValidator; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.*; +import hudson.model.*; +import hudson.remoting.VirtualChannel; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.FormValidation; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.jenkinsci.remoting.RoleChecker; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +import static com.microfocus.application.automation.tools.octane.executor.UftConstants.CODELESS_FOLDER_TEMPLATE; +import static com.microfocus.application.automation.tools.run.RunFromFileBuilder.HP_TOOLS_LAUNCHER_EXE; +import static java.util.stream.Collectors.groupingBy; + +/** + * Builder for available frameworks for converting + */ +public class TestsToRunConverterBuilder extends Builder implements SimpleBuildStep { + + private static final String DEFAULT_EXECUTING_DIRECTORY = "${workspace}"; + + private static final String CHECKOUT_DIRECTORY_PARAMETER = "testsToRunCheckoutDirectory"; + + private static final String CODELESS_SCRIPT_FILE = ".cl"; + + private static final String TEST_FILE_EXT = ".json"; + + private static final String MBT_JSON_FILE = "mbt.json"; + + public static final String TESTS_TO_RUN_PARAMETER = "testsToRun"; + + private TestsToRunConverterModel framework; + + public TestsToRunConverterBuilder(String framework) { + this.framework = new TestsToRunConverterModel(framework, ""); + } + + @DataBoundConstructor + public TestsToRunConverterBuilder(String framework, String format) { + this.framework = new TestsToRunConverterModel(framework, format); + } + + private static void printToConsole(TaskListener listener, String msg) { + listener.getLogger().println(TestsToRunConverterBuilder.class.getSimpleName() + " : " + msg); + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { + try { + ParametersAction parameterAction = build.getAction(ParametersAction.class); + String rawTests = null; + String executingDirectory = DEFAULT_EXECUTING_DIRECTORY; + if (parameterAction != null) { + ParameterValue suiteIdParameter = parameterAction.getParameter(SdkConstants.JobParameters.SUITE_ID_PARAMETER_NAME); + if (suiteIdParameter != null) { + printToConsole(listener, SdkConstants.JobParameters.SUITE_ID_PARAMETER_NAME + " : " + suiteIdParameter.getValue()); + } + ParameterValue suiteRunIdParameter = parameterAction.getParameter(SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME); + if (suiteRunIdParameter != null) { + printToConsole(listener, SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME + " : " + suiteRunIdParameter.getValue()); + } + + ParameterValue executionIdParameter = parameterAction.getParameter(SdkConstants.JobParameters.EXECUTION_ID_PARAMETER_NAME); + if (executionIdParameter != null) { + printToConsole(listener, SdkConstants.JobParameters.EXECUTION_ID_PARAMETER_NAME + " : " + executionIdParameter.getValue()); + } + + ParameterValue testsParameter = parameterAction.getParameter(TESTS_TO_RUN_PARAMETER); + if (testsParameter != null && testsParameter.getValue() instanceof String) { + rawTests = (String) testsParameter.getValue(); + printToConsole(listener, TESTS_TO_RUN_PARAMETER + " found with value : " + rawTests); + } + + ParameterValue checkoutDirParameter = parameterAction.getParameter(CHECKOUT_DIRECTORY_PARAMETER); + if (checkoutDirParameter != null) { + if (testsParameter.getValue() instanceof String && StringUtils.isNotEmpty((String) checkoutDirParameter.getValue())) { + executingDirectory = (String) checkoutDirParameter.getValue();//"%" + CHECKOUT_DIRECTORY_PARAMETER + "%"; + printToConsole(listener, CHECKOUT_DIRECTORY_PARAMETER + " parameter found with value : " + executingDirectory); + } else { + printToConsole(listener, CHECKOUT_DIRECTORY_PARAMETER + " parameter found, but its value is empty or its type is not String. Using default value."); + } + } + printToConsole(listener, "checkout directory : " + executingDirectory); + } + if (StringUtils.isEmpty(rawTests)) { + printToConsole(listener, TESTS_TO_RUN_PARAMETER + " is not found or has empty value. Skipping."); + return; + } + + if (framework == null || SdkStringUtils.isEmpty(getFramework())) { + printToConsole(listener, "No frameworkModel is selected. Skipping."); + return; + } + String frameworkName = getFramework(); + String frameworkFormat = getFormat(); + printToConsole(listener, "Selected framework = " + frameworkName); + if (SdkStringUtils.isNotEmpty(frameworkFormat)) { + printToConsole(listener, "Using format = " + frameworkFormat); + } + + TestsToRunFramework testsToRunFramework = TestsToRunFramework.fromValue(frameworkName); + boolean isMbt = rawTests.contains("mbtData"); + TestsToRunConverterResult convertResult; + Map globalParameters = getGlobalParameters(parameterAction); + + List testsData = TestsToRunConverter.parse(rawTests); + TestsToRunConvertersFactory.createConverter(testsToRunFramework).enrichTestsData(testsData, globalParameters); + + if (isMbt) { + //MBT needs to know real path to tests and not ${workspace} + //MBT needs to run on slave to extract function libraries from checked out files + try { + EnvVars env = build.getEnvironment(listener); + executingDirectory = env.expand(executingDirectory); + } catch (IOException | InterruptedException e) { + listener.error("Failed loading build environment " + e); + } + convertResult = filePath.act(new GetConvertResult(testsToRunFramework, frameworkFormat, testsData, executingDirectory, globalParameters)); + } else { + convertResult = (new GetConvertResult(testsToRunFramework, frameworkFormat, testsData, executingDirectory, globalParameters)).invoke(null, null); + } + // process tests by type + if (convertResult.getMbtTests() != null) { + processTests(build, filePath, launcher, listener, convertResult); + } + + printToConsole(listener, "Found #tests : " + convertResult.getTestsData().size()); + printToConsole(listener, "Set to parameter : " + convertResult.getTestsToRunConvertedParameterName() + " = " + convertResult.getConvertedTestsString()); + printToConsole(listener, "********************* Conversion is done *********************"); + if (JobProcessorFactory.WORKFLOW_RUN_NAME.equals(build.getClass().getName())) { + List newParams = (parameterAction != null) ? new ArrayList<>(parameterAction.getAllParameters()) : new ArrayList<>(); + newParams.add(new StringParameterValue(convertResult.getTestsToRunConvertedParameterName(), convertResult.getConvertedTestsString())); + ParametersAction newParametersAction = new ParametersAction(newParams); + build.addOrReplaceAction(newParametersAction); + } else { + VariableInjectionAction via = new VariableInjectionAction(convertResult.getTestsToRunConvertedParameterName(), convertResult.getConvertedTestsString()); + build.addAction(via); + } + } catch (IllegalArgumentException e) { + printToConsole(listener, "Failed to convert : " + e.getMessage()); + build.setResult(Result.FAILURE); + + return; + } + } + + private void processTests(Run build, FilePath filePath, Launcher launcher, TaskListener listener, TestsToRunConverterResult convertResult) throws IOException, InterruptedException { + // group tests by type + Map> mbtTestsByType = convertResult.getMbtTests().stream().collect(groupingBy(MbtTest::getType)); + + // first handle uft tests if exist + if (CollectionUtils.isNotEmpty(mbtTestsByType.get(TestingToolType.UFT))) { + prepareUftTests((List)(List)mbtTestsByType.get(TestingToolType.UFT), build, filePath, launcher, listener); + } + + // handle codeless tests + if (CollectionUtils.isNotEmpty(mbtTestsByType.get(TestingToolType.CODELESS))) { + prepareCodelessTests((List)(List)mbtTestsByType.get(TestingToolType.CODELESS), build, filePath); + } + } + + private Map getGlobalParameters(ParametersAction parameterAction) { + Map map = new HashMap<>(); + Set predefinedParams = new HashSet<>(Arrays.asList( + SdkConstants.JobParameters.ADD_GLOBAL_PARAMETERS_TO_TESTS_PARAM, + SdkConstants.JobParameters.SUITE_ID_PARAMETER_NAME, + SdkConstants.JobParameters.SUITE_RUN_ID_PARAMETER_NAME, + SdkConstants.JobParameters.OCTANE_SPACE_PARAMETER_NAME, + SdkConstants.JobParameters.OCTANE_WORKSPACE_PARAMETER_NAME, + SdkConstants.JobParameters.OCTANE_CONFIG_ID_PARAMETER_NAME, + SdkConstants.JobParameters.OCTANE_URL_PARAMETER_NAME, + SdkConstants.JobParameters.OCTANE_RUN_BY_USERNAME + )); + + parameterAction.getAllParameters().stream() + .filter(p -> predefinedParams.contains(p.getName()) || p.getName().toLowerCase(Locale.ROOT).contains("octane")) + .forEach(param -> addParameterIfExist(map, parameterAction, param.getName())); + + return map; + } + + private void addParameterIfExist(Map map, ParametersAction parameterAction, String paramName) { + ParameterValue param = parameterAction.getParameter(paramName); + if (param != null) { + map.put(param.getName(), param.getValue().toString()); + } + } + + private void prepareUftTests(List tests, @Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws IOException, InterruptedException { + build.getRootDir(); + Properties props = new Properties(); + props.setProperty("runType", "MBT"); + props.setProperty("resultsFilename", "must be here"); + + EnvVars env = build.getEnvironment(listener); + + props.setProperty("parentFolder", workspace.getRemote() + "\\" + MfMBTConverter.MBT_PARENT_SUB_DIR); + props.setProperty("repoFolder", workspace.getRemote()); + ParametersAction parameterAction = build.getAction(ParametersAction.class); + ParameterValue checkoutDirParameter = parameterAction.getParameter(CHECKOUT_DIRECTORY_PARAMETER); + if (checkoutDirParameter != null) { + props.setProperty("parentFolder", env.expand((String) checkoutDirParameter.getValue()) + "\\" + MfMBTConverter.MBT_PARENT_SUB_DIR); + props.setProperty("repoFolder", env.expand((String) checkoutDirParameter.getValue())); + } + + int counter = 1; + + for (MbtUftTest mbtUftTest : tests) { + props.setProperty("test" + counter, mbtUftTest.getName()); + props.setProperty("package" + counter, "_" + counter); + props.setProperty("script" + counter, env.expand(mbtUftTest.getScript())); + props.setProperty("unitIds" + counter, mbtUftTest.getUnitIds().stream().map(n -> n.toString()).collect(Collectors.joining(";"))); + props.setProperty("underlyingTests" + counter, env.expand((String.join(";", mbtUftTest.getUnderlyingTests())))); + + if (mbtUftTest.getEncodedIterations() != null && !mbtUftTest.getEncodedIterations().isEmpty()) { + //Expects to receive params in CSV format, encoded base64, for example Y29sMSxjb2wyCjEsMwoyLDQK + props.setProperty("datableParams" + counter, mbtUftTest.getEncodedIterations()); + } + counter++; + } + + //prepare time + Date now = new Date(); + Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); + String time = formatter.format(now); + + // get properties serialized into a stream + String strProps; + try { + strProps = AlmToolsUtils.getPropsAsString(props); + } catch (IOException e) { + build.setResult(Result.FAILURE); + listener.error("Failed to store properties on agent machine: " + e); + return; + } + String propsFileName = String.format("mbt_props%s.txt", time); + FilePath fileProps = workspace.child(propsFileName); + + //HP Tool Launcher + URL cmdExeUrl = Jenkins.get().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE); + if (cmdExeUrl == null) { + listener.fatalError(HP_TOOLS_LAUNCHER_EXE + " not found in resources"); + return; + } + FilePath cmdLineExe = workspace.child(HP_TOOLS_LAUNCHER_EXE); + + try { + // create a file for the properties file, and save the properties + if (!AlmToolsUtils.tryCreatePropsFile(listener, strProps, fileProps)) { + build.setResult(Result.FAILURE); + return; + } + printToConsole(listener, "MBT props file saved to " + fileProps.getRemote()); + + // Copy the script to the project workspace + if (!cmdLineExe.exists()) { + cmdLineExe.copyFrom(cmdExeUrl); + printToConsole(listener, "HPToolLauncher copied to " + cmdLineExe.getRemote()); + } + + } catch (IOException | InterruptedException e) { + build.setResult(Result.FAILURE); + listener.error("Copying executable files to executing node " + e); + } + + try { + // Run the HpToolsLauncher.exe + AlmToolsUtils.runOnBuildEnv(build, launcher, listener, cmdLineExe, propsFileName, null); + // Has the report been successfully generated? + } catch (IOException ioe) { + Util.displayIOException(ioe, listener); + build.setResult(Result.FAILURE); + listener.error("Failed running HpToolsLauncher " + ioe); + return; + } + } + + private void prepareCodelessTests(List tests, Run build, FilePath workspace) throws IOException, InterruptedException { + FilePath parentFolder = workspace.child(String.format(CODELESS_FOLDER_TEMPLATE, build.getNumber())); + parentFolder.mkdirs(); + + // write the codeless script files + writeUnitScriptFiles(tests, parentFolder); + // write the mbt json file + writeMbtJsonFile(tests, parentFolder); + } + + private void writeUnitScriptFiles(List tests, FilePath parentFolder) throws IOException, InterruptedException { + for (MbtCodelessTest test : tests) { + for (MbtCodelessUnit unit : test.getUnits()) { + String fileName = unit.getUnitId() + CODELESS_SCRIPT_FILE; + FilePath unitFile = parentFolder.child(fileName); + unitFile.write(unit.getScript(), String.valueOf(StandardCharsets.UTF_8)); + unit.setPath(unitFile.getRemote()); + } + } + } + + private void writeMbtJsonFile(List tests, FilePath parentFolder) throws IOException, InterruptedException { + JSONArray mbtJsonArr = new JSONArray(); + + int counter = 1; + for (MbtCodelessTest test : tests) { + JSONObject codelessTestJson = new JSONObject(); + + // add test section to json + JSONObject testJsonObj = new JSONObject(); + testJsonObj.put("reportPath", parentFolder.getRemote()); + codelessTestJson.put("test", testJsonObj); + + // add units to json + JSONArray unitsJsonArr = generateUnitsJson(test.getUnits()); + codelessTestJson.put("units", unitsJsonArr); + + // add iterations data to json + JSONObject dataJsonObj = generateDataJson(test); + codelessTestJson.put("data", dataJsonObj); + + // write codeless test file + // use counter since test name is not unique + String fileName = counter + "_" + test.getName() + TEST_FILE_EXT; + FilePath testFile = parentFolder.child(fileName); + testFile.write(codelessTestJson.toString(), String.valueOf(StandardCharsets.UTF_8)); + + JSONObject mbtTestJsonObj = new JSONObject(); + mbtTestJsonObj.put("counter", counter); + mbtTestJsonObj.put("testName", test.getName()); + mbtTestJsonObj.put("path", testFile.getRemote()); + + mbtJsonArr.add(mbtTestJsonObj); + counter++; + } + + // write mbt json file + FilePath mbtJsonFile = parentFolder.child(MBT_JSON_FILE); + mbtJsonFile.write(mbtJsonArr.toString(), String.valueOf(StandardCharsets.UTF_8)); + } + + private JSONArray generateUnitsJson(List codelessUnits) { + JSONArray unitsJsonArr = new JSONArray(); + codelessUnits.forEach(codelessUnit -> { + JSONObject unitJsonObj = new JSONObject(); + unitJsonObj.put("unitId", codelessUnit.getUnitId()); + unitJsonObj.put("name", codelessUnit.getName()); + unitJsonObj.put("order", codelessUnit.getOrder()); + unitJsonObj.put("path", codelessUnit.getPath()); + // add parameters section to unit + JSONArray parametersJsonArr = new JSONArray(); + if (!CollectionUtils.isEmpty(codelessUnit.getParameters())) { + codelessUnit.getParameters().forEach(parameter -> { + JSONObject parameterJsonObj = new JSONObject(); + // take the parameter id and name from the unit parameter since the codeless scripts contain unit parameters + // data and not test parameters data + parameterJsonObj.put("id", parameter.getUnitParameterId()); + parameterJsonObj.put("name", parameter.getUnitParameterName()); + parameterJsonObj.put("type", parameter.getType()); + parametersJsonArr.add(parameterJsonObj); + }); + } + unitJsonObj.put("parameters", parametersJsonArr); + unitsJsonArr.add(unitJsonObj); + }); + + return unitsJsonArr; + } + + private JSONObject generateDataJson(MbtCodelessTest test) { + // prepare data + // sort units by order + List sortedUnits = test.getUnits().stream().sorted(Comparator.comparing(MbtCodelessUnit::getOrder)).collect(Collectors.toList()); + + // build a sorted list of all input parameters + List sortedInputParameters = new ArrayList<>(); + sortedUnits.forEach(unit -> { + List sortedList = unit.getParameters().stream().filter(parameter -> parameter.getType().equalsIgnoreCase("input")) + .sorted(Comparator.comparing(MbtUnitParameter::getOrder)) + .collect(Collectors.toList()); + sortedInputParameters.addAll(sortedList); + }); + + // build a map between an output parameter name and the actual parameter. it will be used when constructing the + // data section of the test json to map between an output parameter in the mbt test to the unit parameter since + // codeless uses unit parameters data and not test parameter data + Map outputParamNameToParameterMap = new HashMap<>(); + sortedUnits.forEach(unit -> unit.getParameters().stream() + .filter(parameter -> parameter.getType().equalsIgnoreCase("output")) + .forEach(parameter -> outputParamNameToParameterMap.put(parameter.getName(), parameter))); + + // build a map between a parameter name and the unit holding it. the key is the parameter id and the parameter name + // since in order to support merged parameters + Map paramNameToUnitMap = new HashMap<>(); + sortedUnits.forEach(unit -> unit.getParameters().forEach(parameter -> paramNameToUnitMap.put(createParameterKey(parameter), unit))); + + List iterationParams = test.getMbtDataTable().getParameters(); + List> iterations = test.getMbtDataTable().getIterations(); + + // construct json + JSONObject dataJsonObj = new JSONObject(); + JSONArray iterationsJsonArr = new JSONArray(); + + // build iterations + for (List currentIteration : iterations) { + JSONArray iterationJsonArr = new JSONArray(); + for (MbtUnitParameter currentParameter : sortedInputParameters) { + JSONObject parameterJsonObj = generateParameterDataJson(currentParameter, currentIteration, iterationParams, paramNameToUnitMap, outputParamNameToParameterMap); + iterationJsonArr.add(parameterJsonObj); + } + iterationsJsonArr.add(iterationJsonArr); + } + dataJsonObj.put("iterations", iterationsJsonArr); + + return dataJsonObj; + } + + private String createParameterKey(MbtUnitParameter parameter) { + return parameter.getParameterId() + "_" + parameter.getName(); + } + + private JSONObject generateParameterDataJson(MbtUnitParameter currentParameter, List currentIteration, List iterationParams, Map paramNameToUnitMap, Map outputParamNameToParameterMap) { + MbtCodelessUnit currentUnit = paramNameToUnitMap.get(createParameterKey(currentParameter)); + + boolean isLinkedToOutput = StringUtils.isNotEmpty(currentParameter.getOutputParameter()); + + JSONObject parameterJsonObj = new JSONObject(); + parameterJsonObj.put("unitOrder", currentUnit.getOrder()); + // take the parameter name from the unit parameter since the codeless scripts contain unit parameters data and not + // test parameters data + parameterJsonObj.put("paramName", currentParameter.getUnitParameterName()); + JSONObject valueJsonObj = new JSONObject(); + if (isLinkedToOutput) { // value should be taken from output parameter + MbtUnitParameter outputParameter = outputParamNameToParameterMap.get(currentParameter.getOutputParameter()); + MbtCodelessUnit linkedParamUnit = paramNameToUnitMap.get(createParameterKey(outputParameter)); + valueJsonObj.put("type", "parameter"); + // set the order and not the unit id since a unit can be added more than once in an mbt test + valueJsonObj.put("name", linkedParamUnit.getOrder() + ":" + outputParameter.getUnitParameterName()); + } else { // value should be taken from iteration both for regular parameter and merged parameter by the merged parameter name + valueJsonObj.put("type", "literal"); + String value = currentIteration.get(iterationParams.indexOf(currentParameter.getName())); // get value by index in iteration parameters list + valueJsonObj.put("value", value != null ? value : ""); + } + parameterJsonObj.put("value", valueJsonObj); + return parameterJsonObj; + } + + /*** + * Used in UI + * @return + */ + public TestsToRunConverterModel getTestsToRunConverterModel() { + return framework; + } + + /*** + * Used in Pipeline + * @return + */ + public String getFramework() { + return framework.getFramework().getName(); + } + + public String getFormat() { + return framework.getFramework().getFormat(); + } + + public boolean getIsCustom() { + return framework != null && TestsToRunFramework.Custom.value().equals(framework.getFramework().getName()); + } + + private static class GetConvertResult implements FilePath.FileCallable { + + private TestsToRunFramework framework; + + private List testData; + + private String executingDirectory; + + private String format; + + private Map globalParameters; + + public GetConvertResult(TestsToRunFramework framework, String format, List testData, String executingDirectory, Map globalParameters) { + this.framework = framework; + this.testData = testData; + this.format = format; + this.executingDirectory = executingDirectory; + this.globalParameters = globalParameters; + } + + @Override + public TestsToRunConverterResult invoke(File file, VirtualChannel virtualChannel) throws IOException, InterruptedException { + return TestsToRunConvertersFactory.createConverter(framework) + .setFormat(format) + .convert(testData, executingDirectory, globalParameters); + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + //no need to check roles as this can be run on master and on slave + } + + } + + @Symbol("convertTestsToRun") + @Extension + public static class Descriptor extends BuildStepDescriptor { + + @Override + public boolean isApplicable(Class jobType) { + return true;//FreeStyleProject.class.isAssignableFrom(jobType); + } + + @Override + public String getDisplayName() { + return "ALM Octane testing framework converter"; + } + + public FormValidation doTestConvert( + @QueryParameter("testsToRun") String rawTests, + @QueryParameter("teststorunconverter.framework") String framework, + @QueryParameter("teststorunconverter.format") String format) { + + try { + + if (StringUtils.isEmpty(rawTests)) { + throw new IllegalArgumentException("'Tests to run' parameter is missing"); + } + + if (StringUtils.isEmpty(framework)) { + throw new IllegalArgumentException("'Framework' parameter is missing"); + } + + TestsToRunFramework testsToRunFramework = TestsToRunFramework.fromValue(framework); + if (TestsToRunFramework.Custom.equals(testsToRunFramework) && StringUtils.isEmpty(format)) { + throw new IllegalArgumentException("'Format' parameter is missing"); + } + + TestsToRunConverterResult convertResult = TestsToRunConvertersFactory.createConverter(testsToRunFramework) + .setFormat(format) + .convert(rawTests, TestsToRunConverterBuilder.DEFAULT_EXECUTING_DIRECTORY, null); + String result = Util.escape(convertResult.getConvertedTestsString()); + return ConfigurationValidator.wrapWithFormValidation(true, "Conversion is successful :

" + result + "
"); + } catch (Exception e) { + return ConfigurationValidator.wrapWithFormValidation(false, "Failed to convert : " + e.getMessage()); + } + } + + /** + * Gets report archive modes. + * + * @return the report archive modes + */ + public List getFrameworks() { + + return TestsToRunConverterModel.Frameworks; + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterModel.java b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterModel.java new file mode 100644 index 0000000000..5207789dc9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterModel.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.testrunner; + +import com.hp.octane.integrations.executor.TestsToRunFramework; +import com.microfocus.application.automation.tools.model.TestsFramework; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/* + * Test model for storing of available frameworks for converting + */ +public class TestsToRunConverterModel implements Serializable { + + private static final long serialVersionUID = 1L; + + public final static TestsFramework none = new TestsFramework("", "", ""); + + public final static List Frameworks; + + private String framework; + private String format; + + static { + List temp = new ArrayList<>(); + temp.add(none); + for (TestsToRunFramework fr : TestsToRunFramework.values()) { + temp.add(new TestsFramework(fr.value(), fr.getDesc(), fr.getFormat())); + } + Frameworks = temp; + } + + @DataBoundConstructor + public TestsToRunConverterModel(String framework, String format) { + this.framework = framework; + this.format = format; + } + + public TestsFramework getFramework() { + return new TestsFramework(framework, "", format); + } + +} + + + diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/VariableInjectionAction.java b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/VariableInjectionAction.java new file mode 100644 index 0000000000..f739460ad3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/testrunner/VariableInjectionAction.java @@ -0,0 +1,82 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.testrunner; + +import hudson.EnvVars; +import hudson.model.AbstractBuild; +import hudson.model.EnvironmentContributingAction; + +import javax.annotation.CheckForNull; +import java.util.HashMap; +import java.util.Map; + +/* + Handle variable injection for tests of converter builder. + */ + +public class VariableInjectionAction implements EnvironmentContributingAction { + + private Map variables; + + public VariableInjectionAction(String key, String value) { + variables = new HashMap<>(); + variables.put(key, value); + } + + @Override + public void buildEnvVars(AbstractBuild abstractBuild, EnvVars envVars) { + if (envVars != null && variables != null) { + for (Map.Entry entry : variables.entrySet()) { + envVars.put(entry.getKey(), entry.getValue()); + } + } + } + + @CheckForNull + @Override + public String getIconFileName() { + return null; + } + + @CheckForNull + @Override + public String getDisplayName() { + return "VariableInjectionAction"; + } + + @CheckForNull + @Override + public String getUrlName() { + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java new file mode 100644 index 0000000000..ced0f1de45 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/AbstractSafeLoggingAsyncPeriodWork.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.model.AsyncPeriodicWork; +import hudson.model.TaskListener; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public abstract class AbstractSafeLoggingAsyncPeriodWork extends AsyncPeriodicWork { + + private static Logger logger = Logger.getLogger(AbstractSafeLoggingAsyncPeriodWork.class.getName()); + + protected AbstractSafeLoggingAsyncPeriodWork(String name) { + super(name); + } + + @Override + protected void execute(TaskListener listener) throws IOException, InterruptedException { + try { + doExecute(listener); + } catch (IOException|InterruptedException e) { + // by default this ends up in log file and is rewritten on each execution + // we want this in the regular Jenkins log in order to be able to troubleshoot + logError(e); + } catch (Throwable t) { + // by default this ends up on the console as uncaught exception + // we want this in the regular Jenkins log in order to be able to troubleshoot + logError(t); + } + } + + protected abstract void doExecute(TaskListener listener) throws IOException, InterruptedException; + + private void logError(Throwable t) { + LogRecord lr = new LogRecord(this.getErrorLoggingLevel(), "{0} thread failed with error"); + lr.setThrown(t); + lr.setParameters(new Object[] { name }); + logger.log(lr); + } + + @Override + protected Level getNormalLoggingLevel() { + return Level.CONFIG; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/HPRunnerType.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/HPRunnerType.java new file mode 100644 index 0000000000..4598740732 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/HPRunnerType.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +/** + * Runner type of test + */ +public enum HPRunnerType { + StormRunnerLoad, + UFT, + UFT_MBT, + PerformanceCenter, + LoadRunner, + NONE +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/OctaneTestsExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/OctaneTestsExtension.java new file mode 100644 index 0000000000..fc6b246dd6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/OctaneTestsExtension.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Run; +import jenkins.model.Jenkins; + +import java.io.IOException; + +/** + * General provider of Octane's tests processing extensions + */ + +public abstract class OctaneTestsExtension implements ExtensionPoint { + + public abstract boolean supports(Run build) throws IOException, InterruptedException; + + + public abstract TestResultContainer getTestResults(Run build, String jenkinsRootUrl) throws IOException, InterruptedException, TestProcessingException; + + public static ExtensionList all() { + return Jenkins.get().getExtensionList(OctaneTestsExtension.class); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestApi.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestApi.java new file mode 100644 index 0000000000..36b4cbaf38 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestApi.java @@ -0,0 +1,73 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.FilePath; +import hudson.model.AbstractBuild; +import hudson.model.Item; +import org.apache.commons.io.IOUtils; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Flavor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607"}) +public class TestApi { + + private AbstractBuild build; + + public TestApi(AbstractBuild build) { + this.build = build; + } + + public void doXml(StaplerRequest req, StaplerResponse res) throws IOException, InterruptedException { + build.getACL().checkPermission(Item.READ); + serveFile(res, TestListener.TEST_RESULT_FILE, Flavor.XML); + } + + private void serveFile(StaplerResponse res, String relativePath, Flavor flavor) throws IOException, InterruptedException { + FilePath file = new FilePath(new File(build.getRootDir(), relativePath)); + if (!file.exists()) { + res.sendError(404, "Information not available"); + return; + } + res.setStatus(200); + res.setContentType(flavor.contentType); + InputStream is = file.read(); + IOUtils.copy(is, res.getOutputStream()); + IOUtils.closeQuietly(is); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestListener.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestListener.java new file mode 100644 index 0000000000..d13111bfb4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestListener.java @@ -0,0 +1,101 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.octane.tests.xml.TestResultXmlWriter; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.Run; +import jenkins.model.Jenkins; +import org.apache.logging.log4j.Logger; + +import javax.xml.stream.XMLStreamException; + +/** + * Jenkins events life cycle listener for processing test results on build completed + */ +@Extension +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872"}) +public class TestListener { + private static Logger logger = SDKBasedLoggerProvider.getLogger(TestListener.class); + + public static final String TEST_RESULT_FILE = "mqmTests.xml"; + + + public boolean processBuild(Run run) { + FilePath resultPath = new FilePath(new FilePath(run.getRootDir()), TEST_RESULT_FILE); + TestResultXmlWriter resultWriter = new TestResultXmlWriter(resultPath, run); + boolean success = true; + boolean hasTests = false; + String jenkinsRootUrl = Jenkins.get().getRootUrl(); + + try { + for (OctaneTestsExtension ext : OctaneTestsExtension.all()) { + if (ext.supports(run)) { + TestResultContainer testResultContainer = ext.getTestResults(run, jenkinsRootUrl); + if (testResultContainer != null && testResultContainer.getIterator().hasNext()) { + resultWriter.writeResults(testResultContainer); + hasTests = true; + } + } + } + } catch (Throwable t) { + success = false; + logger.error("failed to process test results", t); + } finally { + try { + resultWriter.close(); + + // we don't push individual maven module results (although we create the file for future use) + if (!"hudson.maven.MavenBuild".equals(run.getClass().getName())) { + if (success && hasTests) { + String projectFullName = BuildHandlerUtils.getJobCiId(run); + String parents = BuildHandlerUtils.getRootJobCiIds(run); + logger.info("enqueued build '" + projectFullName + " #" + run.getNumber() + "' for test result submission"); + if (projectFullName != null) { + OctaneSDK.getClients().forEach(octaneClient -> + octaneClient.getTestsService().enqueuePushTestsResult(projectFullName, String.valueOf(run.getNumber()), parents)); + } + } + } + } catch (XMLStreamException xmlse) { + success = false; + logger.error("failed to finalize test results processing", xmlse); + } + } + return success && hasTests; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestProcessingException.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestProcessingException.java new file mode 100644 index 0000000000..039eb8c872 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestProcessingException.java @@ -0,0 +1,43 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +/** + * Created by franksha on 05/01/2017. + */ +public class TestProcessingException extends Exception { + + public TestProcessingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestResultContainer.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestResultContainer.java new file mode 100644 index 0000000000..e678dde7a0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/TestResultContainer.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.hp.octane.integrations.testresults.XmlWritableTestResult; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFields; + +import java.util.Iterator; + +public class TestResultContainer { + + private Iterator iterator; + private ResultFields resultFields; + + public TestResultContainer(Iterator iterator, ResultFields resultFields) { + this.iterator = iterator; + this.resultFields = resultFields; + } + + public Iterator getIterator() { + return iterator; + } + + public ResultFields getResultFields() { + return resultFields; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildDescriptor.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildDescriptor.java new file mode 100644 index 0000000000..3c0842d7b5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildDescriptor.java @@ -0,0 +1,70 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +public final class BuildDescriptor { + + private final String jobId; + private final String jobName; + private final String buildId; + private final String buildName; + private final String subType; + + public BuildDescriptor(String jobId, String jobName, String buildId, String buildName, String subType) { + this.jobId = jobId; + this.jobName = jobName; + this.buildId = buildId; + this.buildName = buildName; + this.subType = subType; + } + + public String getJobId() { + return jobId; + } + + public String getJobName() { + return jobName; + } + + public String getBuildId() { + return buildId; + } + + public String getBuildName() { + return buildName; + } + + public String getSubType() { + return subType; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerExtension.java new file mode 100644 index 0000000000..0ee07eead9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerExtension.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Run; +import jenkins.model.Jenkins; + +abstract class BuildHandlerExtension implements ExtensionPoint { + + public abstract boolean supports(Run build); + + public abstract BuildDescriptor getBuildType(Run build); + + @Deprecated + public abstract String getProjectFullName(Run build); + + public static ExtensionList all() { + return Jenkins.getInstanceOrNull().getExtensionList(BuildHandlerExtension.class); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtils.java new file mode 100644 index 0000000000..671bc43754 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtils.java @@ -0,0 +1,219 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +import com.hp.octane.integrations.dto.causes.CIEventCause; +import com.hp.octane.integrations.dto.causes.CIEventCauseType; +import com.hp.octane.integrations.dto.snapshots.CIBuildResult; +import com.hp.octane.integrations.utils.CIPluginSDKUtils; +import com.hp.octane.integrations.utils.SdkConstants; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.CIEventCausesFactory; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.FilePath; +import hudson.matrix.MatrixConfiguration; +import hudson.matrix.MatrixRun; +import hudson.model.AbstractBuild; +import hudson.model.Result; +import hudson.model.Run; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.actions.LabelAction; +import org.jenkinsci.plugins.workflow.actions.ThreadNameAction; +import org.jenkinsci.plugins.workflow.actions.WorkspaceAction; +import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode; +import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode; +import org.jenkinsci.plugins.workflow.flow.FlowExecution; +import org.jenkinsci.plugins.workflow.graph.FlowEndNode; +import org.jenkinsci.plugins.workflow.graph.FlowGraphWalker; +import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.graph.FlowStartNode; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Generic utilities handling Job/Run metadata extraction/transformation/processing + */ + +public class BuildHandlerUtils { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(BuildHandlerUtils.class); + public static final String JOB_LEVEL_SEPARATOR = "/job/"; + + public static BuildDescriptor getBuildType(Run run) { + for (BuildHandlerExtension ext : BuildHandlerExtension.all()) { + if (ext.supports(run)) { + return ext.getBuildType(run); + } + } + return new BuildDescriptor( + BuildHandlerUtils.getJobCiId(run), + run.getParent().getName(), + BuildHandlerUtils.getBuildCiId(run), + String.valueOf(run.getNumber()), + ""); + } + + @Deprecated + public static String getProjectFullName(Run run) { + for (BuildHandlerExtension ext : BuildHandlerExtension.all()) { + if (ext.supports(run)) { + return ext.getProjectFullName(run); + } + } + return run.getParent().getFullName(); + } + + public static FilePath getWorkspace(Run run) { + if (run.getExecutor() != null && run.getExecutor().getCurrentWorkspace() != null) { + return run.getExecutor().getCurrentWorkspace(); + } + if (run instanceof AbstractBuild) { + return ((AbstractBuild) run).getWorkspace(); + } + if (run instanceof WorkflowRun) { + FlowExecution fe = ((WorkflowRun) run).getExecution(); + if (fe != null) { + FlowGraphWalker w = new FlowGraphWalker(fe); + for (FlowNode n : w) { + WorkspaceAction action = n.getAction(WorkspaceAction.class); + if (action != null) { + FilePath workspace = action.getWorkspace(); + if (workspace == null) { + workspace = handleWorkspaceActionWithoutWorkspace(action); + } + return workspace; + } + } + } + } + + logger.error("BuildHandlerUtils.getWorkspace - run is not handled. Run type : " + run.getClass()); + return null; + } + + private static FilePath handleWorkspaceActionWithoutWorkspace(WorkspaceAction action) { + logger.error("Found WorkspaceAction without workspace"); + logger.warn("Node getPath = " + action.getPath()); + logger.warn("Node getNode = " + action.getNode()); + FilePath workspace = null; + + if (StringUtils.isNotEmpty(action.getPath())) { + logger.warn("Node getPath is not empty, return getPath as workspace"); + workspace = new FilePath(new File(action.getPath())); + } else { + logger.warn("Node getPath is empty, return workspace = null"); + } + return workspace; + } + + public static String getBuildCiId(Run run) { + return String.valueOf(run.getNumber()); + // YG temporary disabling the support for fluid build number until Octane supports it + //return run.getNumber() + "_" + run.getStartTimeInMillis(); + } + + public static String getJobCiId(Run run) { + if (run.getParent() instanceof MatrixConfiguration) { + return JobProcessorFactory.getFlowProcessor(((MatrixRun) run).getProject()).getTranslatedJobName(); + } + if (run.getParent().getClass().getName().equals(JobProcessorFactory.WORKFLOW_JOB_NAME)) { + return JobProcessorFactory.getFlowProcessor(run.getParent()).getTranslatedJobName(); + } + return JobProcessorFactory.getFlowProcessor(((AbstractBuild) run).getProject()).getTranslatedJobName(); + } + + public static String translateFolderJobName(String jobPlainName) { + return jobPlainName.replaceAll("/", JOB_LEVEL_SEPARATOR); + } + + public static String revertTranslateFolderJobName(String translatedJobName) { + return translatedJobName.replaceAll(JOB_LEVEL_SEPARATOR, "/"); + } + + public static String translateFullDisplayName(String fullDisplayName) { + return fullDisplayName.replaceAll(" » ", "/"); + } + + public static CIBuildResult translateRunResult(Run run) { + CIBuildResult result; + if (run.getResult() == Result.SUCCESS) { + result = CIBuildResult.SUCCESS; + } else if (run.getResult() == Result.ABORTED) { + result = CIBuildResult.ABORTED; + } else if (run.getResult() == Result.FAILURE) { + result = CIBuildResult.FAILURE; + } else if (run.getResult() == Result.UNSTABLE) { + result = CIBuildResult.UNSTABLE; + } else { + result = CIBuildResult.UNAVAILABLE; + } + return result; + } + + public static boolean isWorkflowStartNode(FlowNode node) { + return node.getParents().isEmpty() || + node.getParents().stream().anyMatch(fn -> fn instanceof FlowStartNode); + } + + public static boolean isWorkflowEndNode(FlowNode node) { + return node instanceof FlowEndNode; + } + + public static boolean isStageStartNode(FlowNode node) { + return node instanceof StepStartNode && node.getAction(LabelAction.class) != null && node.getAction(ThreadNameAction.class) == null; + } + + public static boolean isStageEndNode(FlowNode node) { + return node instanceof StepEndNode && isStageStartNode(((StepEndNode) node).getStartNode()); + } + + public static WorkflowRun extractParentRun(FlowNode flowNode) { + try { + return (WorkflowRun) flowNode.getExecution().getOwner().getExecutable(); + } catch (IOException ioe) { + logger.error("failed to extract parent workflow run from " + flowNode, ioe); + throw new IllegalStateException("failed to extract parent workflow run from " + flowNode); + } + } + + public static String getRootJobCiIds(Run run) { + Set parents = new HashSet<>(); + CIPluginSDKUtils.getRootJobCiIds(BuildHandlerUtils.getJobCiId(run), CIEventCausesFactory.processCauses(run), parents); + return String.join(SdkConstants.General.JOB_PARENT_DELIMITER, parents); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MatrixBuildExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MatrixBuildExtension.java new file mode 100644 index 0000000000..fbf5d9b9d5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MatrixBuildExtension.java @@ -0,0 +1,74 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.microfocus.application.automation.tools.octane.model.ModelFactory; +import com.microfocus.application.automation.tools.octane.model.processors.parameters.ParameterProcessors; +import hudson.Extension; +import hudson.matrix.MatrixRun; +import hudson.model.AbstractBuild; +import hudson.model.Run; + +import java.util.List; + +/** + * Run/Build metadata factory for Matrix projects + */ + +@Extension +public class MatrixBuildExtension extends BuildHandlerExtension { + + @Override + public boolean supports(Run run) { + return "hudson.matrix.MatrixRun".equals(run.getClass().getName()); + } + + @Override + public BuildDescriptor getBuildType(Run run) { + AbstractBuild matrixRun = (AbstractBuild) run; + List parameters = ParameterProcessors.getInstances(run); + String subBuildName = ModelFactory.generateSubBuildName(parameters); + return new BuildDescriptor( + BuildHandlerUtils.getJobCiId(run), + matrixRun.getRootBuild().getProject().getName(), + BuildHandlerUtils.getBuildCiId(run), + String.valueOf(run.getNumber()), + subBuildName); + } + + @Override + public String getProjectFullName(Run run) { + return ((MatrixRun) run).getProject().getFullName(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MavenBuildExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MavenBuildExtension.java new file mode 100644 index 0000000000..c94a863be6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/build/MavenBuildExtension.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.Run; + +/** + * Run/Build metadata factory for Maven projects + */ + +@Extension +public class MavenBuildExtension extends BuildHandlerExtension { + + @Override + public boolean supports(Run run) { + return "hudson.maven.MavenBuild".equals(run.getClass().getName()) || + "hudson.maven.MavenModuleSetBuild".equals(run.getClass().getName()); + } + + @Override + public BuildDescriptor getBuildType(Run run) { + return new BuildDescriptor( + BuildHandlerUtils.getJobCiId(run), + ((AbstractBuild) run).getProject().getName(), + BuildHandlerUtils.getBuildCiId(run), + String.valueOf(run.getNumber()), + ""); + } + + @Override + public String getProjectFullName(Run run) { + if ("hudson.maven.MavenBuild".equals(run.getClass().getName())) { + // we don't push individual maven module results (although we create the file) + return null; + } else { + return ((AbstractBuild) run).getProject().getFullName(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/MFToolsDetectionExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/MFToolsDetectionExtension.java new file mode 100644 index 0000000000..7c05481c9f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/MFToolsDetectionExtension.java @@ -0,0 +1,162 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.HPRunnerType; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.ParameterValue; +import hudson.model.ParametersAction; +import hudson.model.Run; +import hudson.tasks.Builder; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Recognize execution of OpenText Tools + */ +@Extension +public class MFToolsDetectionExtension extends ResultFieldsDetectionExtension { + + private static Logger logger = SDKBasedLoggerProvider.getLogger(MFToolsDetectionExtension.class); + private static final String STORMRUNNER_LOAD_TEST_RUNNER_CLASS = "StormTestRunner"; + private static final String STORMRUNNER_TEST_RUN_TEST_RUNNER_CLASS = "TestRunBuilder"; + private static final String PERFORMANCE_CENTER_TEST_RUNNER_CLASS = "PcBuilder"; + private static final String RUN_FROM_FILE_BUILDER = "RunFromFileBuilder"; + private static final String RUN_FROM_ALM_BUILDER = "RunFromAlmBuilder"; + + private static final String UFT = "UFT"; + public static final String UFT_MBT = "MBT"; + private static final String STORMRUNNER_LOAD = "StormRunner Load"; + private static final String LOAD_RUNNER = "LoadRunner"; + private static final String PERFORMANCE_CENTER_RUNNER = "Performance Center"; + private static final String PERFORMANCE_TEST_TYPE = "Performance"; + + + private static final String PERFORMANCE_REPORT = "PerformanceReport"; + private static final String TRANSACTION_SUMMARY = "TransactionSummary"; + + private static Map builder2RunnerType = new HashMap<>(); + private static Map runnerType2ResultFields = new HashMap<>(); + + static { + builder2RunnerType.put(STORMRUNNER_LOAD_TEST_RUNNER_CLASS, HPRunnerType.StormRunnerLoad); + builder2RunnerType.put(STORMRUNNER_TEST_RUN_TEST_RUNNER_CLASS, HPRunnerType.StormRunnerLoad); + builder2RunnerType.put(RUN_FROM_FILE_BUILDER, HPRunnerType.UFT); + builder2RunnerType.put(RUN_FROM_ALM_BUILDER, HPRunnerType.UFT); + builder2RunnerType.put(PERFORMANCE_CENTER_TEST_RUNNER_CLASS, HPRunnerType.PerformanceCenter); + + runnerType2ResultFields.put(HPRunnerType.PerformanceCenter, new ResultFields(null, PERFORMANCE_CENTER_RUNNER, null, PERFORMANCE_TEST_TYPE)); + runnerType2ResultFields.put(HPRunnerType.UFT, new ResultFields(UFT, UFT, null)); + runnerType2ResultFields.put(HPRunnerType.UFT_MBT, new ResultFields(UFT_MBT, null, null)); + runnerType2ResultFields.put(HPRunnerType.StormRunnerLoad, new ResultFields(null, STORMRUNNER_LOAD, null)); + runnerType2ResultFields.put(HPRunnerType.LoadRunner, new ResultFields(null, LOAD_RUNNER, null)); + } + + /** + * Detect result fields for ALM Octane tests + * + * @param build + * @return + * @throws IOException + * @throws InterruptedException + */ + @Override + public ResultFields detect(Run build) throws IOException, InterruptedException { + HPRunnerType runnerType = getRunnerType(build); + return runnerType2ResultFields.get(runnerType); + } + + /** + * Get MF runner type from run + * + * @param run + * @return + */ + public static HPRunnerType getRunnerType(Run run) { + HPRunnerType hpRunnerType = HPRunnerType.NONE; + ParametersAction parameterAction = run.getAction(ParametersAction.class); + if (JobProcessorFactory.WORKFLOW_RUN_NAME.equals(run.getClass().getName())) { + + ParameterValue runnerTypePv = parameterAction != null ? parameterAction.getParameter(HPRunnerType.class.getSimpleName()) : null; + if (runnerTypePv != null) { + hpRunnerType = HPRunnerType.valueOf((String) runnerTypePv.getValue()); + } + } else { + List builders = JobProcessorFactory.getFlowProcessor(run.getParent()).tryGetBuilders(); + if (builders != null) { + for (Builder builder : builders) { + String builderName = builder.getClass().getSimpleName(); + if (builder2RunnerType.containsKey(builderName)) { + hpRunnerType = builder2RunnerType.get(builderName); + break; + } + } + } + } + + if (hpRunnerType == HPRunnerType.UFT) { + ParameterValue octaneFramework = parameterAction != null ? parameterAction.getParameter("octaneTestRunnerFramework") : null; + if(octaneFramework!=null && octaneFramework.getValue().equals("MBT")){ + hpRunnerType = HPRunnerType.UFT_MBT; + } + } + if (hpRunnerType == HPRunnerType.UFT && isLoadRunnerProject(run)) { + hpRunnerType = HPRunnerType.LoadRunner; + } + return hpRunnerType; + } + + private static boolean isLoadRunnerProject(Run run) { + if (run.getRootDir() != null) { + try { + FilePath performanceReportFolder = new FilePath(run.getRootDir()).child(PERFORMANCE_REPORT); + FilePath transactionSummaryFolder = new FilePath(run.getRootDir()).child(TRANSACTION_SUMMARY); + return performanceReportFolder.exists() && + performanceReportFolder.isDirectory() && + transactionSummaryFolder.exists() && + transactionSummaryFolder.isDirectory(); + } catch (IOException | InterruptedException e) { + logger.error("Failed to check isLoadRunnerProject :" + e.getMessage()); + } + } + return false; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFields.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFields.java new file mode 100644 index 0000000000..c1f0b8c47a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFields.java @@ -0,0 +1,124 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +/** + * Class describing metadata of executed tests for test pushing to Octane + */ +public class ResultFields { + + private String framework; + private String testingTool; + private String testLevel; + private String testType; + + public ResultFields() { + } + + public ResultFields(final String framework, final String testingTool, final String testLevel) { + this(framework, testingTool, testLevel, null); + } + + public ResultFields(final String framework, final String testingTool, final String testLevel, final String testType) { + this.framework = framework; + this.testingTool = testingTool; + this.testLevel = testLevel; + this.testType = testType; + } + + public String getFramework() { + return framework; + } + + public String getTestingTool() { + return testingTool; + } + + public String getTestLevel() { + return testLevel; + } + + public void setFramework(final String framework) { + this.framework = framework; + } + + public void setTestLevel(final String testLevel) { + this.testLevel = testLevel; + } + + public void setTestingTool(final String testingTool) { + this.testingTool = testingTool; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final ResultFields that = (ResultFields) o; + + if (framework != null ? !framework.equals(that.framework) : that.framework != null) { + return false; + } + if (testingTool != null ? !testingTool.equals(that.testingTool) : that.testingTool != null) { + return false; + } + + if (testType != null ? !testType.equals(that.testType) : that.testType != null) { + return false; + } + return !(testLevel != null ? !testLevel.equals(that.testLevel) : that.testLevel != null); + + } + + @Override + public int hashCode() { + int result = framework != null ? framework.hashCode() : 0; + result = 31 * result + (testingTool != null ? testingTool.hashCode() : 0); + result = 31 * result + (testLevel != null ? testLevel.hashCode() : 0); + result = 31 * result + (testType != null ? testType.hashCode() : 0); + return result; + } + + public String getTestType() { + return testType; + } + + public void setTestType(String testType) { + this.testType = testType; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java new file mode 100644 index 0000000000..6b0d0a03b4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionExtension.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Run; +import jenkins.model.Jenkins; + +import java.io.IOException; + +public abstract class ResultFieldsDetectionExtension implements ExtensionPoint { + + public abstract ResultFields detect(Run build) throws IOException, InterruptedException; + + public static ExtensionList all() { + return Jenkins.getInstanceOrNull().getExtensionList(ResultFieldsDetectionExtension.class); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java new file mode 100644 index 0000000000..d1a953ce5e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionService.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.model.Run; +import org.apache.logging.log4j.Logger; + +/** + * Service used for auto detection of test results global parameters like test-framework, testing-tool, etc. + */ +public class ResultFieldsDetectionService { + private static Logger logger = SDKBasedLoggerProvider.getLogger(ResultFieldsDetectionService.class); + + public ResultFields getDetectedFields(Run build) throws InterruptedException { + for (ResultFieldsDetectionExtension ext : ResultFieldsDetectionExtension.all()) { + try { + ResultFields fields = ext.detect(build); + if (fields != null) { + return fields; + } + } catch (InterruptedException e) { + logger.error("Interrupted during running of detection service: " + ext.getClass().getName(), e); + throw e; + } catch (Exception e) { + logger.error("Error during running of detection service: " + ext.getClass().getName(), e); + } + } + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtension.java new file mode 100644 index 0000000000..51a7ed72e8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtension.java @@ -0,0 +1,171 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import hudson.FilePath; +import hudson.Util; +import hudson.maven.MavenBuild; +import hudson.maven.MavenModule; +import hudson.maven.MavenModuleSetBuild; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.remoting.VirtualChannel; +import hudson.tasks.junit.JUnitResultArchiver; +import hudson.tasks.test.AbstractTestResultAction; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.types.FileSet; +import org.jenkinsci.remoting.Role; +import org.jenkinsci.remoting.RoleChecker; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Extension(optional = true) +public class TestNGExtension extends ResultFieldsDetectionExtension { + private static final String TESTNG = "TestNG"; + private static final String TESTNG_RESULT_FILE = "testng-results.xml"; + private static final List supportedReportFileLocations = Arrays.asList( + "target/surefire-reports/" + TESTNG_RESULT_FILE, + "target/failsafe-reports/" + TESTNG_RESULT_FILE + ); + + @Override + public ResultFields detect(final Run build) throws IOException, InterruptedException { + if (!(build instanceof AbstractBuild)) { + return null; + } + + final List publishers = ((AbstractBuild) build).getProject().getPublishersList().toList(); + for (Object publisher : publishers) { + if ("hudson.tasks.junit.JUnitResultArchiver".equals(publisher.getClass().getName())) { + JUnitResultArchiver junit = (JUnitResultArchiver) publisher; + String testResultsPattern = junit.getTestResults(); + if (BuildHandlerUtils.getWorkspace(build).act(new TestNgResultsFileFinder(testResultsPattern))) { + return new ResultFields(TESTNG, null, null); + } + } + } + + if ("hudson.maven.MavenBuild".equals(build.getClass().getName())) { + MavenBuild mavenBuild = (MavenBuild) build; + if (findTestNgResultsFile(mavenBuild)) { + return new ResultFields(TESTNG, null, null); + } + } + + if ("hudson.maven.MavenModuleSetBuild".equals(build.getClass().getName())) { + Map moduleLastBuilds = ((MavenModuleSetBuild) build).getModuleLastBuilds(); + for (MavenBuild mavenBuild : moduleLastBuilds.values()) { + if (findTestNgResultsFile(mavenBuild)) { + return new ResultFields(TESTNG, null, null); + } + } + } + return null; + } + + boolean findTestNgResultsFile(MavenBuild mavenBuild) throws IOException, InterruptedException { + AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); + //try finding only if the maven build includes tests + return action != null && mavenBuild.getWorkspace().act(new TestNgResultsFileMavenFinder()); + } + + public static class TestNgResultsFileFinder implements FilePath.FileCallable { + + private String testResultsPattern; + + public TestNgResultsFileFinder(String testResultsPattern) { + this.testResultsPattern = testResultsPattern; + } + + @Override + public Boolean invoke(File workspace, VirtualChannel virtualChannel) throws IOException, InterruptedException { + FileSet fs = Util.createFileSet(workspace, testResultsPattern); + DirectoryScanner ds = fs.getDirectoryScanner(); + String[] includedFiles = ds.getIncludedFiles(); + File baseDir = ds.getBasedir(); + + if (includedFiles.length > 0 && findTestNgResultsFile(baseDir, includedFiles)) { + return true; + } + return false; + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + roleChecker.check(this, Role.UNKNOWN); + } + + boolean findTestNgResultsFile(File baseDir, String[] includedFiles) throws IOException, InterruptedException { + Set directoryCache = new LinkedHashSet<>(); + + for (String path : includedFiles) { + FilePath file = new FilePath(baseDir).child(path); + if (file.exists() && !directoryCache.contains(file.getParent())) { + directoryCache.add(file.getParent()); + FilePath testNgResulsFile = new FilePath(file.getParent(), TESTNG_RESULT_FILE); + if (testNgResulsFile.exists()) { + return true; + } + } + } + return false; + } + } + + public static class TestNgResultsFileMavenFinder implements FilePath.FileCallable { + + @Override + public Boolean invoke(File workspace, VirtualChannel virtualChannel) { + for (String locationInWorkspace : supportedReportFileLocations) { + File reportFile = new File(workspace, locationInWorkspace); + if (reportFile.exists()) { + return true; + } + } + return false; + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + roleChecker.check(this, Role.UNKNOWN); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinTestExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinTestExtension.java new file mode 100644 index 0000000000..cba3402656 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinTestExtension.java @@ -0,0 +1,95 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.gherkin; + +import com.hp.octane.integrations.testresults.GherkinUtils; +import com.hp.octane.integrations.testresults.XmlWritableTestResult; +import com.microfocus.application.automation.tools.octane.actions.cucumber.CucumberResultsService; +import com.microfocus.application.automation.tools.octane.actions.cucumber.CucumberTestResultsAction; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.OctaneTestsExtension; +import com.microfocus.application.automation.tools.octane.tests.TestProcessingException; +import com.microfocus.application.automation.tools.octane.tests.TestResultContainer; +import hudson.Extension; +import hudson.model.Run; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Extension +public class GherkinTestExtension extends OctaneTestsExtension { + private static Logger logger = SDKBasedLoggerProvider.getLogger(GherkinTestExtension.class); + + @Override + public boolean supports(Run build) { + if (build.getAction(CucumberTestResultsAction.class) != null) { + logger.debug("CucumberTestResultsAction found, gherkin results expected"); + return true; + } else { + logger.debug("CucumberTestResultsAction not found, no gherkin results expected"); + return false; + } + } + + @Override + public TestResultContainer getTestResults(Run build, String jenkinsRootUrl) throws + TestProcessingException, IOException, InterruptedException { + try { + List gherkinFiles = GherkinUtils.findGherkinFilesByTemplateWithCounter(build.getRootDir().getAbsolutePath(), + CucumberResultsService.GHERKIN_NGA_RESULTS + "%s.xml", 0); + List testResults = GherkinUtils.parseFiles(gherkinFiles); + return new TestResultContainer(testResults.iterator(), null); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new TestProcessingException("Error while processing gherkin test results", e); + } + } + + private List findGherkinFiles(File buildDir){ + List result = new ArrayList<>(); + int i = 0; + File gherkinTestResultsFile = new File(buildDir, CucumberResultsService.getGherkinResultFileName(i)); + + while (gherkinTestResultsFile.exists()) { + result.add(gherkinTestResultsFile); + i++; + gherkinTestResultsFile = new File(buildDir, CucumberResultsService.getGherkinResultFileName(i)); + } + + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java new file mode 100644 index 0000000000..e57ef3ab4e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/impl/ObjectStreamIterator.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.impl; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.FilePath; +import org.apache.logging.log4j.Logger; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class ObjectStreamIterator implements Iterator { + private static Logger logger = SDKBasedLoggerProvider.getLogger(ObjectStreamIterator.class); + + private ObjectInputStream ois; + private E next; + + public ObjectStreamIterator(FilePath filePath) throws IOException, InterruptedException { + this.ois = new ObjectInputStream(new BufferedInputStream(filePath.read())); + } + + @Override + public boolean hasNext() { + if (next != null) { + return true; + } + try { + next = (E) ois.readObject(); + return true; + } catch (Throwable e) { + try { + ois.close(); + } catch (IOException ioe) { + logger.error("Failed to close the stream", ioe); // NON-NLS + } + return false; + } + } + + @Override + public E next() { + if (hasNext()) { + E value = next; + next = null; + return value; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java new file mode 100644 index 0000000000..6c807eac6a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/AbstractMavenModuleDetection.java @@ -0,0 +1,104 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.FilePath; +import hudson.model.Run; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +public abstract class AbstractMavenModuleDetection implements ModuleDetection { + + protected FilePath rootDir; + protected List pomDirs; + + public AbstractMavenModuleDetection(Run build) { + rootDir = BuildHandlerUtils.getWorkspace(build); + pomDirs = new LinkedList<>(); + + addPomDirectories(build); + } + + protected abstract void addPomDirectories(Run build); + + @Override + public String getModule(FilePath resultFile) throws IOException, InterruptedException { + for (FilePath pomDir: pomDirs) { + if (childOf(pomDir, resultFile)) { + return normalize(locatePom(resultFile, pomDir)); + } + } + // unable to determine module + return null; + } + + protected void addPomDirectory(FilePath pomDir) { + pomDirs.add(pomDir); + } + + protected boolean childOf(FilePath parent, FilePath child) { + while (child != null) { + if (parent.equals(child)) { + return true; + } + child = child.getParent(); + } + return false; + } + + + private String locatePom(FilePath filePath, FilePath pomDir) throws IOException, InterruptedException { + while (filePath != null) { + FilePath parentPath = filePath.getParent(); + if (parentPath.equals(pomDir)) { + // walk up as far as the enclosing pom directory + break; + } + FilePath pomPath = new FilePath(parentPath, "pom.xml"); + if (pomPath.exists()) { + // we found a nested pom directory + return parentPath.getRemote().substring(rootDir.getRemote().length()); + } + filePath = parentPath; + } + // no other pom found in nested directories + return pomDir.getRemote().substring(rootDir.getRemote().length()); + } + + private String normalize(String path) { + return path.replace("\\", "/").replaceFirst("^/", ""); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitExtension.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitExtension.java new file mode 100644 index 0000000000..a60bd9a94d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitExtension.java @@ -0,0 +1,321 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import com.google.inject.Inject; +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.JenkinsUtils; +import com.microfocus.application.automation.tools.octane.actions.cucumber.CucumberTestResultsAction; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.executor.CheckOutSubDirEnvContributor; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.HPRunnerType; +import com.microfocus.application.automation.tools.octane.tests.OctaneTestsExtension; +import com.microfocus.application.automation.tools.octane.tests.TestResultContainer; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.octane.tests.detection.MFToolsDetectionExtension; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFields; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFieldsDetectionService; +import com.microfocus.application.automation.tools.octane.tests.impl.ObjectStreamIterator; +import com.microfocus.application.automation.tools.settings.RunnerMiscSettingsGlobalConfiguration; +import hudson.Extension; +import hudson.FilePath; +import hudson.maven.MavenBuild; +import hudson.maven.MavenModule; +import hudson.maven.MavenModuleSetBuild; +import hudson.model.*; +import hudson.remoting.VirtualChannel; +import hudson.tasks.test.AbstractTestResultAction; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.remoting.Role; +import org.jenkinsci.remoting.RoleChecker; + +import javax.xml.stream.XMLStreamException; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.Pattern; + +import static com.hp.octane.integrations.utils.SdkConstants.JobParameters.OCTANE_CONFIG_ID_PARAMETER_NAME; + +/** + * Converter of Jenkins test report to ALM Octane test report format(junitResult.xml->mqmTests.xml) + */ +@Extension +public class JUnitExtension extends OctaneTestsExtension { + private static Logger logger = SDKBasedLoggerProvider.getLogger(JUnitExtension.class); + + private static final String JUNIT_RESULT_XML = "junitResult.xml"; // NON-NLS + public static final String TEMP_TEST_RESULTS_FILE_NAME_PREFIX = "GetJUnitTestResults"; + private static final String TEST_RESULT_NAME_REGEX_PATTERN_PARAMETER_NAME = "octane_test_result_name_run_regex_pattern"; + + @Inject + private ResultFieldsDetectionService resultFieldsDetectionService; + + public boolean supports(Run build) { + if (build.getAction(CucumberTestResultsAction.class) != null) { + logger.debug("CucumberTestResultsAction found. Will not process JUnit results."); + return false; + } else if (build.getAction(AbstractTestResultAction.class) != null) { + logger.debug("AbstractTestResultAction found, JUnit results expected"); + return true; + } else { + logger.debug("AbstractTestResultAction not found, no JUnit results expected"); + return false; + } + } + + @Override + public TestResultContainer getTestResults(Run run, String jenkinsRootUrl) throws IOException, InterruptedException { + logger.debug("Collecting JUnit results"); + + FilePath resultFile = new FilePath(run.getRootDir()).child(JUNIT_RESULT_XML); + boolean getResultsOnController = !RunnerMiscSettingsGlobalConfiguration.getInstance().isAgentToControllerEnabled(); + FilePath workspace = BuildHandlerUtils.getWorkspace(run); + if (resultFile.exists()) { + logger.debug("JUnit result report found"); + if (workspace == null) { + logger.error("Received null workspace : " + run); + return null; + } + + + HPRunnerType hpRunnerType = MFToolsDetectionExtension.getRunnerType(run); + if(hpRunnerType.equals(HPRunnerType.UFT) || hpRunnerType.equals(HPRunnerType.UFT_MBT)){ + getResultsOnController = true; + } + FilePath filePath = getTestResultsFromWorkspace(run, jenkinsRootUrl, getResultsOnController, workspace, Collections.singletonList(resultFile),hpRunnerType); + ResultFields detectedFields = getResultFields(run); + return new TestResultContainer(new ObjectStreamIterator<>(filePath), detectedFields); + } else { + //avoid java.lang.NoClassDefFoundError when maven plugin is not present + if ("hudson.maven.MavenModuleSetBuild".equals(run.getClass().getName())) { + logger.debug("MavenModuleSetBuild detected, looking for results in maven modules"); + + List resultFiles = new LinkedList<>(); + Map moduleLastBuilds = ((MavenModuleSetBuild) run).getModuleLastBuilds(); + for (MavenBuild mavenBuild : moduleLastBuilds.values()) { + AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); + if (action != null) { + FilePath moduleResultFile = new FilePath(mavenBuild.getRootDir()).child(JUNIT_RESULT_XML); + if (moduleResultFile.exists()) { + logger.debug("Found results in " + mavenBuild.getFullDisplayName()); + resultFiles.add(moduleResultFile); + } + } + } + if (!resultFiles.isEmpty()) { + ResultFields detectedFields = getResultFields(run); + FilePath filePath = getTestResultsFromWorkspace(run, jenkinsRootUrl, getResultsOnController, workspace, resultFiles,HPRunnerType.NONE); + return new TestResultContainer(new ObjectStreamIterator<>(filePath), detectedFields); + } + } + logger.debug("No JUnit result report found"); + return null; + } + } + + private FilePath getTestResultsFromWorkspace(Run run, String jenkinsRootUrl, boolean getResultsOnController, FilePath workspace, List resultFiles,HPRunnerType runnerType) throws IOException, InterruptedException { + FilePath filePath; + try { + if (getResultsOnController) { + logger.info("Get results from controller"); + filePath = (new GetJUnitTestResults(run, runnerType, resultFiles, false, jenkinsRootUrl)).invoke(null, null); + } else { + logger.info("Get results from agent"); + filePath = workspace.act(new GetJUnitTestResults(run, runnerType, resultFiles, false, jenkinsRootUrl)); + } + }catch (Exception e){ + //if failed on controller/agent retrying from agent/controller + logger.error(String.format("Failed to get test results from %s, trying to get test results from %s : %s", + getResultsOnController ? "controller" : "agent", + getResultsOnController ? "agent" : "controller", + e.getMessage()), + e); + if (getResultsOnController) { + logger.info("Get results from agent"); + filePath = workspace.act(new GetJUnitTestResults(run, runnerType, resultFiles, false, jenkinsRootUrl)); + } else { + logger.info("Get results from controller"); + filePath = (new GetJUnitTestResults(run, runnerType, resultFiles, false, jenkinsRootUrl)).invoke(null, null); + } + } + return filePath; + } + + private ResultFields getResultFields(Run build) throws InterruptedException { + return resultFieldsDetectionService.getDetectedFields(build); + } + + private static class GetJUnitTestResults implements FilePath.FileCallable { + + private final List reports; + private final String jobName; + private final String buildId; + private final String jenkinsRootUrl; + private final HPRunnerType hpRunnerType; + private FilePath filePath; + private List moduleDetection; + private long buildStarted; + private FilePath workspace; + private boolean stripPackageAndClass; + private String sharedCheckOutDirectory; + private Pattern testParserRegEx; + private boolean octaneSupportsSteps; + + //this class is run on master and JUnitXmlIterator is runnning on slave. + //this object pass some master2slave data + private Object additionalContext; + private String nodeName; + + public GetJUnitTestResults(Run build, HPRunnerType hpRunnerType, List reports, boolean stripPackageAndClass, String jenkinsRootUrl) throws IOException, InterruptedException { + this.reports = reports; + this.filePath = new FilePath(build.getRootDir()).createTempFile(TEMP_TEST_RESULTS_FILE_NAME_PREFIX, null); + this.buildStarted = build.getStartTimeInMillis(); + this.workspace = BuildHandlerUtils.getWorkspace(build); + this.stripPackageAndClass = stripPackageAndClass; + this.hpRunnerType = hpRunnerType; + this.jenkinsRootUrl = jenkinsRootUrl; + String buildRootDir = build.getRootDir().getCanonicalPath(); + this.sharedCheckOutDirectory = CheckOutSubDirEnvContributor.getSharedCheckOutDirectory(build.getParent()); + if (sharedCheckOutDirectory == null && (HPRunnerType.UFT.equals(hpRunnerType) || HPRunnerType.UFT_MBT.equals(hpRunnerType))) { + ParametersAction parameterAction = build.getAction(ParametersAction.class); + ParameterValue pv = parameterAction != null ? parameterAction.getParameter(UftConstants.UFT_CHECKOUT_FOLDER) : null; + sharedCheckOutDirectory = pv != null && pv instanceof StringParameterValue ? + StringUtils.strip((String) pv.getValue(), "\\/") : ""; + } + + this.jobName = JobProcessorFactory.getFlowProcessor(build.getParent()).getTranslatedJobName(); + this.buildId = build.getId(); + moduleDetection = Arrays.asList( + new MavenBuilderModuleDetection(build), + new MavenSetModuleDetection(build), + new ModuleDetection.Default()); + + + if (HPRunnerType.UFT.equals(hpRunnerType) || HPRunnerType.UFT_MBT.equals(hpRunnerType)) { + Node node = JenkinsUtils.getCurrentNode(workspace); + this.nodeName = node != null && !node.getNodeName().isEmpty() ? node.getNodeName() : ""; + //extract folder names for created tests + String reportFolder = buildRootDir + "/archive/UFTReport" + + (StringUtils.isNotEmpty(this.nodeName) ? "/" + this.nodeName : ""); + List testFolderNames = new ArrayList<>(); + testFolderNames.add(build.getRootDir().getAbsolutePath()); + File reportFolderFile = new File(reportFolder); + if (reportFolderFile.exists()) { + File[] children = reportFolderFile.listFiles(); + if (children != null) { + for (File child : children) { + testFolderNames.add(child.getName()); + } + } + } + additionalContext = testFolderNames; + } + if (HPRunnerType.StormRunnerLoad.equals(hpRunnerType)) { + try { + File file = new File(build.getRootDir(), "log"); + Path path = Paths.get(file.getPath()); + additionalContext = Files.readAllLines(path, StandardCharsets.UTF_8); + } catch (Exception e) { + logger.error("Failed to add log file for StormRunnerLoad :" + e.getMessage()); + } + } + if(build.getAction(ParametersAction.class) != null && build.getAction(ParametersAction.class).getParameter(TEST_RESULT_NAME_REGEX_PATTERN_PARAMETER_NAME) != null && + build.getAction(ParametersAction.class).getParameter(TEST_RESULT_NAME_REGEX_PATTERN_PARAMETER_NAME).getValue() != null) { + try { + //\[.*\] - input for testName = testName[parameters] + //\[.*\) - input for testName = testName[parameters](more params) + this.testParserRegEx = Pattern.compile(Objects.requireNonNull(build.getAction(ParametersAction.class).getParameter(TEST_RESULT_NAME_REGEX_PATTERN_PARAMETER_NAME).getValue()).toString()); + } catch (IllegalArgumentException e){ + logger.error("Failed to parse regular expression pattern for test result name extractor.Job name: {}, Build {}, Input: {}, Error massage: {}.", + this.jobName, + this.buildId, + Objects.requireNonNull(build.getAction(ParametersAction.class).getParameter(TEST_RESULT_NAME_REGEX_PATTERN_PARAMETER_NAME).getValue()).toString() +"\n", + e.getMessage()); + } + } + if (hpRunnerType.equals(HPRunnerType.UFT_MBT)) { + try { + ParametersAction parameterAction = build.getAction(ParametersAction.class); + ParameterValue pv = parameterAction != null ? parameterAction.getParameter(OCTANE_CONFIG_ID_PARAMETER_NAME) : null; + String instanceId = pv instanceof StringParameterValue ? StringUtils.strip((String) pv.getValue(), "\\/") : ""; + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + octaneSupportsSteps = octaneClient.getConfigurationService().isOctaneVersionGreaterOrEqual("16.0.217"); + } catch (Exception e) { + logger.error("Failed to check octane version to know whether octaneSupportsSteps", e); + } + } + } + + @Override + public FilePath invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { + OutputStream os = filePath.write(); + BufferedOutputStream bos = new BufferedOutputStream(os); + ObjectOutputStream oos = new ObjectOutputStream(bos); + + try { + for (FilePath report : reports) { + JUnitXmlIterator iterator = new JUnitXmlIterator(report.read(), moduleDetection, workspace, sharedCheckOutDirectory, jobName, buildId, buildStarted, stripPackageAndClass, hpRunnerType, jenkinsRootUrl, additionalContext,testParserRegEx, octaneSupportsSteps,nodeName); + while (iterator.hasNext()) { + oos.writeObject(iterator.next()); + } + } + } catch (XMLStreamException e) { + throw new IOException(e); + } + os.flush(); + + oos.close(); + return filePath; + } + + @Override + public void checkRoles(RoleChecker roleChecker) throws SecurityException { + roleChecker.check(this, Role.UNKNOWN); + } + } + + /* + * To be used in tests only. + */ + public void _setResultFieldsDetectionService(ResultFieldsDetectionService detectionService) { + this.resultFieldsDetectionService = detectionService; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitTestResult.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitTestResult.java new file mode 100644 index 0000000000..bd57f0c798 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitTestResult.java @@ -0,0 +1,241 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import com.hp.octane.integrations.testresults.XmlWritableTestResult; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultIterationData; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepData; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepParameter; +import com.hp.octane.integrations.utils.SdkStringUtils; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.tests.HPRunnerType; +import com.microfocus.application.automation.tools.octane.tests.detection.MFToolsDetectionExtension; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.Serializable; +import java.util.List; + +/** + * Test Run XML writer to mqmTests.xml + */ +final public class JUnitTestResult implements Serializable, XmlWritableTestResult { + private static Logger logger = SDKBasedLoggerProvider.getLogger(JUnitTestResult.class); + private final static int DEFAULT_STRING_SIZE = 255; + private final String moduleName; + private final String packageName; + private final String className; + private final String testName; + private final String description; + private TestResultStatus result; + private long duration; + private final long started; + private TestError testError; + private final String externalReportUrl; + private final HPRunnerType runnerType; + private final String externalRunId; + private final List uftResultData; + private final boolean octaneSupportsSteps; + + public JUnitTestResult(String moduleName, String packageName, String className, String testName, TestResultStatus result, long duration, long started, TestError testError, String externalReportUrl, String description, HPRunnerType runnerType, String externalRunId, List uftResultData, boolean octaneSupportsSteps) { + this.moduleName = restrictSize(moduleName, DEFAULT_STRING_SIZE); + this.packageName = restrictSize(packageName, DEFAULT_STRING_SIZE); + this.className = restrictSize(className, DEFAULT_STRING_SIZE); + if (StringUtils.isEmpty(testName)) { + this.testName = "[noName]"; + } else { + this.testName = restrictSize(testName, DEFAULT_STRING_SIZE); + } + this.result = result; + this.duration = duration; + this.started = started; + this.testError = testError; + this.externalReportUrl = externalReportUrl; + this.description = description; + this.runnerType = runnerType; + this.externalRunId = externalRunId; + this.uftResultData = uftResultData; + this.octaneSupportsSteps = octaneSupportsSteps; + } + + private String restrictSize(String value, int size) { + String result = value; + if (value != null && value.length() > size) { + result = value.substring(0, size); + } + return result; + } + + public String getModuleName() { + return moduleName; + } + + public String getPackageName() { + return packageName; + } + + public String getClassName() { + return className; + } + + public String getTestName() { + return testName; + } + + public void setResult(TestResultStatus result) { + this.result = result; + } + + public TestResultStatus getResult() { + return result; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public long getDuration() { + return duration; + } + + public long getStarted() { + return started; + } + + public void setTestError(TestError testError) { + this.testError = testError; + } + + public TestError getTestError() { + return testError; + } + + public String getExternalReportUrl() { + return externalReportUrl; + } + + public List getUftResultData() { + return uftResultData; + } + + @Override + public void writeXmlElement(XMLStreamWriter writer) throws XMLStreamException { + writer.writeStartElement("test_run"); + writer.writeAttribute("module", moduleName); + writer.writeAttribute("package", packageName); + writer.writeAttribute("class", className); + writer.writeAttribute("name", testName); + writer.writeAttribute("duration", String.valueOf(duration)); + writer.writeAttribute("status", result.toPrettyName()); + writer.writeAttribute("started", String.valueOf(started)); + if (externalReportUrl != null && !externalReportUrl.isEmpty()) { + writer.writeAttribute("external_report_url", externalReportUrl); + } + if (externalRunId != null && !externalRunId.isEmpty()) { + writer.writeAttribute("external_run_id", externalRunId); + } + if (HPRunnerType.UFT_MBT.equals(runnerType)) { + writer.writeAttribute("run_type", MFToolsDetectionExtension.UFT_MBT); + } + if (result.equals(TestResultStatus.FAILED) && testError != null) { + writer.writeStartElement("error"); + writer.writeAttribute("type", String.valueOf(testError.getErrorType())); + writer.writeAttribute("message", String.valueOf(testError.getErrorMsg())); + writer.writeCharacters(testError.getStackTraceStr()); + writer.writeEndElement(); + } else if (testError != null && !SdkStringUtils.isEmpty(testError.getErrorMsg())) {//warning case + writer.writeStartElement("error"); + writer.writeAttribute("message", String.valueOf(testError.getErrorMsg())); + writer.writeEndElement(); + } + + if (description != null && !description.isEmpty()) { + writer.writeStartElement("description"); + writer.writeCharacters(description); + writer.writeEndElement(); + } + if (octaneSupportsSteps && uftResultData != null) { + try { + for (int i = 0; i < uftResultData.size(); i++) { + writer.writeStartElement("steps"); + writer.writeAttribute("iteration", String.valueOf(i + 1)); + final List steps = uftResultData.get(i).getSteps(); + for (int j = 0; j < steps.size(); j++) { + final UftResultStepData uftResultStepData = steps.get(j); + writer.writeStartElement("step"); + writer.writeAttribute("name", String.valueOf(uftResultStepData.getParents().get(uftResultStepData.getParents().size() - 1))); + writer.writeAttribute("duration", String.valueOf(uftResultStepData.getDuration())); + writer.writeAttribute("status", uftResultStepData.getResult()); + final String errorMessage = uftResultStepData.getMessage(); + if (StringUtils.isNotBlank(errorMessage)) { + writer.writeStartElement("error_message"); + writer.writeCharacters(errorMessage); + writer.writeEndElement(); + } + if (uftResultStepData.getInputParameters() != null && !uftResultStepData.getInputParameters().isEmpty()) { + writer.writeStartElement("input_parameters"); + for (int k = 0; k < uftResultStepData.getInputParameters().size(); k++) { + final UftResultStepParameter parameter = uftResultStepData.getInputParameters().get(k); + writer.writeStartElement("parameter"); + writer.writeAttribute("name", parameter.getName()); + writer.writeAttribute("value", parameter.getValue()); + writer.writeAttribute("type", parameter.getType()); + writer.writeEndElement(); + } + writer.writeEndElement(); + } + if (uftResultStepData.getOutputParameters() != null && !uftResultStepData.getOutputParameters().isEmpty()) { + writer.writeStartElement("output_parameters"); + for (int k = 0; k < uftResultStepData.getOutputParameters().size(); k++) { + final UftResultStepParameter parameter = uftResultStepData.getOutputParameters().get(k); + writer.writeStartElement("parameter"); + writer.writeAttribute("name", parameter.getName()); + writer.writeAttribute("value", parameter.getValue()); + writer.writeAttribute("type", parameter.getType()); + writer.writeEndElement(); + } + writer.writeEndElement(); + } + writer.writeEndElement(); + } + writer.writeEndElement(); + } + } catch (Exception e) { + logger.error("Failed to write Steps elements", e); + } + } + writer.writeEndElement(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java new file mode 100644 index 0000000000..d28c0c6eba --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/JUnitXmlIterator.java @@ -0,0 +1,710 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.executor.impl.TestingToolType; +import com.hp.octane.integrations.dto.tests.Property; +import com.hp.octane.integrations.dto.tests.TestSuite; +import com.hp.octane.integrations.executor.converters.MfMBTConverter; +import com.hp.octane.integrations.uft.ufttestresults.UftTestResultsUtils; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultIterationData; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepData; +import com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepParameter; +import com.hp.octane.integrations.utils.SdkConstants; +import com.microfocus.application.automation.tools.JenkinsUtils; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.octane.tests.HPRunnerType; +import com.microfocus.application.automation.tools.octane.tests.junit.codeless.CodelessResult; +import com.microfocus.application.automation.tools.octane.tests.junit.codeless.CodelessResultParameter; +import com.microfocus.application.automation.tools.octane.tests.junit.codeless.CodelessResultUnit; +import com.microfocus.application.automation.tools.octane.tests.xml.AbstractXmlIterator; +import hudson.FilePath; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Paths; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * JUnit result parser and enricher according to HPRunnerType + */ +public class JUnitXmlIterator extends AbstractXmlIterator { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(JUnitXmlIterator.class); + private final FilePath workspace; + private final long buildStarted; + private final String buildId; + private final String jobName; + private final HPRunnerType hpRunnerType; + private boolean stripPackageAndClass; + private String moduleName; + private String moduleNameFromFile; + private String packageName; + private String id; + private String className; + private String testName; + private long testDuration; + private TestResultStatus status; + private String stackTraceStr; + private String errorType; + private String errorMsg; + private String externalURL; + private String uftResultFilePath; + private String description; + private List moduleDetection; + private String jenkinsRootUrl; + private String sharedCheckOutDirectory; + private Object additionalContext; + private String filePath; + public static final String SRL_REPORT_URL = "reportUrl"; + private Pattern testParserRegEx; + private String externalRunId; + private List uftResultData; + private boolean octaneSupportsSteps; + private TestingToolType testingToolType = TestingToolType.UFT; + // for codeless use + private long stepDuration; + private boolean insideCaseElement = false; // used for codeless test to differentiate between test duration and step duration + private JUnitTestResult currentJUnitTestResult; + private List currentIterationSteps; + private Map testNameToJunitResultMap = new HashMap<>(); + private String stepName; + private ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + private Map testNameToCodelessResultMap = new HashMap<>(); + private String nodeName; + + private final int ERROR_MESSAGE_MAX_SIZE = System.getProperty("octane.sdk.tests.error_message_max_size") != null ? Integer.parseInt(System.getProperty("octane.sdk.tests.error_message_max_size")) : 512*512; + private final int ERROR_DETAILS_MAX_SIZE = System.getProperty("octane.sdk.tests.error_details_max_size") != null ? Integer.parseInt(System.getProperty("octane.sdk.tests.error_details_max_size")) : 512*512; + + + public JUnitXmlIterator(InputStream read, List moduleDetection, FilePath workspace, String sharedCheckOutDirectory, String jobName, String buildId, long buildStarted, boolean stripPackageAndClass, HPRunnerType hpRunnerType, String jenkinsRootUrl, Object additionalContext, Pattern testParserRegEx, boolean octaneSupportsSteps,String nodeName) throws XMLStreamException { + super(read); + this.stripPackageAndClass = stripPackageAndClass; + this.moduleDetection = moduleDetection; + this.workspace = workspace; + this.sharedCheckOutDirectory = sharedCheckOutDirectory; + this.buildId = buildId; + this.jobName = jobName; + this.buildStarted = buildStarted; + this.hpRunnerType = hpRunnerType; + this.jenkinsRootUrl = jenkinsRootUrl; + this.additionalContext = additionalContext; + this.testParserRegEx = testParserRegEx; + this.octaneSupportsSteps = octaneSupportsSteps; + this.nodeName = nodeName; + } + + private static long parseTime(String timeString) { + String time = timeString.replace(",", ""); + try { + float seconds = Float.parseFloat(time); + return (long) (seconds * 1000); + } catch (NumberFormatException e) { + try { + return new DecimalFormat().parse(time).longValue(); + } catch (ParseException ex) { + logger.debug("Unable to parse test duration: " + timeString); + } + } + return 0; + } + + @Override + protected void onEvent(XMLEvent event) throws XMLStreamException, IOException, InterruptedException { + if (testingToolType.equals(TestingToolType.CODELESS)) { + handleCodelessTest(event); + } else { + handleJUnitTest(event); + } + } + + private void handleJUnitTest(XMLEvent event) throws XMLStreamException, IOException, InterruptedException { + if (event instanceof StartElement) { + StartElement element = (StartElement) event; + String localName = element.getName().getLocalPart(); + if ("file".equals(localName)) { // NON-NLS + filePath = peekNextValue(); + if(checkIsCodelessTestResult(filePath)) { + testingToolType = TestingToolType.CODELESS; + handleCodelessTest(event); + } else { + filePath = readNextValue(); + testingToolType = TestingToolType.UFT; + for (ModuleDetection detection : moduleDetection) { + moduleNameFromFile = moduleName = detection.getModule(new FilePath(new File(filePath))); + if (moduleName != null) { + break; + } + } + } + } else if ("id".equals(localName)) { + id = readNextValue(); + } else if ("case".equals(localName)) { // NON-NLS + resetTestData(); + } else if ("className".equals(localName)) { // NON-NLS + String fqn = readNextValue(); + int moduleIndex = fqn.indexOf("::"); + if (moduleIndex > 0) { + moduleName = fqn.substring(0, moduleIndex); + fqn = fqn.substring(moduleIndex + 2); + } + + int p = fqn.lastIndexOf('.'); + className = fqn.substring(p + 1); + if (p > 0) { + packageName = fqn.substring(0, p); + } else { + packageName = ""; + } + } else if ("stdout".equals(localName)) { + String stdoutValue = readNextValue(); + if (stdoutValue != null) { + if ((hpRunnerType.equals(HPRunnerType.UFT) || hpRunnerType.equals(HPRunnerType.UFT_MBT)) && stdoutValue.contains("Test result: Warning")) { + errorMsg = "Test ended with 'Warning' status."; + parseUftErrorMessages(); + } + + externalURL = extractValueFromStdout(stdoutValue, "__octane_external_url_start__", "__octane_external_url_end__", externalURL); + description = extractValueFromStdout(stdoutValue, "__octane_description_start__", "__octane_description_end__", description); + } + } else if ("testName".equals(localName)) { // NON-NLS + testName = readNextValue(); + if (testName != null && testName.endsWith("()")) {//clear ending () for gradle tests + testName = testName.substring(0, testName.length() - 2); + } + + if (hpRunnerType.equals(HPRunnerType.UFT) || hpRunnerType.equals(HPRunnerType.UFT_MBT)) { + if (testName != null && testName.contains("..")) { //resolve existence of ../ - for example c://a/../b => c://b + testName = new File(FilenameUtils.separatorsToSystem(testName)).getCanonicalPath(); + } + + String myPackageName = packageName; + String myClassName = className; + String myTestName = testName; + packageName = ""; + className = ""; + + // if workspace is prefix of the method name, cut it off + // currently this handling is needed for UFT tests + int uftTextIndexStart = getUftTestIndexStart(workspace, sharedCheckOutDirectory, testName); + if (uftTextIndexStart != -1) { + String path = testName.substring(uftTextIndexStart).replace(SdkConstants.FileSystem.LINUX_PATH_SPLITTER, SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER);; + boolean isMBT = path.startsWith(MfMBTConverter.MBT_PARENT_SUB_DIR); + if(isMBT){//remove MBT prefix + //mbt test located in two level folder : ___mbt/_order + path = path.substring(MfMBTConverter.MBT_PARENT_SUB_DIR.length() + 1);//remove ___mbt + path = path.substring(path.indexOf(SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER));//remove order part + } + + path = StringUtils.strip(path, SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER); + + //split path to package and name fields + if (path.contains(SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER)) { + int testNameStartIndex = path.lastIndexOf(SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER); + + testName = path.substring(testNameStartIndex + 1); + packageName = path.substring(0, testNameStartIndex); + } else { + testName = path; + if (isMBT) { + testName = MfMBTConverter.decodeTestNameIfRequired(testName); + } + } + } + + String cleanedTestName = cleanTestName(testName); + boolean testReportCreated = true; + if (additionalContext != null && additionalContext instanceof List) { + //test folders are appear in the following format GUITest1[1], while [1] number of test. It possible that tests with the same name executed in the same job + //by adding [1] or [2] we can differentiate between different instances. + //We assume that test folders are sorted so in this section, once we found the test folder, we remove it from collection , in order to find the second instance in next iteration + List createdTests = (List) additionalContext; + String searchFor = cleanedTestName + "["; + Optional optional = createdTests.stream().filter(str -> str.startsWith(searchFor)).findFirst(); + if (optional.isPresent()) { + cleanedTestName = optional.get(); + createdTests.remove(cleanedTestName); + } + testReportCreated = optional.isPresent(); + } + + if (testReportCreated) { + final String basePath = ((List) additionalContext).get(0); + String nodeNameSubFolder = StringUtils.isNotEmpty(this.nodeName) ? nodeName +"/" : ""; + uftResultFilePath = Paths.get(basePath, "archive", "UFTReport", nodeNameSubFolder, cleanedTestName, "/Result/run_results.xml").toFile().getCanonicalPath(); + externalURL = jenkinsRootUrl + "job/" + jobName + "/" + buildId + "/artifact/UFTReport/" + nodeNameSubFolder + cleanedTestName + "/Result/run_results.html"; + } else { + //if UFT didn't created test results page - add reference to Jenkins test results page + externalURL = jenkinsRootUrl + "job/" + jobName + "/" + buildId + "/testReport/" + myPackageName + "/" + jenkinsTestClassFormat(myClassName) + "/" + jenkinsTestNameFormat(myTestName) + "/"; + } + } else if (hpRunnerType.equals(HPRunnerType.PerformanceCenter)) { + externalURL = jenkinsRootUrl + "job/" + jobName + "/" + buildId + "/artifact/performanceTestsReports/pcRun/Report.html"; + } else if (hpRunnerType.equals(HPRunnerType.StormRunnerLoad)) { + externalURL = tryGetStormRunnerReportURLFromJunitFile(filePath); + if (StringUtils.isEmpty(externalURL) && additionalContext != null && additionalContext instanceof Collection) { + externalURL = tryGetStormRunnerReportURLFromLog((Collection) additionalContext); + } + } + } else if ("duration".equals(localName)) { // NON-NLS + testDuration = parseTime(readNextValue()); + } else if ("skipped".equals(localName)) { // NON-NLS + if ("true".equals(readNextValue())) { // NON-NLS + status = TestResultStatus.SKIPPED; + } + } else if ("failedSince".equals(localName)) { // NON-NLS + if (!"0".equals(readNextValue()) && !TestResultStatus.SKIPPED.equals(status)) { + status = TestResultStatus.FAILED; + } + } else if ("errorStackTrace".equals(localName)) { // NON-NLS + status = TestResultStatus.FAILED; + stackTraceStr = ""; + if (peek() instanceof Characters) { + stackTraceStr = readNextValue(); + int index = stackTraceStr.indexOf("at "); + if (index >= 0) { + errorType = stackTraceStr.substring(0, index); + } + } + } else if ("errorDetails".equals(localName)) { // NON-NLS + status = TestResultStatus.FAILED; + errorMsg = readNextValue(); + int index = stackTraceStr.indexOf(':'); + if (index >= 0) { + errorType = stackTraceStr.substring(0, index); + } + if ((hpRunnerType.equals(HPRunnerType.UFT)|| hpRunnerType.equals(HPRunnerType.UFT_MBT)) && StringUtils.isNotEmpty(errorMsg)) { + parseUftErrorMessages(); + } + } + } else if (event instanceof EndElement) { + EndElement element = (EndElement) event; + String localName = element.getName().getLocalPart(); + + if ("case".equals(localName)) { // NON-NLS + errorMsg = StringUtils.length(errorMsg) > ERROR_MESSAGE_MAX_SIZE ? StringUtils.abbreviate(errorMsg,ERROR_MESSAGE_MAX_SIZE) : errorMsg; + stackTraceStr = StringUtils.length(stackTraceStr) > ERROR_DETAILS_MAX_SIZE ? StringUtils.abbreviate(errorMsg,ERROR_DETAILS_MAX_SIZE) : stackTraceStr; + TestError testError = new TestError(stackTraceStr, errorType, errorMsg); + + if(this.testParserRegEx != null){ + splitTestNameByPattern(); + } + if (hpRunnerType.equals(HPRunnerType.UFT_MBT) && StringUtils.isNotEmpty(uftResultFilePath)) { + try { + uftResultData = UftTestResultsUtils.getMBTData(new File(uftResultFilePath)); + } catch (Exception e) { + logger.error("Failed to get MBT Data which includes steps results", e); + } + } + if (stripPackageAndClass) { + //workaround only for UFT - we do not want packageName="All-Tests" and className="<None>" as it comes from JUnit report + addItem(new JUnitTestResult(moduleName, "", "", testName, status, testDuration, buildStarted, testError, externalURL, description, hpRunnerType,this.externalRunId, uftResultData, octaneSupportsSteps)); + } else { + addItem(new JUnitTestResult(moduleName, packageName, className, testName, status, testDuration, buildStarted, testError, externalURL, description, hpRunnerType,this.externalRunId, uftResultData, octaneSupportsSteps)); + } + } else if ("suites".equals(localName)) { + finalizeCodelessTests(); + } + } + } + + // parse codeless test parts. the codeless junit result is different than the uft. so, its processing is different: + // 1) in codeless, for each test, + // a separate result file is generated. each "suite" section in the file matches an iteration. each "case" section matches + // a unit in an iteration. so, in order to process a test run, we need to process all its iterations one by one and add + // the test at the close of the "suites" element. after each iteration is processed, we need to update the test duration + // and status if there is a change + // 2) the test's name is taken from the file name + private void handleCodelessTest(XMLEvent event) throws XMLStreamException, IOException, InterruptedException { + if (event instanceof StartElement) { + StartElement element = (StartElement) event; + String localName = element.getName().getLocalPart(); + if ("file".equals(localName)) { // NON-NLS + filePath = peekNextValue(); + if(!checkIsCodelessTestResult(filePath)) { + testingToolType = TestingToolType.UFT; + handleJUnitTest(event); + } else { // start of a new iteration + filePath = readNextValue(); + testingToolType = TestingToolType.CODELESS; + String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1); + testName = fileName.substring(0, fileName.lastIndexOf("-Report")); + readCodelessTestJsonResult(testName, filePath); + currentIterationSteps = new ArrayList<>(); + currentJUnitTestResult = testNameToJunitResultMap.get(testName); + } + } else if ("suite".equals(localName)) { // start of iteration + resetTestData(); + } else if ("case".equals(localName)) { // start of step + resetCaseData(); + insideCaseElement = true; + } else if ("duration".equals(localName)) { // NON-NLS + if (insideCaseElement) { + stepDuration = parseTime(readNextValue()); + } else { + testDuration = parseTime(readNextValue()); + } + } else if ("testName".equals(localName)) { // + stepName = readNextValue(); + } else if ("skipped".equals(localName)) { // NON-NLS + if ("true".equals(readNextValue())) { // NON-NLS + status = TestResultStatus.SKIPPED; + } + } else if ("failedSince".equals(localName)) { // NON-NLS + if (!"0".equals(readNextValue()) && !TestResultStatus.SKIPPED.equals(status)) { + status = TestResultStatus.FAILED; + } + } else if ("errorStackTrace".equals(localName)) { // NON-NLS + status = TestResultStatus.FAILED; + stackTraceStr = ""; + if (peek() instanceof Characters) { + stackTraceStr = readNextValue(); + int index = stackTraceStr.indexOf("at "); + if (index >= 0) { + errorType = stackTraceStr.substring(0, index); + } + } + } else if ("errorDetails".equals(localName)) { // NON-NLS + status = TestResultStatus.FAILED; + errorMsg = readNextValue(); + int index = stackTraceStr.indexOf(':'); + if (index >= 0) { + errorType = stackTraceStr.substring(0, index); + } + if ((hpRunnerType.equals(HPRunnerType.UFT)|| hpRunnerType.equals(HPRunnerType.UFT_MBT)) && StringUtils.isNotEmpty(errorMsg)) { + parseUftErrorMessages(); + } + } + } else if (event instanceof EndElement) { + EndElement element = (EndElement) event; + String localName = element.getName().getLocalPart(); + + if ("case".equals(localName)) { // end step + errorMsg = StringUtils.length(errorMsg) > ERROR_MESSAGE_MAX_SIZE ? StringUtils.abbreviate(errorMsg,ERROR_MESSAGE_MAX_SIZE) : errorMsg; + UftResultStepData stepData = new UftResultStepData(Collections.singletonList(stepName), "", status.toPrettyName(), errorMsg, stepDuration); + currentIterationSteps.add(stepData); + + insideCaseElement = false; + } else if ("suite".equals(localName)) { // end of iteration, add the junit result + UftResultIterationData iterationData = new UftResultIterationData(currentIterationSteps, testDuration); + TestResultStatus iterationStatus = TestResultStatus.fromPrettyName(calculateIterationStatus(iterationData)); + if(currentJUnitTestResult == null) { + List iterations = new ArrayList<>(); + iterations.add(iterationData); + TestError testError = null; + if(iterationStatus.equals(TestResultStatus.FAILED)) { + testError = new TestError("", "", findFirstError(iterationData)); + } + // strip the test counter from the test name. but leave it in the map as is since test name is not unique + String actualTestName = testName.substring(testName.indexOf("_") + 1); + currentJUnitTestResult = new JUnitTestResult("", "", "", actualTestName, iterationStatus, testDuration, buildStarted, testError, "", "", hpRunnerType, this.externalRunId, iterations, octaneSupportsSteps); + testNameToJunitResultMap.put(testName, currentJUnitTestResult); + } else { // new iteration to an existing test result + currentJUnitTestResult.setDuration(currentJUnitTestResult.getDuration() + testDuration); + currentJUnitTestResult.getUftResultData().add(iterationData); + if (iterationStatus.equals(TestResultStatus.FAILED) && !currentJUnitTestResult.getResult().equals(TestResultStatus.FAILED)) { + currentJUnitTestResult.setResult(TestResultStatus.FAILED); + TestError testError = new TestError(stackTraceStr, errorType, findFirstError(iterationData)); + currentJUnitTestResult.setTestError(testError); + } + } + testingToolType = TestingToolType.UFT; + } else if ("suites".equals(localName)) { + finalizeCodelessTests(); + } + } + } + + private void finalizeCodelessTests() { + if (!testNameToJunitResultMap.isEmpty()) { + // add parameters to all the units + addParametersToUnitsResponse(); + testNameToJunitResultMap.values().forEach(this::addItem); + } + } + + private void resetTestData() { + packageName = ""; + className = ""; + testName = ""; + testDuration = 0; + status = TestResultStatus.PASSED; + stackTraceStr = ""; + errorType = ""; + errorMsg = ""; + externalURL = ""; + description = ""; + uftResultFilePath = ""; + moduleName = moduleNameFromFile; + uftResultData = null; + } + + private void resetCaseData() { + stepDuration = 0; + status = TestResultStatus.PASSED; + stackTraceStr = ""; + errorType = ""; + errorMsg = ""; + insideCaseElement = false; + stepName = ""; + } + + private String calculateIterationStatus(UftResultIterationData iterationData) { + Set stepStatuses = iterationData.getSteps().stream().map(UftResultStepData::getResult).collect(Collectors.toSet()); + if(stepStatuses.contains(TestResultStatus.FAILED.toPrettyName())) { + return TestResultStatus.FAILED.toPrettyName(); + } else if (stepStatuses.contains(TestResultStatus.PASSED.toPrettyName())) { + return TestResultStatus.PASSED.toPrettyName(); + } else { + return TestResultStatus.SKIPPED.toPrettyName(); + } + } + + private String findFirstError(UftResultIterationData iterationData) { + Optional failedStepOptional = iterationData.getSteps().stream().filter(uftResultStepData -> uftResultStepData.getResult().equals(TestResultStatus.FAILED.toPrettyName())).findFirst(); + if(failedStepOptional.isPresent()) { + return failedStepOptional.get().getMessage(); + } + return ""; + } + + // codeless test result file path is in the form of c:\Jenkins\workspace\MBT-test-runner-1001-8xepv\codeless_17\1_Codeless Model_00002.json-Report.xml + private boolean checkIsCodelessTestResult(String resultFilePath) { + String codelessFolderName = String.format(UftConstants.CODELESS_FOLDER_TEMPLATE, buildId); + return resultFilePath.contains(SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER + codelessFolderName + SdkConstants.FileSystem.WINDOWS_PATH_SPLITTER); + } + + private void readCodelessTestJsonResult(String testName, String testFilePath) { + if(testNameToCodelessResultMap.get(testName) != null) { // codeless json result was already read for a previous iteration + return; + } + String jsonFileName = testFilePath.replace("xml", "json"); + FilePath jsonFilePath = workspace.child(jsonFileName); + try { + if(jsonFilePath.exists()) { + String jsonResult = jsonFilePath.readToString(); + CodelessResult codelessResult = mapper.readValue(jsonResult, CodelessResult.class); + testNameToCodelessResultMap.put(testName, codelessResult); + } + } catch (IOException | InterruptedException e) { + logger.warn("Failed to read codeless json result file {}", jsonFileName, e); + } + } + + private void addParametersToUnitsResponse() { + testNameToJunitResultMap.entrySet().forEach(entry -> { + String testName = entry.getKey(); + JUnitTestResult testResult = entry.getValue(); + CodelessResult codelessResult = testNameToCodelessResultMap.get(testName); + if(codelessResult != null) { + List resultIterations = testResult.getUftResultData(); + List> codelessIterations = codelessResult.getIterations(); + // assume that lists have the same size and iterations are equally ordered + if(resultIterations.size() == codelessIterations.size()) { + for(int i = 0; i < resultIterations.size(); i++) { + List steps = resultIterations.get(i).getSteps(); + List currentCodelessUnits = codelessIterations.get(i); + // assume that the iterations have the same units size and units are equally ordered + if(steps.size() == currentCodelessUnits.size()) { + for(int k = 0; k < steps.size(); k++) { + UftResultStepData currentStep = steps.get(k); + CodelessResultUnit currentUnit = currentCodelessUnits.get(k); + mergeParameters(currentStep, currentUnit); + } + } else { + logger.warn("Codeless response for {} iteration {} is inconsistent- # of units does not match", testName, i); + } + } + } else { + logger.warn("Codeless response for {} is inconsistent- # of iterations does not match", testName); + } + } + }); + } + + private void mergeParameters(UftResultStepData stepData, CodelessResultUnit codelessResultUnit) { + if(CollectionUtils.isEmpty(codelessResultUnit.getParameters())) { + return; + } + + codelessResultUnit.getParameters().forEach(parameter -> { + UftResultStepParameter uftResultStepParameter = convertParameter(parameter); + if(parameter.getType().equals("input")) { + stepData.getInputParameters().add(uftResultStepParameter); + } else { + stepData.getOutputParameters().add(uftResultStepParameter); + } + }); + } + + private UftResultStepParameter convertParameter(CodelessResultParameter parameter) { + return new UftResultStepParameter(parameter.getName(), parameter.getValue(), ""); + } + + private void splitTestNameByPattern(){ + Matcher matcher = testParserRegEx.matcher(this.testName); + if (matcher.find()) { + this.externalRunId = this.testName.substring(matcher.start()); + this.testName = this.testName.substring(0, matcher.start()); + } + } + + + private void parseUftErrorMessages() { + try { + if (StringUtils.isNotEmpty(uftResultFilePath)) { + String msg = UftTestResultsUtils.getAggregatedErrorMessage(UftTestResultsUtils.getErrorData(new File(uftResultFilePath))); + if (msg.length() >= 255) { + msg = msg.substring(0, 250) +" ..."; + } + if (StringUtils.isNotEmpty(msg)) { + errorMsg = msg; + } + } + } catch (Exception e) { + logger.error("Failed to parseUftErrorMessages" + e.getMessage()); + } + } + + private static String tryGetStormRunnerReportURLFromLog(Collection logLines) { + //console contains link to report + //link start with "View report:" + String VIEW_REPORT_PREFIX = "view report at:"; + for (Object str : logLines) { + if (str instanceof String && ((String) str).toLowerCase().startsWith(VIEW_REPORT_PREFIX)) { + return ((String) str).substring(VIEW_REPORT_PREFIX.length()).trim(); + } + } + return ""; + } + + private static String tryGetStormRunnerReportURLFromJunitFile(String path) { + try { + String srUrl = null; + File srReport = new File(path); + if (srReport.exists()) { + TestSuite testSuite = DTOFactory.getInstance().dtoFromXmlFile(srReport, TestSuite.class); + for (Property property : testSuite.getProperties()) { + if (property.getPropertyName().equals(SRL_REPORT_URL)) { + srUrl = property.getPropertyValue(); + break; + }; + } + } + return srUrl; + } catch (Exception e) { + logger.debug("Failed to getStormRunnerURL: " + e.getMessage()); + return ""; + } + } + private String extractValueFromStdout(String stdoutValue, String startString, String endString, String defaultValue) { + String result = defaultValue; + int startIndex = stdoutValue.indexOf(startString); + if (startIndex > 0) { + int endIndex = stdoutValue.indexOf(endString, startIndex); + if (endIndex > 0) { + result = stdoutValue.substring(startIndex + startString.length(), endIndex).trim(); + } + } + return result; + } + + private int getUftTestIndexStart(FilePath workspace, String sharedCheckOutDirectory, String testName) { + int returnIndex = -1; + try { + if (sharedCheckOutDirectory == null) { + sharedCheckOutDirectory = ""; + } + String pathToTest; + if (StringUtils.isEmpty(sharedCheckOutDirectory)) { + pathToTest = workspace.getRemote(); + } else { + pathToTest = Paths.get(sharedCheckOutDirectory).isAbsolute() ? + sharedCheckOutDirectory : + Paths.get(FilenameUtils.separatorsToSystem(workspace.getRemote()), + FilenameUtils.separatorsToSystem(sharedCheckOutDirectory)) + .toFile().getCanonicalPath(); + } + + + if (testName.toLowerCase().startsWith(pathToTest.toLowerCase())) { + returnIndex = pathToTest.length() + 1; + } + } catch (Exception e) { + logger.error(String.format("Failed to getUftTestIndexStart for testName '%s' and sharedCheckOutDirectory '%s' : %s", testName, sharedCheckOutDirectory, e.getMessage()), e); + } + return returnIndex; + } + + private String cleanTestName(String testName) { + // subfolder\testname + if (testName.contains("\\")) { + return testName.substring(testName.lastIndexOf('\\') + 1); + } + if (testName.contains("/")) { + return testName.substring(testName.lastIndexOf('/') + 1); + } + return testName; + } + + private String jenkinsTestNameFormat(String testName) { + if (StringUtils.isEmpty(testName)) { + return testName; + } + return testName.trim().replaceAll("[-:\\ ,()/\\[\\]]", "_").replace('#', '_').replace('\\', '_').replace('.', '_'); + } + + private String jenkinsTestClassFormat(String className) { + if (StringUtils.isEmpty(className)) { + return className; + } + return className.trim().replaceAll("[:/<>]", "_").replace("\\", "_").replace(" ", "%20"); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java new file mode 100644 index 0000000000..190194d11a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenBuilderModuleDetection.java @@ -0,0 +1,89 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import hudson.FilePath; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.model.Project; +import hudson.model.Run; +import hudson.tasks.Builder; +import hudson.tasks.Maven; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.File; + +public class MavenBuilderModuleDetection extends AbstractMavenModuleDetection { + + public MavenBuilderModuleDetection(Run build) { + super(build); + } + + protected void addPomDirectories(Run build) { + if (build instanceof AbstractBuild) { + + if (((AbstractBuild)build).getProject() instanceof FreeStyleProject || + JobProcessorFactory.MATRIX_CONFIGURATION_NAME.equals(((AbstractBuild)build).getProject().getClass().getName())) { + boolean unknownBuilder = false; + for (Builder builder : ((Project) ((AbstractBuild)build).getProject()).getBuilders()) { + if (builder instanceof Maven) { + Maven maven = (Maven) builder; + if (maven.pom != null) { + if (maven.pom.endsWith("/pom.xml") || maven.pom.endsWith("\\pom.xml")) { + addPomDirectory(new FilePath(rootDir, maven.pom.substring(0, maven.pom.length() - 8))); + continue; + } else { + int p = maven.pom.lastIndexOf(File.separatorChar); + if (p > 0) { + addPomDirectory(new FilePath(rootDir, maven.pom.substring(0, p))); + continue; + } + } + } + addPomDirectory(rootDir); + } else { + unknownBuilder = true; + } + } + if (unknownBuilder && rootDir != null && !pomDirs.contains(rootDir)) { + // attempt to support shell and batch executions too + // simply assume there is top-level pom file for any non-maven builder + addPomDirectory(rootDir); + } + } + } else if (JobProcessorFactory.WORKFLOW_RUN_NAME.equals(WorkflowRun.class.getName()) && rootDir != null) { + addPomDirectory(rootDir); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java new file mode 100644 index 0000000000..4fd0e6dad7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/MavenSetModuleDetection.java @@ -0,0 +1,58 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import hudson.maven.MavenBuild; +import hudson.maven.MavenModuleSetBuild; +import hudson.model.Run; + +import java.util.Collection; +import java.util.List; + +public class MavenSetModuleDetection extends AbstractMavenModuleDetection { + + public MavenSetModuleDetection(Run build) { + super(build); + } + + protected void addPomDirectories(Run build) { + if (build instanceof MavenModuleSetBuild) { + Collection> builds = ((MavenModuleSetBuild) build).getModuleBuilds().values(); + for (List builds1 : builds) { + for (MavenBuild build2 : builds1) { + addPomDirectory(build2.getWorkspace()); + } + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/ModuleDetection.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/ModuleDetection.java new file mode 100644 index 0000000000..fd8b6ab7cc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/ModuleDetection.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import hudson.FilePath; + +import java.io.IOException; +import java.io.Serializable; + +public interface ModuleDetection extends Serializable { + + String getModule(FilePath resultFile) throws IOException, InterruptedException; + + class Default implements ModuleDetection { + + @Override + public String getModule(FilePath resultFile) throws IOException, InterruptedException { + return ""; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestError.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestError.java new file mode 100644 index 0000000000..b1a0545992 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestError.java @@ -0,0 +1,62 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +import java.io.Serializable; + +/** + * Created by lev on 14/03/2016. + */ +public final class TestError implements Serializable { + private final String stackTraceStr; + private final String errorType; + private final String errorMsg; + + public TestError(String stackTraceStr, String errorType, String errorMsg) { + this.stackTraceStr = stackTraceStr; + this.errorType = errorType; + this.errorMsg = errorMsg; + } + + public String getStackTraceStr() { + return stackTraceStr; + } + + public String getErrorType() { + return errorType; + } + + public String getErrorMsg() { + return errorMsg; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestResultStatus.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestResultStatus.java new file mode 100644 index 0000000000..c4eaf581b1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/TestResultStatus.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit; + +public enum TestResultStatus { + + PASSED("Passed"), + SKIPPED("Skipped"), + FAILED("Failed"); + + private final String prettyName; + + TestResultStatus(String prettyName) { + this.prettyName = prettyName; + } + + public String toPrettyName() { + return prettyName; + } + + public static TestResultStatus fromPrettyName(String prettyName) { + for (TestResultStatus status : values()) { + if (status.toPrettyName().equals(prettyName)) { + return status; + } + } + throw new IllegalArgumentException("Unsupported TestResultStatus '" + prettyName + "'."); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResult.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResult.java new file mode 100644 index 0000000000..0ac2e9cf24 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResult.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit.codeless; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Itay Karo on 02/01/2022 + */ +public class CodelessResult implements Serializable { + + private List> iterations; + + public List> getIterations() { + return iterations; + } + + public void setIterations(List> iterations) { + this.iterations = iterations; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultParameter.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultParameter.java new file mode 100644 index 0000000000..60808ad049 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultParameter.java @@ -0,0 +1,82 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit.codeless; + +import java.io.Serializable; + +/** + * @author Itay Karo on 02/01/2022 + */ +public class CodelessResultParameter implements Serializable { + + private String id; + + private String name; + + private String type; + + private String value; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultUnit.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultUnit.java new file mode 100644 index 0000000000..937a5e7e57 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/junit/codeless/CodelessResultUnit.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.junit.codeless; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Itay Karo on 02/01/2022 + */ +public class CodelessResultUnit implements Serializable { + + private String name; + + private List parameters; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java new file mode 100644 index 0000000000..c8d0853031 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/AbstractXmlIterator.java @@ -0,0 +1,122 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.xml; + +import com.ctc.wstx.stax.WstxInputFactory; +import hudson.util.IOUtils; + +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.XMLEvent; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.NoSuchElementException; + +public abstract class AbstractXmlIterator { + + private InputStream is; + protected XMLEventReader reader; + private LinkedList queue; + private boolean closed; + + public AbstractXmlIterator(InputStream is) throws XMLStreamException { + this.is = is; + reader = createXmlInputFactory().createXMLEventReader(is); + queue = new LinkedList<>(); + } + + public XMLEvent peek() throws XMLStreamException { + return reader.peek(); + } + + public boolean hasNext() throws XMLStreamException, IOException, InterruptedException { + while (queue.isEmpty() && !closed) { + if (reader.hasNext()) { + onEvent(reader.nextEvent()); + } else { + try { + reader.close(); + } catch (XMLStreamException e) { + // close quietly + } + IOUtils.closeQuietly(is); + closed = true; + } + } + return !queue.isEmpty(); + } + + public E next() throws XMLStreamException, IOException, InterruptedException { + if (!hasNext()) { + throw new NoSuchElementException(); + } else { + return queue.removeFirst(); + } + } + + protected abstract void onEvent(XMLEvent event) throws XMLStreamException, IOException, InterruptedException; + + protected void addItem(E item) { + queue.add(item); + } + + protected String readNextValue() throws XMLStreamException { + XMLEvent nextEvent = reader.nextEvent(); + if(nextEvent instanceof EndElement){ + return ""; + } else { + return ((Characters)nextEvent).getData(); + } + } + + protected String peekNextValue() throws XMLStreamException { + XMLEvent event = reader.peek(); + if(event instanceof EndElement){ + return ""; + } else { + return ((Characters)event).getData(); + } + } + + private static XMLInputFactory createXmlInputFactory() { + //up to Jenkins version 2.319.2 this was the XML Input Factory implementation used, new Factory cause test result corruption + XMLInputFactory xmlFactory = new WstxInputFactory(); + xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); + xmlFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + return xmlFactory; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java b/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java new file mode 100644 index 0000000000..cbc51fdec9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriter.java @@ -0,0 +1,137 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.xml; + +import com.hp.octane.integrations.testresults.XmlWritableTestResult; +import com.microfocus.application.automation.tools.octane.tests.TestResultContainer; +import com.microfocus.application.automation.tools.octane.tests.build.BuildDescriptor; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFields; +import hudson.FilePath; +import hudson.model.Run; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +/** + * Save results to mqmTests.xml in XML format + */ +@SuppressWarnings("all") +public class TestResultXmlWriter { + + private FilePath targetPath; + private BuildDescriptor buildDescriptor; + + private XMLStreamWriter writer; + private OutputStream outputStream; + + public TestResultXmlWriter(FilePath targetPath, BuildDescriptor buildDescriptor) { + this.targetPath = targetPath; + this.buildDescriptor = buildDescriptor; + } + + public TestResultXmlWriter(FilePath targetPath, Run build) { + this.targetPath = targetPath; + this.buildDescriptor = BuildHandlerUtils.getBuildType(build); + } + + public void writeResults(TestResultContainer testResultContainer) throws InterruptedException, XMLStreamException, IOException { + if (testResultContainer != null) { + ResultFields resultFields = testResultContainer.getResultFields(); + initialize(resultFields); + + Iterator testResults = testResultContainer.getIterator(); + while (testResults.hasNext()) { + XmlWritableTestResult testResult = testResults.next(); + testResult.writeXmlElement(writer); + } + } + } + + public void close() throws XMLStreamException { + if (outputStream != null) { + writer.writeEndElement(); // test_runs + writer.writeEndElement(); // test_result + writer.writeEndDocument(); + writer.close(); + IOUtils.closeQuietly(outputStream); + } + } + + private void initialize(ResultFields resultFields) throws IOException, InterruptedException, XMLStreamException { + if (outputStream == null) { + outputStream = targetPath.write(); + writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, StandardCharsets.UTF_8.name() ); + writer.writeStartDocument(); + + writer.writeStartElement("test_result"); + writer.writeStartElement("build"); + writer.writeAttribute("server_id", "to-be-filled-in-SDK"); + writer.writeAttribute("job_id", buildDescriptor.getJobId()); + writer.writeAttribute("build_id", buildDescriptor.getBuildId()); + if (!StringUtils.isEmpty(buildDescriptor.getSubType())) { + writer.writeAttribute("sub_type", buildDescriptor.getSubType()); + } + writer.writeEndElement(); // build + writeFields(resultFields); + writer.writeStartElement("test_runs"); + } + } + + private void writeFields(ResultFields resultFields) throws XMLStreamException { + if (resultFields != null) { + writer.writeStartElement("test_fields"); + writeField("Framework", resultFields.getFramework()); + writeField("Test_Level", resultFields.getTestLevel()); + writeField("Testing_Tool_Type", resultFields.getTestingTool()); + writeField("Test_Type", resultFields.getTestType()); + writer.writeEndElement(); + } + } + + private void writeField(String type, String value) throws XMLStreamException { + if (StringUtils.isNotEmpty(value)) { + writer.writeStartElement("test_field"); + writer.writeAttribute("type", type); + writer.writeAttribute("value", value); + writer.writeEndElement(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/ScanResultQueue.java b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/ScanResultQueue.java new file mode 100644 index 0000000000..4bf1832297 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/ScanResultQueue.java @@ -0,0 +1,94 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.vulnerabilities; + +import java.io.Serializable; + +@SuppressWarnings("squid:S2039") +public interface ScanResultQueue { + + ScanResultQueue.QueueItem peekFirst(); + + boolean failed(); + + void remove(); + + void add(String buildId, String jobId, String projectName, String ProjectVersion); + + void clear(); + + class QueueItem implements Serializable { + private static final long serialVersionUID = 1; + private String buildId; + private String jobId; + private String projectName; + private String ProjectVersion; + + public QueueItem(String buildId, String jobId, String projectName, String projectVersion) { + this.buildId = buildId; + this.jobId = jobId; + this.projectName = projectName; + ProjectVersion = projectVersion; + } + + public String getBuildId() { + return buildId; + } + + public void setBuildId(String buildId) { + this.buildId = buildId; + } + + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getProjectVersion() { + return ProjectVersion; + } + + public void setProjectVersion(String projectVersion) { + ProjectVersion = projectVersion; + } + + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesListener.java b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesListener.java new file mode 100644 index 0000000000..80757a411a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesListener.java @@ -0,0 +1,73 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.vulnerabilities; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.configuration.FodConfigUtil; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.configuration.SSCServerConfigUtil; +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.listeners.RunListener; +import org.apache.logging.log4j.Logger; + +/** + * Jenkins events life cycle listener for processing vulnerabilities scan results on build completed + */ + +@Extension +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872"}) +public class VulnerabilitiesListener extends RunListener { + private static Logger logger = SDKBasedLoggerProvider.getLogger(VulnerabilitiesListener.class); + + @Override + public void onFinalized(AbstractBuild build) { + if (!OctaneSDK.hasClients()) { + return; + } + + SSCServerConfigUtil.SSCProjectVersionPair projectVersionPair = SSCServerConfigUtil.getProjectConfigurationFromBuild(build); + if (!VulnerabilitiesUtils.insertQueueItem(build, projectVersionPair)) { + return; + } + + Long release = FodConfigUtil.getFODReleaseFromBuild(build); + if (release != null) { + logger.info("FOD configuration was found in " + build); + VulnerabilitiesUtils.insertFODQueueItem(build, release); + } + if (projectVersionPair == null && release == null) { + logger.debug("No Security Scan integration configuration was found " + build); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesUtils.java b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesUtils.java new file mode 100644 index 0000000000..d05b692147 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesUtils.java @@ -0,0 +1,115 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.vulnerabilities; + +import com.hp.octane.integrations.OctaneClient; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.services.configurationparameters.FortifySSCFetchTimeoutParameter; +import com.hp.octane.integrations.services.vulnerabilities.ToolType; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.configuration.SSCServerConfigUtil; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.model.ParametersAction; +import hudson.model.Run; +import org.apache.logging.log4j.Logger; + +import java.util.HashMap; +import java.util.Map; + +public class VulnerabilitiesUtils { + private static Logger logger = SDKBasedLoggerProvider.getLogger(VulnerabilitiesUtils.class); + private VulnerabilitiesUtils() {} + + public static void insertFODQueueItem(Run run, Long releaseId ) { + HashMap additionalProperties = new HashMap<>(); + additionalProperties.put("releaseId", releaseId.toString()); + insertQueueItem(run, ToolType.FOD, additionalProperties); + } + + + public static boolean insertQueueItem(Run run, SSCServerConfigUtil.SSCProjectVersionPair projectVersionPair) { + if (projectVersionPair != null) { + logger.warn("SSC configuration was found in " + run); + String sscServerUrl = SSCServerConfigUtil.getSSCServer(); + if (sscServerUrl == null || sscServerUrl.isEmpty()) { + logger.debug("SSC configuration not found in the whole CI Server"); + return false; + } + VulnerabilitiesUtils.insertQueueItem(run, ToolType.SSC, null); + } + return true; + } + + private static void insertQueueItem(Run run, ToolType toolType, Map props) { + String jobCiId = BuildHandlerUtils.getJobCiId(run); + String buildCiId = BuildHandlerUtils.getBuildCiId(run); + + final Long queueItemTimeoutHours = getQueueItemTimeoutHoursFromJob(run); + String parents = BuildHandlerUtils.getRootJobCiIds(run); + OctaneSDK.getClients().forEach(octaneClient -> { + octaneClient.getVulnerabilitiesService().enqueueRetrieveAndPushVulnerabilities( + jobCiId, + buildCiId, toolType, + run.getStartTimeInMillis(), + queueItemTimeoutHours == null ? getFortifyTimeoutHours(octaneClient.getInstanceId()) : queueItemTimeoutHours, + props, + parents); + }); + } + + public static int getFortifyTimeoutHours(String instanceId){ + OctaneClient octaneClient = OctaneSDK.getClientByInstanceId(instanceId); + FortifySSCFetchTimeoutParameter parameter = (FortifySSCFetchTimeoutParameter) octaneClient.getConfigurationService().getConfiguration() + .getParameter(FortifySSCFetchTimeoutParameter.KEY); + if (parameter != null) { + return parameter.getTimeout(); + } + return FortifySSCFetchTimeoutParameter.DEFAULT_TIMEOUT; + } + + private static Long getQueueItemTimeoutHoursFromJob(Run run) { + Long queueItemTimeoutHours = null; + String paramName = "fortify-maximum-analysis-timeout-hours"; + try { + ParametersAction parameters = run.getAction(ParametersAction.class); + if (parameters != null && parameters.getParameter(paramName) != null) { + queueItemTimeoutHours = Long.parseLong((String) parameters.getParameter(paramName).getValue()); + } + } catch (Exception e) { + logger.warn("Failed to parse " + paramName + " : " + e.getMessage()); + queueItemTimeoutHours = null; + } + return queueItemTimeoutHours; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesWorkflowListener.java b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesWorkflowListener.java new file mode 100644 index 0000000000..abfccc799b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/octane/vulnerabilities/VulnerabilitiesWorkflowListener.java @@ -0,0 +1,90 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.vulnerabilities; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.configuration.FodConfigUtil; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import com.microfocus.application.automation.tools.octane.configuration.SSCServerConfigUtil; +import com.microfocus.application.automation.tools.octane.tests.build.BuildHandlerUtils; +import hudson.Extension; +import org.apache.logging.log4j.Logger; +import org.jenkinsci.plugins.workflow.flow.GraphListener; +import org.jenkinsci.plugins.workflow.graph.FlowEndNode; +import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.lang.reflect.InvocationTargetException; + +/** + * Jenkins events life cycle listener for processing vulnerabilities scan results on build completed + */ + +@Extension +public class VulnerabilitiesWorkflowListener implements GraphListener { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(VulnerabilitiesWorkflowListener.class); + + @Override + public void onNewHead(FlowNode flowNode) { + if (!OctaneSDK.hasClients()) { + return; + } + try { + if (BuildHandlerUtils.isWorkflowEndNode(flowNode)) { + sendPipelineFinishedEvent((FlowEndNode) flowNode); + } + } catch (Exception e) { + logger.error("failed to build and/or dispatch STARTED/FINISHED event for " + flowNode, e); + } + } + + protected void sendPipelineFinishedEvent(FlowEndNode flowEndNode) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + WorkflowRun parentRun = BuildHandlerUtils.extractParentRun(flowEndNode); + + if (!OctaneSDK.hasClients()) { + return; + } + + SSCServerConfigUtil.SSCProjectVersionPair projectVersionPair = SSCServerConfigUtil.getProjectConfigurationFromWorkflowRun(parentRun); + if (!VulnerabilitiesUtils.insertQueueItem(parentRun, projectVersionPair)) return; + + Long release = FodConfigUtil.getFODReleaseFromRun(parentRun); + if (release != null) { + logger.info("FOD configuration was found in " + parentRun); + VulnerabilitiesUtils.insertFODQueueItem(parentRun, release); + } + if (projectVersionPair == null && release == null) { + logger.debug("No Security Scan integration configuration was found " + parentRun); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pc/PcClient.java b/src/main/java/com/microfocus/application/automation/tools/pc/PcClient.java new file mode 100644 index 0000000000..b33fef168b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pc/PcClient.java @@ -0,0 +1,715 @@ +/* + * 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. + * ___________________________________________________________________ + */ + + +/* + * Implements the main method of loadtest + * + * */ + +package com.microfocus.application.automation.tools.pc; + +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; +import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy; +import com.microfocus.application.automation.tools.pc.helper.DateFormatter; +import com.microfocus.application.automation.tools.run.PcBuilder; +import hudson.FilePath; +import hudson.console.HyperlinkNote; +import org.apache.commons.io.IOUtils; +import org.apache.http.client.ClientProtocolException; + +import java.beans.IntrospectionException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PcClient { + + private PcModel model; + private PcRestProxy restProxy; + private boolean loggedIn; + private PrintStream logger; + private DateFormatter dateFormatter = new DateFormatter(""); + + public PcClient(PcModel pcModel, PrintStream logger) { + try { + model = pcModel; + String credentialsProxyId = model.getCredentialsProxyId(true); + UsernamePasswordCredentials usernamePCPasswordCredentialsForProxy = PcBuilder.getCredentialsId(credentialsProxyId); + String proxyOutUser = (usernamePCPasswordCredentialsForProxy == null || model.getProxyOutURL(true).isEmpty()) ? "" : usernamePCPasswordCredentialsForProxy.getUsername(); + String proxyOutPassword = (usernamePCPasswordCredentialsForProxy == null || model.getProxyOutURL(true).isEmpty()) ? "" : usernamePCPasswordCredentialsForProxy.getPassword().getPlainText(); + if (model.getProxyOutURL(true) != null && !model.getProxyOutURL(true).isEmpty()) { + logger.println(String.format("%s - %s: %s", dateFormatter.getDate(), Messages.UsingProxy(), model.getProxyOutURL(true))); + if (!proxyOutUser.isEmpty()) { + if (model.getCredentialsProxyId().startsWith("$")) + logger.println(String.format("%s - %s %s.", dateFormatter.getDate(), Messages.UsingProxyCredentialsBuildParameters(), proxyOutUser)); + else + logger.println(String.format("%s - %s %s.", dateFormatter.getDate(), Messages.UsingProxyCredentialsConfiguration(), proxyOutUser)); + } + } + restProxy = new PcRestProxy(model.isHTTPSProtocol(), model.getPcServerName(true), model.isAuthenticateWithToken(), model.getAlmDomain(true), model.getAlmProject(true), model.getProxyOutURL(true), proxyOutUser, proxyOutPassword); + this.logger = logger; + } catch (PcException e) { + logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage())); + } + + } + + public PcClient(PcModel pcModel, PrintStream logger, T proxy) { + model = pcModel; + restProxy = proxy; + this.logger = logger; + } + + public boolean login() { + try { + String credentialsId = model.getCredentialsId(true); + UsernamePasswordCredentials usernamePCPasswordCredentials = PcBuilder.getCredentialsId(credentialsId); + if (usernamePCPasswordCredentials != null) { + if (model.getCredentialsId().startsWith("$")) + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.UsingPCCredentialsBuildParameters())); + else + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.UsingPCCredentialsConfiguration())); + logger.println(String.format("%s - %s\n[LRE Server='%s://%s/loadtest/%s', %s='%s']", dateFormatter.getDate(), Messages.TryingToLogin(), model.isHTTPSProtocol(), restProxy.GetPcServer(), restProxy.GetTenant(), model.isAuthenticateWithToken() ? "ClientIdKey" : "User", usernamePCPasswordCredentials.getUsername())); + loggedIn = restProxy.authenticate(usernamePCPasswordCredentials.getUsername(), usernamePCPasswordCredentials.getPassword().getPlainText()); + } else { + logger.println(String.format("%s - %s\n[LRE Server='%s://%s/loadtest/%s', %s='%s']", dateFormatter.getDate(), Messages.TryingToLogin(), model.isHTTPSProtocol(), restProxy.GetPcServer(), restProxy.GetTenant(), model.isAuthenticateWithToken() ? "ClientIdKey" : "User", PcBuilder.usernamePCPasswordCredentials.getUsername())); + loggedIn = restProxy.authenticate(PcBuilder.usernamePCPasswordCredentials.getUsername(), PcBuilder.usernamePCPasswordCredentials.getPassword().getPlainText()); + } + } catch (PcException e) { + logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage())); + } catch (Exception e) { + logger.println(String.format("%s - %s", dateFormatter.getDate(), e)); + } + logger.println(String.format("%s - %s", dateFormatter.getDate(), loggedIn ? Messages.LoginSucceeded() : Messages.LoginFailed())); + return loggedIn; + } + + public boolean isLoggedIn() { + + return loggedIn; + } + + public int startRun() throws NumberFormatException, ClientProtocolException, PcException, IOException { + + + int testID = Integer.parseInt(model.getTestId(true)); + int testInstance = getCorrectTestInstanceID(testID); + setCorrectTrendReportID(); + + logger.println(String.format("%s - \n" + + "%s \n" + + "====================\n" + + "%s: %s \n" + + "%s: %s \n" + + "%s: %s \n" + + "%s: %s \n" + + "%s: %s \n" + + "%s: %s \n" + + "%s: %s \n" + + "====================\n", + dateFormatter.getDate(), + Messages.ExecutingLoadTest(), + Messages.Domain(), model.getAlmDomain(true), + Messages.Project(), model.getAlmProject(true), + Messages.TestID(), Integer.parseInt(model.getTestId(true)), + Messages.TestInstanceID(), testInstance, + Messages.TimeslotDuration(), + new TimeslotDuration(model.getTimeslotDurationHours(true), model.getTimeslotDurationMinutes(true)), + Messages.PostRunAction(), model.getPostRunAction().getValue(), + Messages.UseVUDS(), model.isVudsMode())); + PcRunResponse response = null; + try { + response = restProxy.startRun(testID, + testInstance, + new TimeslotDuration(model.getTimeslotDurationHours(true),model.getTimeslotDurationMinutes(true)), + model.getPostRunAction().getValue(), + model.isVudsMode(), + 0); + logger.println(String.format("%s - %s (TestID: %s, RunID: %s, TimeslotID: %s)", dateFormatter.getDate(), Messages.RunStarted(), + response.getTestID(), response.getID(), response.getTimeslotID())); + return response.getID(); + } catch (NumberFormatException | ClientProtocolException | PcException ex) { + Integer result = checkError1310(ex.getMessage()); + if (result != null) { + return result; + } else { + logger.println(String.format("%s - %s. Error: %s", dateFormatter.getDate(), Messages.StartRunFailed(), ex.getMessage())); + } + } catch (IOException ex) { + logger.println(String.format("%s - %s. IOException Error: %s", dateFormatter.getDate(), Messages.StartRunFailed(), ex.getMessage())); + } + if (!("RETRY".equals(model.getRetry()))) { + return 0; + } else { + //counter + int retryCount = 0; + //values + int retryDelay = Integer.parseInt(model.getRetryDelay()); + int retryOccurrences = Integer.parseInt(model.getRetryOccurrences()); + + while (retryCount <= retryOccurrences) { + retryCount++; + try { + if (retryCount <= retryOccurrences) { + logger.println(String.format("%s - %s. %s (%s %s). %s: %s.", + dateFormatter.getDate(), + Messages.StartRunRetryFailed(), + Messages.AttemptingStartAgainSoon(), + retryDelay, + Messages.Minutes(), + Messages.AttemptsRemaining(), + retryOccurrences - retryCount + 1)); + Thread.sleep(retryDelay * 60 * 1000); + } + } catch (InterruptedException ex) { + logger.println(String.format("%s - wait failed", dateFormatter.getDate())); + } + + try { + response = restProxy.startRun(testID, + testInstance, + new TimeslotDuration(model.getTimeslotDurationHours(true) ,model.getTimeslotDurationMinutes(true)), + model.getPostRunAction().getValue(), + model.isVudsMode(), + 0); + } catch (NumberFormatException | ClientProtocolException | PcException ex) { + Integer result = checkError1310(ex.getMessage()); + if (result != null) { + return result; + } else { + logger.println(String.format("%s -%s. %s: %s", + dateFormatter.getDate(), + Messages.StartRunRetryFailed(), + Messages.Error(), + ex.getMessage())); + } + } catch (IOException ex) { + logger.println(String.format("%s -%s. %s: %s", + dateFormatter.getDate(), + Messages.StartRunRetryFailed(), + Messages.Error(), + ex.getMessage())); + } + int ret = 0; + if (response != null) { + try { + ret = response.getID(); + } catch (Exception ex) { + logger.println(String.format("%s - %s. %s: %s", + dateFormatter.getDate(), + Messages.RetrievingIDFailed(), + Messages.Error(), + ex.getMessage())); + } + } + if (ret != 0) { + logger.println(String.format("%s - %s (TestID: %s, RunID: %s, TimeslotID: %s)\n", + dateFormatter.getDate(), + Messages.RunStarted(), + response.getTestID(), + response.getID(), + response.getTimeslotID())); + return ret; + } + } + } + return 0; + } + + private Integer checkError1310(String msg) { + Pattern p = Pattern.compile("executeRequest exception: Run was started with ID (\\d+), but.*Error code: 1310"); + Matcher m = p.matcher(msg); + if (m.matches()) { + logger.println(String.format("%s - %s. Recovered-error: %s", dateFormatter.getDate(), Messages.StartRunFailed(), msg)); + logger.println(String.format("%s - %s (TestID: %s, RunID: %s, TimeslotID: %s)", dateFormatter.getDate(), Messages.RunStarted(), + Integer.parseInt(model.getTestId(true)), m.group(1), "0")); + return Integer.parseInt(m.group(1)); + } else { + return null; + } + } + + private int getCorrectTestInstanceID(int testID) throws IOException, PcException { + if ("AUTO".equals(model.getAutoTestInstanceID())) { + try { + logger.println(String.format("%s - %s.", + dateFormatter.getDate(), + Messages.SearchingTestInstance())); + PcTestInstances pcTestInstances = null; + try { + pcTestInstances = restProxy.getTestInstancesByTestId(testID); + } catch (PcException ex) { + logger.println(String.format("%s - getTestInstancesByTestId %s. %s: %s", + dateFormatter.getDate(), + Messages.Failure(), + Messages.Error(), + ex.getMessage())); + } + + int testInstanceID; + if (pcTestInstances != null && pcTestInstances.getTestInstancesList() != null) { + PcTestInstance pcTestInstance = pcTestInstances.getTestInstancesList().get(pcTestInstances.getTestInstancesList().size() - 1); + testInstanceID = pcTestInstance.getInstanceId(); + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.FoundTestInstanceID(), + testInstanceID)); + } else { + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + Messages.NotFoundTestInstanceID())); + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + Messages.SearchingAvailableTestSet())); + // Get a random TestSet + PcTestSets pcTestSets = restProxy.GetAllTestSets(); + if (pcTestSets != null && pcTestSets.getPcTestSetsList() != null) { + PcTestSet pcTestSet = pcTestSets.getPcTestSetsList().get(pcTestSets.getPcTestSetsList().size() - 1); + int testSetID = pcTestSet.getTestSetID(); + logger.println(String.format("%s - %s (testID: %s, TestSetID: %s)", + dateFormatter.getDate(), + Messages.CreatingNewTestInstance(), + testID, + testSetID)); + testInstanceID = restProxy.createTestInstance(testID, testSetID); + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.TestInstanceCreatedSuccessfully(), + testInstanceID)); + } else { + String msg = Messages.NoTestSetAvailable(); + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + msg)); + throw new PcException(msg); + } + } + return testInstanceID; + } catch (Exception e) { + logger.println(String.format("%s - getCorrectTestInstanceID %s. %s: %s", + dateFormatter.getDate(), + Messages.Failure(), + Messages.Error(), + e.getMessage())); + return Integer.parseInt(null); + } + } + return Integer.parseInt(model.getTestInstanceId(true)); + } + + private void setCorrectTrendReportID() throws IOException, PcException { + // If the user selected "Use trend report associated with the test" we want the report ID to be the one from the test + String msg = Messages.NoTrendReportAssociated() + "\n" + + Messages.PleaseTurnAutomaticTrendOn() + "\n" + + Messages.PleaseTurnAutomaticTrendOnAlternative(); + if (("ASSOCIATED").equals(model.getAddRunToTrendReport()) && model.getPostRunAction() != PostRunAction.DO_NOTHING) { + PcTest pcTest = restProxy.getTestData(Integer.parseInt(model.getTestId(true))); + //if the trend report ID is parametrized + if (!model.getTrendReportId().startsWith("$")) { + if (pcTest.getTrendReportId() > -1) + model.setTrendReportId(String.valueOf(pcTest.getTrendReportId())); + else { + throw new PcException(msg); + } + } else { + try { + if (Integer.parseInt(model.getTrendReportId(true)) > -1) + model.setTrendReportId(String.valueOf(model.getTrendReportId(true))); + else { + throw new PcException(msg); + } + } catch (Exception ex) { + throw new PcException(msg + System.getProperty("line.separator") + ex); + } + } + } + } + + public String getTestName() throws IOException, PcException { + + try { + PcTest pcTest = restProxy.getTestData(Integer.parseInt(model.getTestId(true))); + return pcTest.getTestName(); + } catch (IOException | PcException ex) { + logger.println(String.format("%s - getTestData %s (testId : %s)", dateFormatter.getDate(), Messages.Failure(), model.getTestId(true))); + throw ex; + } + } + + public PcRunResponse waitForRunCompletion(int runId) throws InterruptedException, ClientProtocolException, PcException, IOException { + + return waitForRunCompletion(runId, 5000); + } + + public PcRunResponse waitForRunCompletion(int runId, int interval) throws InterruptedException, ClientProtocolException, PcException, IOException { + RunState state = RunState.UNDEFINED; + switch (model.getPostRunAction()) { + case DO_NOTHING: + state = RunState.BEFORE_COLLATING_RESULTS; + break; + case COLLATE: + state = RunState.BEFORE_CREATING_ANALYSIS_DATA; + break; + case COLLATE_AND_ANALYZE: + state = RunState.FINISHED; + break; + } + return waitForRunState(runId, state, interval); + } + + + private PcRunResponse waitForRunState(int runId, RunState completionState, int interval) throws InterruptedException, + ClientProtocolException, PcException, IOException { + + int counter = 0; + RunState[] states = {RunState.BEFORE_COLLATING_RESULTS, RunState.BEFORE_CREATING_ANALYSIS_DATA}; + PcRunResponse response = null; + RunState lastState = RunState.UNDEFINED; + int threeStrikes = 3; + do { + try { + + if (threeStrikes < 3) { + logger.println(String.format("%s - Cannot get response from LRE about the state of the Run (ID=%s) %s time(s) consecutively", + dateFormatter.getDate(), + runId, + (3 - threeStrikes))); + if (threeStrikes == 0) { + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.StoppingMonitoringOnRun(), + runId)); + break; + } + Thread.sleep(2000); + login(); + } + response = restProxy.getRunData(runId); + RunState currentState = RunState.get(response.getRunState()); + if (lastState.ordinal() < currentState.ordinal()) { + lastState = currentState; + logger.println(String.format("%s - RunID: %s - State = %s", + dateFormatter.getDate(), + runId, + currentState.value())); + } + + // In case we are in state before collate or before analyze, we will wait 1 minute for the state to change otherwise we exit + // because the user probably stopped the run from LRE or timeslot has reached the end. + if (Arrays.asList(states).contains(currentState)) { + counter++; + Thread.sleep(1000); + if (counter > 60) { + logger.println(String.format("%s - Run ID: %s - %s = %s", + dateFormatter.getDate(), + runId, + Messages.StoppedFromPC(), + currentState.value())); + break; + } + } else { + counter = 0; + Thread.sleep(interval); + } + threeStrikes = 3; + } catch (InterruptedException e) { + throw e; + } catch (PcException e) { + threeStrikes--; + } + } while (lastState.ordinal() < completionState.ordinal()); + return response; + } + + public FilePath publishRunReport(int runId, String reportDirectory) throws IOException, PcException, InterruptedException { + PcRunResults runResultsList = restProxy.getRunResults(runId); + if (runResultsList.getResultsList() != null) { + for (PcRunResult result : runResultsList.getResultsList()) { + if (result.getName().equals(PcBuilder.pcReportArchiveName)) { + File dir = new File(reportDirectory); + dir.mkdirs(); + String reportArchiveFullPath = dir.getCanonicalPath() + IOUtils.DIR_SEPARATOR + PcBuilder.pcReportArchiveName; + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.PublishingAnalysisReport())); + restProxy.GetRunResultData(runId, result.getID(), reportArchiveFullPath); + FilePath fp = new FilePath(new File(reportArchiveFullPath)); + fp.unzip(fp.getParent()); + fp.delete(); + FilePath reportFile = fp.sibling(PcBuilder.pcReportFileName); + if (reportFile.exists()) + return reportFile; + } + } + } + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.FailedToGetRunReport())); + return null; + } + + public boolean logout() { + if (!loggedIn) + return true; + + boolean logoutSucceeded = false; + try { + logoutSucceeded = restProxy.logout(); + loggedIn = !logoutSucceeded; + } catch (PcException e) { + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + e.getMessage())); + } catch (Exception e) { + logger.println(e); + } + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + logoutSucceeded ? Messages.LogoutSucceeded() : Messages.LogoutFailed())); + return logoutSucceeded; + } + + public boolean stopRun(int runId) { + boolean stopRunSucceeded = false; + try { + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.StoppingRun())); + stopRunSucceeded = restProxy.stopRun(runId, "stop"); + } catch (PcException e) { + logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage())); + } catch (Exception e) { + logger.println(String.format("%s - %s", dateFormatter.getDate(), e)); + } + logger.println(String.format("%s - %s", dateFormatter.getDate(), stopRunSucceeded ? Messages.StopRunSucceeded() : Messages.StopRunFailed())); + return stopRunSucceeded; + } + + public PcRunEventLog getRunEventLog(int runId) { + try { + return restProxy.getRunEventLog(runId); + } catch (PcException e) { + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + e.getMessage())); + } catch (Exception e) { + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + e.getMessage())); + } + return null; + } + + public void addRunToTrendReport(int runId, String trendReportId) { + + TrendReportRequest trRequest = new TrendReportRequest(model.getAlmProject(true), runId, null); + logger.println(String.format("%s - Adding run: %s to trend report: %s", + dateFormatter.getDate(), + runId, + trendReportId)); + try { + restProxy.updateTrendReport(trendReportId, trRequest); + logger.println(String.format("%s - %s: %s %s: %s", + dateFormatter.getDate(), + Messages.PublishingRun(), + runId, + Messages.OnTrendReport(), + trendReportId)); + } catch (PcException e) { + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.FailedToAddRunToTrendReport(), + e.getMessage())); + } catch (IOException e) { + logger.println(String.format("%s - %s: %s.", + dateFormatter.getDate(), + Messages.FailedToAddRunToTrendReport(), + Messages.ProblemConnectingToPCServer())); + } + } + + public void waitForRunToPublishOnTrendReport(int runId, String trendReportId) throws PcException, IOException, InterruptedException { + + ArrayList trendReportMetaDataResultsList; + boolean publishEnded = false; + int counterPublishStarted = 0; + int counterPublishNotStarted = 0; + boolean resultNotFound = true; + + do { + trendReportMetaDataResultsList = restProxy.getTrendReportMetaData(trendReportId); + + if (trendReportMetaDataResultsList.isEmpty()) break; + + for (PcTrendedRun result : trendReportMetaDataResultsList) { + resultNotFound = result.getRunID() != runId; + if (resultNotFound) continue; + + if (result.getState().equals(PcBuilder.TRENDED) || result.getState().equals(PcBuilder.ERROR)) { + publishEnded = true; + logger.println(String.format("%s - Run: %s %s: %s", + dateFormatter.getDate(), + runId, + Messages.PublishingStatus(), + result.getState())); + break; + } else { + Thread.sleep(5000); + counterPublishStarted++; + if (counterPublishStarted >= 360) { //waiting 30 minutes for timeout + String msg = String.format("%s: %s", + Messages.Error(), + Messages.PublishingEndTimeout()); + throw new PcException(msg); + } + } + } + if (!publishEnded && resultNotFound) { + Thread.sleep(5000); + counterPublishNotStarted++; + if (counterPublishNotStarted >= 180) { //waiting 15 minutes for timeout + String msg = String.format("%s", + Messages.PublishingStartTimeout()); + throw new PcException(msg); + } else if (counterPublishNotStarted % 12 == 0) { //warning every minute until timeout + logger.println(String.format("%s - %s. %s: %s ... ", + dateFormatter.getDate(), + Messages.WaitingForTrendReportToStart(), + Messages.MinutesUntilTimeout(), + 10 - (counterPublishNotStarted / 12) + )); + } + } + } while (!publishEnded && counterPublishStarted < 120 && counterPublishNotStarted < 120); + } + + public boolean downloadTrendReportAsPdf(String trendReportId, String directory) throws PcException { + + + try { + logger.println(String.format("%s - %s: %s %s", + dateFormatter.getDate(), + Messages.DownloadingTrendReport(), + trendReportId, + Messages.InPDFFormat())); + InputStream in = restProxy.getTrendingPDF(trendReportId); + File dir = new File(directory); + if (!dir.exists()) { + dir.mkdirs(); + } + String filePath = directory + IOUtils.DIR_SEPARATOR + "trendReport" + trendReportId + ".pdf"; + Path destination = Paths.get(filePath); + Files.copy(in, destination, StandardCopyOption.REPLACE_EXISTING); + logger.println(String.format("%s - %s: %s %s", + dateFormatter.getDate(), + Messages.TrendReport(), + trendReportId, + Messages.SuccessfullyDownloaded())); + } catch (Exception e) { + + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.FailedToDownloadTrendReport(), + e.getMessage())); + throw new PcException(e.getMessage()); + } + + return true; + + } + + public void publishTrendReport(String filePath, String trendReportId) { + + if (filePath == null) { + return; + } + // return String.format( HyperlinkNote.encodeTo(filePath, "View trend report " + trendReportId)); + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + HyperlinkNote.encodeTo(filePath, Messages.ViewTrendReport() + " " + trendReportId))); + + } + + + // This method will return a map with the following structure: + // for example: + // + // + // This function uses reflection since we know only at runtime which transactions data will be reposed from the rest request. + public Map getTrendReportByXML(String trendReportId, int runId, TrendReportTypes.DataType dataType, TrendReportTypes.PctType pctType, TrendReportTypes.Measurement measurement) throws IOException, PcException, IntrospectionException, NoSuchMethodException { + + Map measurmentsMap = new LinkedHashMap(); + measurmentsMap.put("RunId", "_" + runId + "_"); + measurmentsMap.put("Trend Measurement Type", measurement.toString() + "_" + pctType.toString()); + + + TrendReportTransactionDataRoot res = restProxy.getTrendReportByXML(trendReportId, runId); + +// java.lang.reflect.Method rootMethod = res.getClass().getMethod("getTrendReport" + dataType.toString() + "DataRowsList"); +// ArrayList RowsListObj = (ArrayList) rootMethod.invoke(res); +// RowsListObj.get(0); + + List RowsListObj = res.getTrendReportRoot(); + + for (int i = 0; i < RowsListObj.size(); i++) { + try { + + java.lang.reflect.Method rowListMethod = RowsListObj.get(i).getClass().getMethod("getTrendReport" + dataType.toString() + "DataRowList"); + + for (Object DataRowObj : (ArrayList) rowListMethod.invoke(RowsListObj.get(i))) { + if (DataRowObj.getClass().getMethod("getPCT_TYPE").invoke(DataRowObj).equals(pctType.toString())) { + java.lang.reflect.Method method; + method = DataRowObj.getClass().getMethod("get" + measurement.toString()); + measurmentsMap.put(DataRowObj.getClass().getMethod("getPCT_NAME").invoke(DataRowObj).toString(), method.invoke(DataRowObj) == null ? "" : method.invoke(DataRowObj).toString()); + } + } + } catch (NoSuchMethodException e) { + // logger.println("No such method exception: " + e); + } catch (Exception e) { + // logger.println(String.format("%s - Error on getTrendReportByXML: %s ", dateFormatter.getDate(), e)); + } + } + + + // logger.print(res); + + + return measurmentsMap; + + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pc/PcModel.java b/src/main/java/com/microfocus/application/automation/tools/pc/PcModel.java new file mode 100644 index 0000000000..72fd4c05d0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pc/PcModel.java @@ -0,0 +1,353 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +/* + * Takes all the parameter from the job in order to create a loadtest object + * */ +package com.microfocus.application.automation.tools.pc; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.PostRunAction; +import com.microfocus.adm.performancecenter.plugins.common.pcentities.TimeslotDuration; +import com.microfocus.application.automation.tools.model.SecretContainer; +import com.microfocus.application.automation.tools.model.SecretContainerImpl; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.Arrays; +import java.util.List; + +public class PcModel { + + public static final String COLLATE = "Collate Results"; + public static final String COLLATE_ANALYZE = "Collate and Analyze"; + public static final String DO_NOTHING = "Do Not Collate"; + + private final String serverAndPort; + private final String pcServerName; + private final String credentialsId; + private final String almDomain; + private final String almProject; + private final String testId; + private final String autoTestInstanceID; + private final PostRunAction postRunAction; + private final boolean vudsMode; + private final String description; + private final String addRunToTrendReport; + private final boolean HTTPSProtocol; + private final String proxyOutURL; + private final String credentialsProxyId; + private final boolean authenticateWithToken; + private String testInstanceId; + private String trendReportId; + private String buildParameters; + private String retry; + private String retryDelay; + private String retryOccurrences; + private String timeslotDurationHours; + private String timeslotDurationMinutes; + + @DataBoundConstructor + public PcModel(String serverAndPort, String pcServerName, String credentialsId, String almDomain, String almProject, + String testId, String autoTestInstanceID, String testInstanceId, String timeslotDurationHours, String timeslotDurationMinutes, + PostRunAction postRunAction, boolean vudsMode, String description, String addRunToTrendReport, String trendReportId, boolean HTTPSProtocol, + String proxyOutURL, String credentialsProxyId, String retry, String retryDelay, String retryOccurrences, boolean authenticateWithToken) { + + this.serverAndPort = serverAndPort; + this.pcServerName = pcServerName; + this.credentialsId = credentialsId; + this.almDomain = almDomain; + this.almProject = almProject; + this.testId = testId; + this.autoTestInstanceID = autoTestInstanceID; + this.testInstanceId = testInstanceId; + this.timeslotDurationHours = timeslotDurationHours; + this.timeslotDurationMinutes = timeslotDurationMinutes; + this.postRunAction = postRunAction; + this.vudsMode = vudsMode; + this.description = description; + this.addRunToTrendReport = addRunToTrendReport; + this.HTTPSProtocol = HTTPSProtocol; + this.trendReportId = trendReportId; + this.proxyOutURL = proxyOutURL; + this.credentialsProxyId = credentialsProxyId; + this.buildParameters = ""; + this.retry = retry; + this.retryDelay = verifyStringValueIsIntAndPositive(retryDelay, 5); + this.retryOccurrences = verifyStringValueIsIntAndPositive(retryOccurrences, 3); + this.authenticateWithToken = authenticateWithToken; + } + + private static boolean isInteger(String s, int radix) { + if (s.isEmpty()) return false; + for (int i = 0; i < s.length(); i++) { + if (i == 0 && s.charAt(i) == '-') { + if (s.length() == 1) return false; + else continue; + } + if (Character.digit(s.charAt(i), radix) < 0) return false; + } + return true; + } + + private static boolean isInteger(String s) { + return isInteger(s, 10); + } + + public static List getPostRunActions() { + return Arrays.asList(PostRunAction.values()); + } + + private static String useParameterIfNeeded(String buildParameters, String attribute) { + if (buildParameters != null && attribute != null) { + if (attribute.startsWith("$")) { + String attributeParameter = attribute.replace("$", "").replace("{", "").replace("}", ""); + String[] buildParametersArray = buildParameters.replace("{", "").replace("}", "").split(","); + for (String buildParameter : buildParametersArray) { + if (buildParameter.trim().startsWith(attributeParameter + "=")) { + return buildParameter.trim().replace(attributeParameter + "=", ""); + } + } + } + } + return attribute; + } + + private String verifyStringValueIsIntAndPositive(String supplied, int defaultValue) { + if (supplied != null && isInteger(supplied)) { + int suppliedInt = Integer.parseInt(supplied); + if (suppliedInt > 0) + return Integer.toString(suppliedInt); + } + return Integer.toString(defaultValue); + } + + public String getRetry() { + + return this.retry; + } + + public String getRetryDelay() { + return this.retryDelay; + } + + public String getRetryOccurrences() { + + return this.retryOccurrences; + } + + protected SecretContainer setPassword(String almPassword) { + + SecretContainer secretContainer = new SecretContainerImpl(); + secretContainer.initialize(almPassword); + return secretContainer; + } + + public String getserverAndPort() { + return this.serverAndPort; + } + + public String getPcServerName() { + + return this.pcServerName; + } + + public String getPcServerName(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.pcServerName) : getPcServerName(); + } + + public String getCredentialsId() { + + return this.credentialsId; + } + + public String getCredentialsId(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.credentialsId) : getCredentialsId(); + } + + public String getCredentialsProxyId() { + + return this.credentialsProxyId; + } + + public String getCredentialsProxyId(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.credentialsProxyId) : getCredentialsProxyId(); + } + + public String getAlmDomain() { + + return this.almDomain; + } + + public String getAlmDomain(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.almDomain) : getAlmDomain(); + } + + public String getAlmProject() { + + return this.almProject; + } + + public String getAlmProject(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.almProject) : getAlmProject(); + } + + public String getTestId() { + + return this.testId; + } + + public String getTestId(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.testId) : getTestId(); + } + + public String getTestInstanceId() { + + return this.testInstanceId; + } + + public String getTestInstanceId(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.testInstanceId) : getTestInstanceId(); + } + + public String getAutoTestInstanceID() { + return this.autoTestInstanceID; + } + + public String getTimeslotDurationHours() { + + return this.timeslotDurationHours; + } + + public String getTimeslotDurationHours(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.timeslotDurationHours) : getTimeslotDurationHours(); + } + + public String getTimeslotDurationMinutes() { + + return this.timeslotDurationMinutes; + } + + public String getTimeslotDurationMinutes(boolean fromPcClient) { + + return fromPcClient ? useParameterIfNeeded(buildParameters, this.timeslotDurationMinutes) : getTimeslotDurationMinutes(); + } + + public boolean isVudsMode() { + + return this.vudsMode; + } + + public PostRunAction getPostRunAction() { + + return this.postRunAction; + } + + public String getDescription() { + + return this.description; + } + + public boolean httpsProtocol() { + return this.HTTPSProtocol; + } + + public String getProxyOutURL() { + return this.proxyOutURL; + } + + public String getProxyOutURL(boolean fromPcClient) { + return fromPcClient ? useParameterIfNeeded(buildParameters, this.proxyOutURL) : getProxyOutURL(); + } + + public String getBuildParameters() { + return this.buildParameters; + } + + public void setBuildParameters(String buildParameters) { + this.buildParameters = buildParameters; + } + + @Override + public String toString() { + + return String.format("%s", runParamsToString().substring(1)); + } + + public String runParamsToString() { + + String vudsModeString = (vudsMode) ? "true" : "false"; + String trendString = ("USE_ID").equals(addRunToTrendReport) ? String.format(", TrendReportID = '%s'", trendReportId) : ""; + + return String.format("[PCServer='%s', CredentialsId='%s', Domain='%s', Project='%s', TestID='%s', " + + "TestInstanceID='%s', TimeslotDurationHours='%s', TimeslotDurationMinutes='%s', PostRunAction='%s', " + + "VUDsMode='%s, trending='%s', HTTPSProtocol='%s', authenticateWithToken='%s']", + + pcServerName, credentialsId, almDomain, almProject, testId, + testInstanceId, timeslotDurationHours, timeslotDurationMinutes, postRunAction.getValue(), + vudsModeString, trendString, HTTPSProtocol, authenticateWithToken); + } + + public String getTrendReportId() { + return trendReportId; + } + + public void setTrendReportId(String trendReportId) { + this.trendReportId = trendReportId; + } + + public String getTrendReportId(boolean fromPcClient) { + return fromPcClient ? useParameterIfNeeded(buildParameters, this.trendReportId) : getTrendReportId(); + } + + public String getAddRunToTrendReport() { + return addRunToTrendReport; + } + + public String isHTTPSProtocol() { + if (!HTTPSProtocol) + return "http"; + return "https"; + } + + public boolean isAuthenticateWithToken() { + return this.authenticateWithToken; + } + + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pc/helper/DateFormatter.java b/src/main/java/com/microfocus/application/automation/tools/pc/helper/DateFormatter.java new file mode 100644 index 0000000000..87d8359713 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pc/helper/DateFormatter.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc.helper; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateFormatter { + + public static final String DEFAULT_PATTERN = "E yyyy MMM dd 'at' HH:mm:ss.SSS a zzz"; + + private SimpleDateFormat simpleDateFormat; + private String pattern; + private String date; + + public DateFormatter(String pattern) { + this.pattern = pattern.isEmpty() ? DEFAULT_PATTERN : pattern; + simpleDateFormat = new SimpleDateFormat(this.pattern); + renewDate(); + } + + public void renewDate() { + try { + date = simpleDateFormat.format(new Date()); + } catch (Exception ex) { + this.pattern = DEFAULT_PATTERN; + simpleDateFormat = new SimpleDateFormat(this.pattern); + date = simpleDateFormat.format(new Date()); + } + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern.isEmpty() ? DEFAULT_PATTERN : pattern; + simpleDateFormat = new SimpleDateFormat(this.pattern); + } + + public String getDate() { + try { + renewDate(); + return date; + } catch (Exception ex) { + return ""; + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep.java new file mode 100644 index 0000000000..e13c35d39d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep.java @@ -0,0 +1,158 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.run.RunLoadRunnerScript; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Computer; +import hudson.model.Node; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; +import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; +import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; +import org.jenkinsci.plugins.workflow.steps.StepContextParameter; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import java.io.IOException; +import java.util.logging.Logger; + + +public class LoadRunnerScriptStep extends AbstractStepImpl { + private final RunLoadRunnerScript runLoadRunnerScript; + + @DataBoundConstructor + public LoadRunnerScriptStep(String scriptPath) { + this.runLoadRunnerScript = new RunLoadRunnerScript(scriptPath); + } + + public String getScriptPath() { + return this.runLoadRunnerScript.getScriptsPath(); + } + + /** + * Gets run from file builder. + * + * @return the run from file builder + */ + public RunLoadRunnerScript getRunLoadRunnerScript() { + return this.runLoadRunnerScript; + } + + /** + * The type DescriptorImpl. + */ + @Extension + @Symbol("runLoadRunnerScript") + public static class DescriptorImpl extends AbstractStepDescriptorImpl { + /** + * Instantiates a new DescriptorImpl. + */ + public DescriptorImpl() { + super(LoadRunnerScriptStepExecution.class); + } + + @Override + public String getFunctionName() { + return "runLoadRunnerScript"; + } + + @Nonnull + @Override + public String getDisplayName() { + return "Run LoadRunner script"; + } + + } + + + private static class LoadRunnerScriptStepExecution extends AbstractSynchronousNonBlockingStepExecution { + + /** + * Logger. + */ + private static final Logger logger = Logger + .getLogger(LoadRunnerScriptStepExecution.class.getName()); + private static final long serialVersionUID = 1L; + @Inject + @SuppressWarnings("squid:S3306") + private transient LoadRunnerScriptStep step; + @StepContextParameter + private transient TaskListener listener; + @StepContextParameter + private transient FilePath ws; + @StepContextParameter + private transient Run build; + @StepContextParameter + private transient Launcher launcher; + @StepContextParameter + private transient EnvVars env; + @StepContextParameter + private transient Computer computer; + @StepContextParameter + private transient Node node; + + public LoadRunnerScriptStepExecution() { + //No need for constructor + } + + /** + * Meat of the execution. + *

+ * When this method returns, a step execution is over. + */ + @Override + protected Void run() throws Exception { + + listener.getLogger().println("Running LoadRunner Script Runner step"); + + try { + step.getRunLoadRunnerScript().perform(build, ws, launcher, listener, env); + } catch (IOException e) { + listener.fatalError("LoadRunner script runner stage encountered an IOException " + e); + build.setResult(Result.FAILURE); + return null; + } + + return null; + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java new file mode 100644 index 0000000000..8c30c8135d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep.java @@ -0,0 +1,356 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; +import com.microfocus.application.automation.tools.lr.model.SummaryDataLogModel; +import com.microfocus.application.automation.tools.lr.model.ScriptRTSSetModel; +import com.microfocus.application.automation.tools.results.RunResultRecorder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import hudson.Extension; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; +import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Objects; + +/** + * Load runner pipeline step + */ +public class LoadRunnerTestStep extends AbstractStepImpl { + + private final RunFromFileBuilder runFromFileBuilder; + private final RunResultRecorder runResultRecorder; + + /** + * Instantiates a new Lr scenario load step. + * + * @param testPaths the test paths + * @param archiveTestResultsMode the type of archiving the user wants. + */ + @DataBoundConstructor + public LoadRunnerTestStep(String testPaths, String archiveTestResultsMode) { + this.runFromFileBuilder = new RunFromFileBuilder(testPaths); + this.runResultRecorder = new RunResultRecorder(archiveTestResultsMode); + } + + /** + * Gets archive run test results mode. + * + * @return the archive run test results mode + */ + public String getArchiveTestResultsMode() { + return runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); + } + + /** + * Gets controller polling interval. + * + * @return the controller polling interval + */ + public String getControllerPollingInterval() { + return runFromFileBuilder.getRunFromFileModel().getControllerPollingInterval(); + } + + /** + * Sets controller polling interval. + * + * @param controllerPollingInterval the controller polling interval + */ + @DataBoundSetter + public void setControllerPollingInterval(String controllerPollingInterval) { + runFromFileBuilder.setControllerPollingInterval(controllerPollingInterval); + } + + /** + * Gets fs timeout. + * + * @return the fs timeout + */ + public String getFsTimeout() { + return runFromFileBuilder.getRunFromFileModel().getFsTimeout(); + } + + /** + * Sets fs timeout. + * + * @param fsTimeout the fs timeout + */ + @DataBoundSetter + public void setFsTimeout(String fsTimeout) { + runFromFileBuilder.setFsTimeout(fsTimeout); + } + + /** + * Gets per scenario time out. + * + * @return the per scenario time out + */ + public String getPerScenarioTimeOut() { + return runFromFileBuilder.getRunFromFileModel().getPerScenarioTimeOut(); + } + + /** + * Sets per scenario time out. + * + * @param perScenarioTimeOut the per scenario time out + */ + @DataBoundSetter + public void setPerScenarioTimeOut(String perScenarioTimeOut) { + runFromFileBuilder.setPerScenarioTimeOut(perScenarioTimeOut); + } + + /** + * Gets test paths. + * + * @return the test paths + */ + public String getTestPaths() { + return runFromFileBuilder.getRunFromFileModel().getFsTests(); + } + + /** + * Gets ignore error strings. + * + * @return the ignore error strings + */ + public String getIgnoreErrorStrings() { + return runFromFileBuilder.getRunFromFileModel().getIgnoreErrorStrings(); + } + + /** + * Sets ignore error strings. + * + * @param ignoreErrorStrings the ignore error strings + */ + @DataBoundSetter + public void setIgnoreErrorStrings(String ignoreErrorStrings) { + runFromFileBuilder.setIgnoreErrorStrings(ignoreErrorStrings); + } + + /** + * Gets analysis template. + * + * @return the analysis template + */ + public String getAnalysisTemplate() { + return runFromFileBuilder.getRunFromFileModel().getAnalysisTemplate(); + } + + /** + * Sets analysis template. + * + * @param analysisTemplate the analysis template + */ + @DataBoundSetter + public void setAnalysisTemplate(String analysisTemplate) { + runFromFileBuilder.setAnalysisTemplate(analysisTemplate); + } + + + /** + * Gets display controller. + * + * @return the display controller + */ + public String getDisplayController() { + return runFromFileBuilder.getRunFromFileModel().getDisplayController(); + } + + /** + * Sets display controller. + * + * @param displayController the display controller + */ + @DataBoundSetter + public void setDisplayController(String displayController) { + runFromFileBuilder.setDisplayController(displayController); + } + + public SummaryDataLogModel getSummaryDataLogModel() { + return runFromFileBuilder.getSummaryDataLogModel(); + } + + @DataBoundSetter + public void setSummaryDataLogModel(SummaryDataLogModel summaryDataLogModel) { + runFromFileBuilder.setSummaryDataLogModel(summaryDataLogModel); + } + + public ScriptRTSSetModel getScriptRTSSetModel() { + return runFromFileBuilder.getScriptRTSSetModel(); + } + + @DataBoundSetter + public void setScriptRTSSetModel(ScriptRTSSetModel scriptRTSSetModel) { + runFromFileBuilder.setScriptRTSSetModel(scriptRTSSetModel); + } + + /** + * Gets run from file builder. + * + * @return the run from file builder + */ + public RunFromFileBuilder getRunFromFileBuilder() { + return runFromFileBuilder; + } + + public RunResultRecorder getRunResultRecorder() { + return runResultRecorder; + } + + /** + * The type Descriptor. + */ + @Extension + @Symbol("loadRunnerTest") + public static class DescriptorImpl extends AbstractStepDescriptorImpl { + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { + super(LrScenarioLoadStepExecution.class); + } + + @Override + public String getFunctionName() { + return "loadRunnerTest"; + } + + @Nonnull + @Override + public String getDisplayName() { + return "Run LoadRunner performance scenario tests"; + } + + /** + * Gets report archive modes. + * + * @return the report archive modes + */ + public List getReportArchiveModes() { + + return ResultsPublisherModel.archiveModes; + } + + /** + * Do check fs tests form validation. + * + * @param value the value + * @return the form validation + */ + @SuppressWarnings("squid:S1172") + public FormValidation doCheckFsTests(@QueryParameter String value) { + return FormValidation.ok(); + } + + /** + * Do check ignore error strings form validation. + * + * @param value the value + * @return the form validation + */ + @SuppressWarnings("squid:S1172") + public FormValidation doCheckIgnoreErrorStrings(@QueryParameter String value) { + + return FormValidation.ok(); + } + + /** + * Do check fs timeout form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckFsTimeout(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + String val1 = value.trim(); + if (val1.length() > 0 && val1.charAt(0) == '-') { + val1 = val1.substring(1); + } + + if (!StringUtils.isNumeric(val1) && !Objects.equals(val1, "")) { + return FormValidation.error("Timeout name must be a number"); + } + return FormValidation.ok(); + } + + /** + * Do check controller polling interval form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckControllerPollingInterval(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + if (!StringUtils.isNumeric(value)) { + return FormValidation.error("Controller Polling Interval must be a number"); + } + + return FormValidation.ok(); + } + + /** + * Do check per scenario time out form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckPerScenarioTimeOut(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + if (!StringUtils.isNumeric(value)) { + return FormValidation.error("Per Scenario Timeout must be a number"); + } + + return FormValidation.ok(); + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java new file mode 100644 index 0000000000..6640526d34 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepExecution.java @@ -0,0 +1,101 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; +import org.jenkinsci.plugins.workflow.steps.StepContextParameter; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.HashMap; +import java.util.logging.Logger; + + +/** + * The Load runner pipeline step execution. + */ +public class LrScenarioLoadStepExecution extends AbstractSynchronousNonBlockingStepExecution { + + /** + * Logger. + */ + private static final Logger logger = Logger + .getLogger(LrScenarioLoadStepExecution.class.getName()); + + private static final long serialVersionUID = 1L; + @Inject + @SuppressWarnings("squid:S3306") + private transient LoadRunnerTestStep step; + @StepContextParameter + private transient TaskListener listener; + @StepContextParameter + private transient FilePath ws; + @StepContextParameter + private transient Run build; + @StepContextParameter + private transient Launcher launcher; + + public LrScenarioLoadStepExecution() { + //no need for actual construction + } + + @Override + protected Void run() throws InterruptedException { + listener.getLogger().println("Running LoadRunner Scenario step"); + try { + step.getRunFromFileBuilder().perform(build, ws, launcher, listener); + } catch (IOException e) { + listener.fatalError("LoadRunnner scenario run stage encountered an IOException " + e); + build.setResult(Result.FAILURE); + return null; + } + HashMap resultFilename = new HashMap(0); + resultFilename.put(RunFromFileBuilder.class.getName(), step.getRunFromFileBuilder().getRunResultsFileName()); + + try { + step.getRunResultRecorder().pipelinePerform(build, ws, launcher, listener, resultFilename); + } catch (IOException e) { + listener.fatalError("LoadRunnner scenario run result recorder stage encountered an IOException " + e); + build.setResult(Result.FAILURE); + return null; + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java similarity index 76% rename from src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java rename to src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java index 81e9994e33..567190a58d 100644 --- a/src/main/java/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep.java @@ -1,42 +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 (c) 2012 Hewlett-Packard Development Company, L.P. + * Copyright 2012-2023 Open Text * - * 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. + * 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. * - * A pipeline step that combined with ssebuilder and runresultrecorder. - * Created by llu4 on 10/20/2016. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.pipelineSteps; +package com.microfocus.application.automation.tools.pipelineSteps; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; import com.cloudbees.plugins.credentials.matchers.IdMatcher; -import com.hp.application.automation.tools.model.*; -import com.hp.application.automation.tools.results.RunResultRecorder; -import com.hp.application.automation.tools.run.SseBuilder; -import com.hp.application.automation.tools.settings.AlmServerSettingsBuilder; +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.results.RunResultRecorder; +import com.microfocus.application.automation.tools.run.SseBuilder; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; +import com.microfocus.application.automation.tools.model.SseModel; import hudson.Extension; import hudson.Util; import hudson.model.Hudson; @@ -81,6 +89,7 @@ public RunResultRecorder getRunResultRecorder() { public SseBuildAndPublishStep(String almServerName, String almProject, String credentialsId, + String clientType, String almDomain, String runType, String almEntityId, @@ -90,6 +99,7 @@ public SseBuildAndPublishStep(String almServerName, sseBuilder = new SseBuilder(almServerName, almProject, credentialsId, + clientType, almDomain, runType, almEntityId, @@ -114,6 +124,8 @@ public String getAlmDomain() { return sseBuilder.getAlmDomain(); } + public String getClientType() { return sseBuilder.getClientType(); } + public String getRunType() { return sseBuilder.getRunType(); } @@ -166,15 +178,6 @@ public CdaDetails getCdaDetails() { return sseBuilder.getCdaDetails(); } - @DataBoundSetter - public void setProxySettings(SseProxySettings proxySettings) { - sseBuilder.setProxySettings(proxySettings); - } - - public SseProxySettings getProxySettings() { - return sseBuilder.getProxySettings(); - } - // This indicates to Jenkins that this is an implementation of an extension point @Extension public static final class DescriptorImpl extends AbstractStepDescriptorImpl { @@ -194,18 +197,16 @@ public String getFunctionName() { @Override public String getDisplayName() { - return "Execute HP tests using HP ALM Lab Management and Publish HP tests result"; + return "Execute tests using ALM Lab Management and Publish tests result"; } public boolean hasAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).hasAlmServers(); + return AlmServerSettingsGlobalConfiguration.getInstance().hasAlmServers(); } public AlmServerSettingsModel[] getAlmServers() { - return Hudson.getInstance().getDescriptorByType( - AlmServerSettingsBuilder.DescriptorImpl.class).getInstallations(); + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); } public FormValidation doCheckTimeslotDuration(@QueryParameter String value) { @@ -296,14 +297,6 @@ public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, .includeCurrentValue(credentialsId); } - /** - * To fill in the credentials drop down list which's field is 'FsProxyCredentialsId'. - */ - public ListBoxModel doFillFsProxyCredentialsIdItems(@AncestorInPath Item project, - @QueryParameter String credentialsId) { - return doFillCredentialsIdItems(project, credentialsId); - } - public FormValidation doCheckCredentialsId(@AncestorInPath Item project, @QueryParameter String url, @QueryParameter String value) { diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java new file mode 100644 index 0000000000..7397ea427b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SseBuilderPublishResultStepExecution.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.results.RunResultRecorder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import com.microfocus.application.automation.tools.run.SseBuilder; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; +import org.jenkinsci.plugins.workflow.steps.StepContextParameter; +import org.apache.commons.lang.StringUtils; +import javax.inject.Inject; +import java.util.HashMap; + +public class SseBuilderPublishResultStepExecution extends AbstractSynchronousNonBlockingStepExecution { + + private static final long serialVersionUID = 1L; + + @Inject + private transient SseBuildAndPublishStep step; + + @StepContextParameter + private transient TaskListener listener; + + @StepContextParameter + private transient FilePath ws; + + @StepContextParameter + private transient Run build; + + @StepContextParameter + private transient Launcher launcher; + + @Override + protected Void run() throws Exception { + listener.getLogger().println("Execute tests using ALM Lab Management"); + + SseBuilder sseBuilder = step.getSseBuilder(); + RunResultRecorder runResultRecorder = step.getRunResultRecorder(); + + String archiveTestResultsMode = runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); + + sseBuilder.perform(build, ws, launcher, listener); + + if (StringUtils.isNotBlank(archiveTestResultsMode)) { + listener.getLogger().println("Publish tests result"); + + HashMap resultFilename = new HashMap(0); + resultFilename.put(RunFromFileBuilder.class.getName(), sseBuilder.getRunResultsFileName()); + + runResultRecorder.pipelinePerform(build, ws, launcher, listener, resultFilename); + } + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvChangeModeStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvChangeModeStep.java new file mode 100644 index 0000000000..516df1f1be --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvChangeModeStep.java @@ -0,0 +1,103 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.model.SvDataModelSelection; +import com.microfocus.application.automation.tools.model.SvPerformanceModelSelection; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.run.SvChangeModeBuilder; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStep; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStepDescriptor; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; +import hudson.Extension; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvChangeModeStep extends AbstractSvStep { + private final ServiceRuntimeConfiguration.RuntimeMode mode; + private final SvDataModelSelection dataModel; + private final SvPerformanceModelSelection performanceModel; + private final SvServiceSelectionModel serviceSelection; + + @DataBoundConstructor + public SvChangeModeStep(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, + SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { + super(serverName, force); + this.mode = mode; + this.dataModel = dataModel; + this.performanceModel = performanceModel; + this.serviceSelection = serviceSelection; + } + + public ServiceRuntimeConfiguration.RuntimeMode getMode() { + return mode; + } + + public SvDataModelSelection getDataModel() { + return dataModel; + } + + public SvPerformanceModelSelection getPerformanceModel() { + return performanceModel; + } + + public SvServiceSelectionModel getServiceSelection() { + return serviceSelection; + } + + @Override + public SimpleBuildStep getBuilder() { + return new SvChangeModeBuilder(serverName, force, mode, dataModel, performanceModel, serviceSelection); + } + + @Extension + public static class DescriptorImpl extends AbstractSvStepDescriptor { + public DescriptorImpl() { + super(SvExecution.class, "svChangeModeStep", new SvChangeModeBuilder.DescriptorImpl()); + } + + @SuppressWarnings("unused") + public FormValidation doCheckDataModel(@QueryParameter String value, @QueryParameter("mode") String mode, + @QueryParameter("serviceSelectionKind") String kind) { + return builderDescriptor.doCheckDataModel(value, mode, kind); + } + + @SuppressWarnings("unused") + public ListBoxModel doFillModeItems() { + return builderDescriptor.doFillModeItems(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvDeployStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvDeployStep.java new file mode 100644 index 0000000000..bc18ac8354 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvDeployStep.java @@ -0,0 +1,96 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.run.SvDeployBuilder; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStep; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStepDescriptor; +import hudson.Extension; +import hudson.util.FormValidation; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvDeployStep extends AbstractSvStep { + private final String service; + private final String projectPath; + private final String projectPassword; + private final boolean firstAgentFallback; + + @DataBoundConstructor + public SvDeployStep(String serverName, boolean force, String service, String projectPath, String projectPassword, boolean firstAgentFallback) { + super(serverName, force); + this.service = service; + this.projectPath = projectPath; + this.projectPassword = projectPassword; + this.firstAgentFallback = firstAgentFallback; + } + + public String getService() { + return service; + } + + public String getProjectPath() { + return projectPath; + } + + public String getProjectPassword() { + return projectPassword; + } + + public boolean isFirstAgentFallback() { + return firstAgentFallback; + } + + @Override + public SimpleBuildStep getBuilder() { + return new SvDeployBuilder(serverName, force, service, projectPath, projectPassword, firstAgentFallback); + } + + @Extension + public static class DescriptorImpl extends AbstractSvStepDescriptor { + public DescriptorImpl() { + super(SvExecution.class, "svDeployStep", new SvDeployBuilder.DescriptorImpl()); + } + + @SuppressWarnings("unused") + public FormValidation doCheckProjectPath(@QueryParameter String projectPath) { + return builderDescriptor.doCheckProjectPath(projectPath); + } + + @SuppressWarnings("unused") + public FormValidation doCheckService(@QueryParameter String service) { + return builderDescriptor.doCheckService(service); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExecution.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExecution.java new file mode 100644 index 0000000000..b1167429f7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExecution.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import javax.inject.Inject; + +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStep; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Run; +import hudson.model.TaskListener; +import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; +import org.jenkinsci.plugins.workflow.steps.StepContextParameter; + +public class SvExecution extends AbstractSynchronousNonBlockingStepExecution { + @SuppressWarnings("CdiInjectionPointsInspection") + @Inject + private transient AbstractSvStep step; + @StepContextParameter + private transient TaskListener listener; + @StepContextParameter + private transient FilePath ws; + @StepContextParameter + private transient Run build; + @StepContextParameter + private transient Launcher launcher; + + @Override + protected Void run() throws Exception { + step.getBuilder().perform(build, ws, launcher, listener); + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExportStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExportStep.java new file mode 100644 index 0000000000..bf235affa6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvExportStep.java @@ -0,0 +1,99 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.run.SvExportBuilder; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStep; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStepDescriptor; +import hudson.Extension; +import hudson.util.FormValidation; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvExportStep extends AbstractSvStep { + private final String targetDirectory; + private final boolean cleanTargetDirectory; + private final SvServiceSelectionModel serviceSelection; + private final boolean switchToStandByFirst; + private final boolean archive; + + @DataBoundConstructor + public SvExportStep(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, + SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst, boolean archive) { + super(serverName, force); + this.targetDirectory = targetDirectory; + this.cleanTargetDirectory = cleanTargetDirectory; + this.serviceSelection = serviceSelection; + this.switchToStandByFirst = switchToStandByFirst; + this.archive = archive; + } + + public String getTargetDirectory() { + return targetDirectory; + } + + public boolean isCleanTargetDirectory() { + return cleanTargetDirectory; + } + + public SvServiceSelectionModel getServiceSelection() { + return serviceSelection; + } + + public boolean isSwitchToStandByFirst() { + return switchToStandByFirst; + } + + public boolean isArchive() { + return archive; + } + + @Override + public SimpleBuildStep getBuilder() { + return new SvExportBuilder(serverName, force, targetDirectory, cleanTargetDirectory, serviceSelection, switchToStandByFirst, archive); + } + + @Extension + public static class DescriptorImpl extends AbstractSvStepDescriptor { + public DescriptorImpl() { + super(SvExecution.class, "svExportStep", new SvExportBuilder.DescriptorImpl()); + } + + @SuppressWarnings("unused") + public FormValidation doCheckTargetDirectory(@QueryParameter String targetDirectory) { + return builderDescriptor.doCheckTargetDirectory(targetDirectory); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvUndeployStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvUndeployStep.java new file mode 100644 index 0000000000..435630db1a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/SvUndeployStep.java @@ -0,0 +1,74 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.run.SvUndeployBuilder; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStep; +import com.microfocus.application.automation.tools.sv.pipeline.AbstractSvStepDescriptor; +import hudson.Extension; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.DataBoundConstructor; + +public class SvUndeployStep extends AbstractSvStep { + private final boolean continueIfNotDeployed; + private final SvServiceSelectionModel serviceSelection; + + @DataBoundConstructor + public SvUndeployStep(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { + super(serverName, force); + this.continueIfNotDeployed = continueIfNotDeployed; + this.serviceSelection = serviceSelection; + } + + @SuppressWarnings("unused") + public boolean isContinueIfNotDeployed() { + return continueIfNotDeployed; + } + + public SvServiceSelectionModel getServiceSelection() { + return serviceSelection; + } + + @Override + public SimpleBuildStep getBuilder() { + return new SvUndeployBuilder(serverName, continueIfNotDeployed, force, serviceSelection); + } + + @Extension + public static class DescriptorImpl extends AbstractSvStepDescriptor { + public DescriptorImpl() { + super(SvExecution.class, "svUndeployStep", new SvUndeployBuilder.DescriptorImpl()); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java new file mode 100644 index 0000000000..0757bf4be5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep.java @@ -0,0 +1,276 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.google.common.collect.ImmutableSet; +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; +import com.microfocus.application.automation.tools.model.RunFromFileSystemModel; +import com.microfocus.application.automation.tools.results.RunResultRecorder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.*; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.plugins.workflow.steps.*; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.util.*; + +/** + * UFT pipeline step + */ +public class UftScenarioLoadStep extends Step { + + private RunFromFileBuilder runFromFileBuilder; + private RunResultRecorder runResultRecorder; + + /** + * Instantiates a new UFT scenario load step. + * + * @param testPaths the test paths + * @param archiveTestResultsMode the type of archiving the user wants. + */ + @DataBoundConstructor + public UftScenarioLoadStep(String testPaths, String archiveTestResultsMode) { + this.runFromFileBuilder = new RunFromFileBuilder(testPaths); + this.runResultRecorder = new RunResultRecorder(archiveTestResultsMode); + } + + @Override + public StepExecution start(StepContext stepContext) throws Exception { + return new UftScenarioLoadStepExecution(stepContext, this); + } + + @DataBoundSetter + private void setRunFromFileBuilder(RunFromFileBuilder runFromFileBuilder){ + this.runFromFileBuilder = runFromFileBuilder; + } + + @DataBoundSetter + public void setRunResultRecorder(RunResultRecorder runResultRecorder){ + this.runResultRecorder = runResultRecorder; + } + /** + * Gets archive test result mode. + * + * @return the archive run test results mode + */ + public String getArchiveTestResultsMode() { + return runResultRecorder.getResultsPublisherModel().getArchiveTestResultsMode(); + } + + /** + * Gets fsTimeout + * + * @return fsTimeout value + */ + public String getFsTimeout() { + return runFromFileBuilder.getRunFromFileModel().getFsTimeout(); + } + + /** + * Sets fsTimeout value + * + * @param fsTimeout the fsTimeout value + */ + @DataBoundSetter + public void setFsTimeout(String fsTimeout) { + runFromFileBuilder.setFsTimeout(fsTimeout); + } + + @DataBoundSetter + public void setFsReportPath(String fsReportPath) { + runFromFileBuilder.setFsReportPath(fsReportPath); + } + + /** + * Gets fsUftRunMode + * + * @return fsUftRunMode value + */ + public String getFsUftRunMode() { + return runFromFileBuilder.getRunFromFileModel().getFsUftRunMode(); + } + + /** + * Sets fsUftRunMode value + * + * @param fsUftRunMode the fsUftRunMode value + */ + @DataBoundSetter + public void setFsUftRunMode(String fsUftRunMode) { + runFromFileBuilder.setFsUftRunMode(fsUftRunMode); + } + + /** + * Gets fsUftRunModes + * + * @return fsUftRunModes value + */ + public List getFsUftRunModes() { + return RunFromFileSystemModel.fsUftRunModes; + } + + /** + * Gets test paths. + * + * @return the test paths + */ + public String getTestPaths() { + return runFromFileBuilder.getRunFromFileModel().getFsTests(); + } + + /** + * Get the report path. + * @return the report path + */ + public String getFsReportPath() { + return runFromFileBuilder.getRunFromFileModel().getFsReportPath(); + } + + /** + * Gets run from file builder. + * + * @return the run from file builder + */ + public RunFromFileBuilder getRunFromFileBuilder() { + return runFromFileBuilder; + } + + /** + * Gets run result builder + * + * @return the run result builder + */ + public RunResultRecorder getRunResultRecorder() { + return runResultRecorder; + } + + /** + * The type Descriptor. + */ + @Extension + public static class DescriptorImpl extends StepDescriptor { + + @Override + public Set> getRequiredContext() { + return ImmutableSet.of(Run.class, TaskListener.class, FilePath.class); + } + + @Override + public String getFunctionName() { + return "uftScenarioLoad"; + } + + @Nonnull + @Override + public String getDisplayName() { + return "Run UFT scenario"; + } + + /** + * Gets fs runModes + * + * @return the fs runModes + */ + public List getFsUftRunModes() { return RunFromFileSystemModel.fsUftRunModes; } + + /** + * Gets report archive modes. + * + * @return the report archive modes + */ + public List getReportArchiveModes() { + + return ResultsPublisherModel.archiveModes; + } + + /** + * Do check test paths validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckTestPaths(@QueryParameter String value) { + + if (StringUtils.isBlank(value)) { + return FormValidation.error("Test path must be set"); + } + + return FormValidation.ok(); + } + + /** + * Do check fs tests form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckFsTests(@QueryParameter String value) { + + if (StringUtils.isBlank(value)) { + return FormValidation.error("Test path must be set"); + } + + return FormValidation.ok(); + } + + /** + * Do check fs timeout validation + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckFsTimeout(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + String val1 = value.trim(); + if (val1.length() > 0 && val1.charAt(0) == '-') { + val1 = val1.substring(1); + } + + if (!StringUtils.isNumeric(val1) && !Objects.equals(val1, "")) { + return FormValidation.error("Timeout name must be a number"); + } + + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java new file mode 100644 index 0000000000..8e8e13d409 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStepExecution.java @@ -0,0 +1,93 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import com.microfocus.application.automation.tools.run.UftOctaneUtils; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import org.jenkinsci.plugins.workflow.steps.StepContext; +import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution; + +import javax.annotation.Nonnull; +import java.util.HashMap; + + +/** + * The UFT pipeline step execution. + */ +public class UftScenarioLoadStepExecution extends SynchronousNonBlockingStepExecution { + + private static final long serialVersionUID = 1L; + + + private transient final UftScenarioLoadStep step; + + + private transient TaskListener listener; + + + private transient FilePath ws; + + + private transient Run build; + + + private transient Launcher launcher; + + protected UftScenarioLoadStepExecution(@Nonnull StepContext context, UftScenarioLoadStep step) { + super(context); + this.step = step; + } + + + @Override + protected Void run() throws Exception{ + ws = getContext().get(FilePath.class); + listener = getContext().get(TaskListener.class); + build = getContext().get(Run.class); + launcher = getContext().get(Launcher.class); + + listener.getLogger().println("Running UftScenarioLoadStepExecution"); + + step.getRunFromFileBuilder().perform(build, ws, launcher, listener); + + HashMap resultFilename = new HashMap(0); + resultFilename.put(RunFromFileBuilder.class.getName(), step.getRunFromFileBuilder().getRunResultsFileName()); + + step.getRunResultRecorder().pipelinePerform(build, ws, launcher, listener, resultFilename); + + return null; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/rest/RestClient.java b/src/main/java/com/microfocus/application/automation/tools/rest/RestClient.java new file mode 100644 index 0000000000..dda3ccd487 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/rest/RestClient.java @@ -0,0 +1,406 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.rest; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.HttpCookie; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import hudson.ProxyConfiguration; + +import com.microfocus.application.automation.tools.sse.sdk.HttpRequestDecorator; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class RestClient implements Client { + + private final String _serverUrl; + protected Map _cookies = new HashMap(); + private final String _restPrefix; + private final String _webuiPrefix; + private final String _username; + private final String XSRF_TOKEN_VALUE; + + private CookieManager cookieManager; + + /** + * Configure SSL context for the client. + */ + static { + // First create a trust manager that won't care. + X509TrustManager trustManager = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // Don't do anything. + } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // Don't do anything. + } + @Override + public X509Certificate[] getAcceptedIssuers() { + // Don't do anything. + return null; + } + + }; + // Now put the trust manager into an SSLContext. + SSLContext sslcontext; + try { + sslcontext = SSLContext.getInstance("SSL"); + sslcontext.init(null, new TrustManager[] { trustManager }, null); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + throw new SSEException(e); + } + + HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory()); + + //Ignore hostname verify + HttpsURLConnection.setDefaultHostnameVerifier( + new HostnameVerifier(){ + public boolean verify(String hostname, SSLSession sslSession) { + return true; + } + } + ); + } + + /** + * Constructor for setting rest client properties. + */ + public RestClient(String url, String domain, String project, String username) { + + if (!url.endsWith("/")) { + url = String.format("%s/", url); + } + _serverUrl = url; + _username = username; + _restPrefix = + getPrefixUrl( + "rest", + String.format("domains/%s", domain), + String.format("projects/%s", project)); + _webuiPrefix = getPrefixUrl("webui/alm", domain, project); + + XSRF_TOKEN_VALUE = UUID.randomUUID().toString(); + cookieManager = new CookieManager(); + CookieHandler.setDefault(cookieManager); + URI uri = null; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + // + } + HttpCookie cookie = new HttpCookie("XSRF-TOKEN", XSRF_TOKEN_VALUE); + cookie.setPath("/qcbin"); + cookieManager.getCookieStore().add(uri, cookie); + } + + public String getXsrfTokenValue() { + return XSRF_TOKEN_VALUE; + } + + /** + * Build + * @param suffix + * @return + */ + @Override + public String build(String suffix) { + return String.format("%1$s%2$s", _serverUrl, suffix); + } + + /** + * Build rest request + */ + @Override + public String buildRestRequest(String suffix) { + return String.format("%1$s/%2$s", _restPrefix, suffix); + } + + /** + * Build web ui request + */ + @Override + public String buildWebUIRequest(String suffix) { + return String.format("%1$s/%2$s", _webuiPrefix, suffix); + } + + /** + * Http get request + */ + @Override + public Response httpGet( + String url, + String queryString, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + Response ret = null; + try { + ret = doHttp(RESTConstants.GET, url, queryString, null, headers, resourceAccessLevel); + } catch (Exception cause) { + throw new SSEException(cause); + } + + return ret; + } + + /** + * Http post request + */ + @Override + public Response httpPost( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + Response ret = null; + try { + ret = doHttp(RESTConstants.POST, url, null, data, headers, resourceAccessLevel); + } catch (Exception cause) { + throw new SSEException(cause); + } + + return ret; + } + + /** + * Http put request + */ + @Override + public Response httpPut( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + Response ret = null; + try { + ret = doHttp(RESTConstants.PUT, url, null, data, headers, resourceAccessLevel); + } catch (Exception cause) { + throw new SSEException(cause); + } + + return ret; + } + + /** + * Get server url + */ + @Override + public String getServerUrl() { + return _serverUrl; + } + + /** + * Get prefix url + * @param protocol + * @param domain + * @param project + * @return + */ + private String getPrefixUrl(String protocol, String domain, String project) { + return String.format("%s%s/%s/%s", _serverUrl, protocol, domain, project); + } + + /** + * Do http request + */ + private Response doHttp( + String type, + String url, + String queryString, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + Response ret; + if ((queryString != null) && !queryString.isEmpty()) { + url += "?" + queryString; + } + try { + HttpURLConnection connection = (HttpURLConnection)ProxyConfiguration.open(new URL(url)); + connection.setRequestMethod(type); + + Map decoratedHeaders = new HashMap(); + if (headers != null) { + decoratedHeaders.putAll(headers); + } + + HttpRequestDecorator.decorateHeaderWithUserInfo( + decoratedHeaders, + getUsername(), + resourceAccessLevel); + + prepareHttpRequest(connection, decoratedHeaders, data); + connection.connect(); + ret = retrieveHtmlResponse(connection); + } catch (Exception cause) { + throw new SSEException(cause); + } + + return ret; + } + + /** + * Prepare http request + */ + private void prepareHttpRequest( + HttpURLConnection connnection, + Map headers, + byte[] bytes) { + setConnectionHeaders(connnection, headers); + setConnectionData(connnection, bytes); + } + + /** + * Set connection data + */ + private void setConnectionData(HttpURLConnection connnection, byte[] bytes) { + + if (bytes != null && bytes.length > 0) { + connnection.setDoOutput(true); + try { + OutputStream out = connnection.getOutputStream(); + out.write(bytes); + out.flush(); + out.close(); + } catch (Exception cause) { + throw new SSEException(cause); + } + } + } + + /** + * Set connection headers + */ + private void setConnectionHeaders(HttpURLConnection connnection, Map headers) { + + if (headers != null) { + Iterator> headersIterator = headers.entrySet().iterator(); + while (headersIterator.hasNext()) { + Entry header = headersIterator.next(); + connnection.setRequestProperty(header.getKey(), header.getValue()); + } + } + } + + /** + * Retrieve Html Response + * @param connection + * that is already connected to its url with an http request, and that should contain + * a response for us to retrieve + * @return a response from the server to the previously submitted http request + */ + private Response retrieveHtmlResponse(HttpURLConnection connection) { + + Response ret = new Response(); + + try { + ret.setStatusCode(connection.getResponseCode()); + ret.setHeaders(connection.getHeaderFields()); + } catch (Exception cause) { + throw new SSEException(cause); + } + + InputStream inputStream; + // select the source of the input bytes, first try 'regular' input + try { + inputStream = connection.getInputStream(); + } + // if the connection to the server somehow failed, for example 404 or 500, + // con.getInputStream() will throw an exception, which we'll keep. + // we'll also store the body of the exception page, in the response data. */ + catch (Exception e) { + inputStream = connection.getErrorStream(); + ret.setFailure(e); + } + + // this takes data from the previously set stream (error or input) + // and stores it in a byte[] inside the response + ByteArrayOutputStream container = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int read; + try { + while ((read = inputStream.read(buf, 0, 1024)) > 0) { + container.write(buf, 0, read); + } + ret.setData(container.toByteArray()); + } catch (Exception ex) { + throw new SSEException(ex); + } + + return ret; + } + + @Override + public String getUsername() { + return _username; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/DetailReport.java b/src/main/java/com/microfocus/application/automation/tools/results/DetailReport.java new file mode 100644 index 0000000000..ff62820223 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/DetailReport.java @@ -0,0 +1,117 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.model.DirectoryBrowserSupport; +import hudson.model.ModelObject; +import hudson.model.Run; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import javax.servlet.ServletException; +import java.io.IOException; + +public class DetailReport implements ModelObject { + + private String name = ""; + private String color = ""; + private String duration = ""; + private String pass = ""; + private String fail = ""; + private Run build = null; + private DirectoryBrowserSupport _directoryBrowserSupport = null; + + public DetailReport(Run build, String name, DirectoryBrowserSupport directoryBrowserSupport) { + this.build = build; + this.name = name; + _directoryBrowserSupport = directoryBrowserSupport; + } + + @Override + public String getDisplayName() { + return name; + } + + @SuppressWarnings("squid:S1452") + public Run getBuild() { + return build; + } + + public String getName() { + return name; + } + + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + + if (_directoryBrowserSupport != null) + _directoryBrowserSupport.generateResponse(req, rsp, this); + } + + public String getColor() { + return color; + } + + public void setColor(String value) { + color = value; + } + + public String getDuration() { + return duration; + } + + public void setDuration(String value) { + duration = value; + } + + public String getPass() { + return pass; + } + + public void setPass(String value) { + pass = value; + } + + public String getFail() { + return fail; + } + + public void setFail(String value) { + fail = value; + } + + public void updateReport(String duration, String pass, String fail) { + setDuration(duration); + setPass(pass); + setFail(fail); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/HtmlBuildReportAction.java b/src/main/java/com/microfocus/application/automation/tools/results/HtmlBuildReportAction.java new file mode 100644 index 0000000000..82594d9060 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/HtmlBuildReportAction.java @@ -0,0 +1,151 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.model.Action; +import hudson.model.Run; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import java.util.List; + + +/** + * Created by betzalel on 28/06/2015. + */ +public class HtmlBuildReportAction implements Action { + private Run build; + private List reportMetaDataList; + private Integer index; + + //NOTE: if parameter has BuildListener, the build cannot be serialize normally. + public HtmlBuildReportAction(Run build, String reportName, Integer index) throws IOException, SAXException, ParserConfigurationException { + this.build = build; + + File reportMetaData_XML = new File(build.getRootDir(), reportName); + if (reportMetaData_XML.exists()) { + this.reportMetaDataList = readReportFromXMLFile(reportMetaData_XML.getAbsolutePath()); + } + this.index = index; + } + + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + protected File reportFile() { + return getBuildHtmlReport(this.build); + } + + private File getBuildHtmlReport(Run run) { + return new File(new File(new File(run.getRootDir(),"archive"), "UFTReport"), "index.html"); + } + + @Override + public String getDisplayName() { + return "UFT Report"; + } + + @Override + public String getUrlName() { + return "uft-report" + (this.index != null ? "-" + this.index : ""); + } + + @Override + public String getIconFileName() { + return "/plugin/hp-application-automation-tools-plugin/icons/24x24/uft_report.png"; + } + + // other property of the report + public List getAllReports() { + return reportMetaDataList; + } + + public List getReportMetaDataList(){ + return this.reportMetaDataList; + } + + + private List readReportFromXMLFile(String filename) throws ParserConfigurationException, IOException, SAXException { + List listReport = new ArrayList<>(); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(filename); + + Element root = doc.getDocumentElement(); + NodeList reportList = root.getElementsByTagName("report"); + for (int i = 0; i < reportList.getLength(); i++) { + ReportMetaData reportmetadata = new ReportMetaData(); + Node nNode = reportList.item(i); + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + Element report = (Element) nNode; + String disPlayName = report.getAttribute("disPlayName"); + String urlName = report.getAttribute("urlName"); + String resourceURL = report.getAttribute("resourceURL"); + String dateTime = report.getAttribute("dateTime"); + String status = report.getAttribute("status"); + String isHtmlreport = report.getAttribute("isHtmlreport"); + String isParallelRunnerReport = report.getAttribute("isParallelRunnerReport"); + String archiveUrl = report.getAttribute("archiveUrl"); + + reportmetadata.setDisPlayName(disPlayName); + reportmetadata.setUrlName(urlName); + reportmetadata.setResourceURL(resourceURL); + reportmetadata.setDateTime(dateTime); + reportmetadata.setStatus(status); + reportmetadata.setIsHtmlReport("true".equals(isHtmlreport)); + reportmetadata.setIsParallelRunnerReport("true".equals(isParallelRunnerReport)); + reportmetadata.setArchiveUrl(archiveUrl); + listReport.add(reportmetadata); + } + } + + return listReport; + } + + + +} diff --git a/src/main/java/com/hp/application/automation/tools/results/LrGraphUtils.java b/src/main/java/com/microfocus/application/automation/tools/results/LrGraphUtils.java similarity index 90% rename from src/main/java/com/hp/application/automation/tools/results/LrGraphUtils.java rename to src/main/java/com/microfocus/application/automation/tools/results/LrGraphUtils.java index cf518c4d10..5b1d2051be 100644 --- a/src/main/java/com/hp/application/automation/tools/results/LrGraphUtils.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/LrGraphUtils.java @@ -1,34 +1,42 @@ /* + * 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 (c) 2016 Hewlett-Packard Development Company, L.P. + * Copyright 2012-2023 Open Text * - * 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 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. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * 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. * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.results; +package com.microfocus.application.automation.tools.results; -import com.hp.application.automation.tools.results.projectparser.performance.AvgTransactionResponseTime; -import com.hp.application.automation.tools.results.projectparser.performance.LrProjectScenarioResults; -import com.hp.application.automation.tools.results.projectparser.performance.PercentileTransactionWholeRun; -import com.hp.application.automation.tools.results.projectparser.performance.TimeRangeResult; -import com.hp.application.automation.tools.results.projectparser.performance.WholeRunResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.AvgTransactionResponseTime; +import com.microfocus.application.automation.tools.results.projectparser.performance.LrProjectScenarioResults; +import com.microfocus.application.automation.tools.results.projectparser.performance.PercentileTransactionWholeRun; +import com.microfocus.application.automation.tools.results.projectparser.performance.TimeRangeResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.WholeRunResult; import net.sf.json.JSONArray; import net.sf.json.JSONObject; @@ -36,7 +44,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.Queue; import java.util.SortedMap; import java.util.TreeMap; @@ -168,7 +175,7 @@ static void constructAvgTransactionGraph(Map.Entry build; + private JSONObject jobDataSet; + private LrJobResults _resultFiles; + + /** + * Instantiates a new Performance job report action. + * + * @param build the build + * @param resultFiles the result dataset + */ + public PerformanceJobReportAction(Run build, LrJobResults resultFiles) { + this.build = build; + this._resultFiles = resultFiles; + } + + /** + * Merge results of several runs - especially useful in pipeline jobs with multiple LR steps + * + * @param resultFiles the result files + */ + public void mergeResults(LrJobResults resultFiles) + { + for(JobLrScenarioResult scenarioResult : resultFiles.getLrScenarioResults().values()) + { + this._resultFiles.addScenario(scenarioResult); + } + } + + /** + * Gets lr result build dataset. + * + * @return the lr result build dataset + */ + public LrJobResults getLrResultBuildDataset() { + return _resultFiles; + } + + /** + * Gets json data. + * + * @return the json data + */ + public JSONObject getJsonData() + { + return jobDataSet; + } + + + @Override + public Collection getProjectActions() { + List projectActions = new ArrayList(); + projectActions.add(new PerformanceProjectAction(build.getParent())); + return projectActions; + } +} diff --git a/src/main/java/com/hp/application/automation/tools/results/PerformanceProjectAction.java b/src/main/java/com/microfocus/application/automation/tools/results/PerformanceProjectAction.java similarity index 84% rename from src/main/java/com/hp/application/automation/tools/results/PerformanceProjectAction.java rename to src/main/java/com/microfocus/application/automation/tools/results/PerformanceProjectAction.java index 295ecea482..f031a9b926 100644 --- a/src/main/java/com/hp/application/automation/tools/results/PerformanceProjectAction.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/PerformanceProjectAction.java @@ -1,39 +1,47 @@ /* + * 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 (c) 2016 Hewlett-Packard Development Company, L.P. + * Copyright 2012-2023 Open Text * - * 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 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. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * 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. * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.results; - -import com.hp.application.automation.tools.results.projectparser.performance.AvgTransactionResponseTime; -import com.hp.application.automation.tools.results.projectparser.performance.GoalResult; -import com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; -import com.hp.application.automation.tools.results.projectparser.performance.LrJobResults; -import com.hp.application.automation.tools.results.projectparser.performance.LrProjectScenarioResults; -import com.hp.application.automation.tools.results.projectparser.performance.LrTest; -import com.hp.application.automation.tools.results.projectparser.performance.PercentileTransactionWholeRun; -import com.hp.application.automation.tools.results.projectparser.performance.ProjectLrResults; -import com.hp.application.automation.tools.results.projectparser.performance.TimeRangeResult; -import com.hp.application.automation.tools.results.projectparser.performance.WholeRunResult; +package com.microfocus.application.automation.tools.results; + +import com.microfocus.application.automation.tools.results.projectparser.performance.AvgTransactionResponseTime; +import com.microfocus.application.automation.tools.results.projectparser.performance.GoalResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.LrJobResults; +import com.microfocus.application.automation.tools.results.projectparser.performance.LrProjectScenarioResults; +import com.microfocus.application.automation.tools.results.projectparser.performance.LrTest; +import com.microfocus.application.automation.tools.results.projectparser.performance.PercentileTransactionWholeRun; +import com.microfocus.application.automation.tools.results.projectparser.performance.ProjectLrResults; +import com.microfocus.application.automation.tools.results.projectparser.performance.TimeRangeResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.WholeRunResult; import hudson.model.Action; import hudson.model.Job; import hudson.model.Run; @@ -50,9 +58,9 @@ import java.util.TreeMap; import java.util.logging.Logger; -import static com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult +import static com.microfocus.application.automation.tools.results.projectparser.performance.JobLrScenarioResult .DEFAULT_CONNECTION_MAX; -import static com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult +import static com.microfocus.application.automation.tools.results.projectparser.performance.JobLrScenarioResult .DEFAULT_SCENARIO_DURATION; /** diff --git a/src/main/java/com/microfocus/application/automation/tools/results/PerformanceReportAction.java b/src/main/java/com/microfocus/application/automation/tools/results/PerformanceReportAction.java new file mode 100644 index 0000000000..049d1b207e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/PerformanceReportAction.java @@ -0,0 +1,156 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.FilePath; +import hudson.model.Action; +import hudson.model.DirectoryBrowserSupport; +import hudson.model.Run; +import hudson.tasks.test.TestResultProjectAction; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + + +public class PerformanceReportAction implements Action, SimpleBuildStep.LastBuildAction { + + private static final String PERFORMANCE_REPORT_FOLDER = "PerformanceReport"; + private static final String REPORT_INDEX = "report.index"; + + private Map detailReportMap = new LinkedHashMap(); + private final List projectActionList; + + + private final Run build; + + public PerformanceReportAction(Run build) throws IOException { + this.build = build; + File reportFolder = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); + if (reportFolder.exists()) { + File indexFile = new File(reportFolder, REPORT_INDEX); + if (indexFile.exists()) { + File file = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); + DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, new FilePath(file), "report", "graph.gif", false); + + + createPreformanceIndexFile(build, indexFile, dbs); + } + } + projectActionList = new ArrayList(); + } + + private void createPreformanceIndexFile(Run build, File indexFile, DirectoryBrowserSupport dbs) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(indexFile)); + String line; + boolean rolling = true; + while ((line = br.readLine()) != null) { + String[] values = line.split("\t"); + if (values.length < 1) + continue; + DetailReport report = new DetailReport(build, values[0], dbs); + if (rolling) { + report.setColor("#FFF"); + rolling = false; + } else { + report.setColor("#F1F1F1"); + rolling = true; + } + if (values.length >= 2) + report.setDuration(values[1]); + else + report.setDuration("##"); + if (values.length >= 3) + report.setPass(values[2]); + else + report.setPass("##"); + if (values.length >= 4) + report.setFail(values[3]); + else + report.setFail("##"); + detailReportMap.put(values[0], report); + } + br.close(); + } + + @Override + public String getIconFileName() { + return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/LoadRunner.png"; + } + + @Override + public String getDisplayName() { + return "Performance Report"; + } + + @Override + public String getUrlName() { + return "PerformanceReport"; + } + + @SuppressWarnings("squid:S1452") + public Run getBuild() { + return build; + } + + public Map getDetailReportMap() { + return detailReportMap; + } + + + public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { + if (detailReportMap.containsKey(name)) + return detailReportMap.get(name); + return null; + } + + @Override + public Collection getProjectActions() { +// List projectActions = new ArrayList<>(); +// projectActions.add(new PerformanceProjectAction(build.getParent())); +// projectActions.add(new TestResultProjectAction(build.getParent())); +// return projectActions; + return Collections.emptySet(); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/ReportMetaData.java b/src/main/java/com/microfocus/application/automation/tools/results/ReportMetaData.java new file mode 100644 index 0000000000..eb0e8931d5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/ReportMetaData.java @@ -0,0 +1,187 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import com.microfocus.application.automation.tools.commonResultUpload.xmlreader.XpathReader; +import com.microfocus.application.automation.tools.settings.RunnerMiscSettingsGlobalConfiguration; +import hudson.FilePath; +import hudson.model.TaskListener; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import java.io.IOException; +import java.time.DateTimeException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashSet; +import java.util.Set; + +import static com.microfocus.application.automation.tools.settings.RunnerMiscSettingsGlobalConfiguration.*; + +public class ReportMetaData { + + private String folderPath; //slave path of report folder(only for html report format) + private String disPlayName; + private String urlName; + private String resourceURL; + private String dateTime; + private String status; + private Boolean isHtmlReport; + private Boolean isParallelRunnerReport; + private String archiveUrl; + private final Set stResFolders = new HashSet<>(); + private static final String RUN_API_TEST_XPATH_EXPRESSION = "//Data[Name='RunAPITest']/Extension/StepCustomData"; + private static final String FAILED_TO_PROCESS_XML_REPORT = "Failed to process run_results.xml report: "; + private static final String ST_RES = "..\\StRes"; + public String getFolderPath() { + return folderPath; + } + + public void setFolderPath(String folderPath) { + this.folderPath = folderPath; + } + + public String getDisPlayName() { + return disPlayName; + } + + public void setDisPlayName(String disPlayName) { + this.disPlayName = disPlayName; + } + + public String getUrlName() { + return urlName; + } + + public void setUrlName(String urlName) { + this.urlName = urlName; + } + + public String getResourceURL() { + return resourceURL; + } + + public void setResourceURL(String resourceURL) { + this.resourceURL = resourceURL; + } + + private static LocalDateTime tryParseDate(String date) { + for (String pattern : DEFAULT_UFT_DATE_PATTERNS) { + try { + return LocalDateTime.parse(date, DateTimeFormatter.ofPattern(pattern)); + } catch (DateTimeException | IllegalArgumentException ignored) { + // ignoring, trying to find appropriate date pattern for date string + } + } + + return null; + } + + public String getDateTime() { + return dateTime; + } + + public String getFormattedDateTime() { + // there is a global configuration option to set the date format for RunResults, we format the received date at the last second + // because this way we can keep the default UFT formatting, nonetheless how users specify their own format + LocalDateTime dt = tryParseDate(dateTime); + if (dt == null) return dateTime; + + try { + return dt.format(RunnerMiscSettingsGlobalConfiguration.getInstance().getDateFormatter()); + } catch (NullPointerException ignored) { + return dateTime; + } + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Boolean getIsHtmlReport() { + return isHtmlReport; + } + + public void setIsHtmlReport(Boolean isHtmlReport) { + this.isHtmlReport = isHtmlReport; + } + + public Boolean getIsParallelRunnerReport() { + return isParallelRunnerReport; + } + + public void setIsParallelRunnerReport(Boolean parallelRunnerReport) { isParallelRunnerReport = parallelRunnerReport; } + + public String getArchiveUrl() { + return archiveUrl; + } + + public void setArchiveUrl(String archiveUrl) { + this.archiveUrl = archiveUrl; + } + + public boolean hasArchiveUrl() { + return archiveUrl != null && !archiveUrl.equals(""); + } + + public Set getStResFolders() { + return stResFolders; + } + + public void computeStResFolders(FilePath xmlReport, TaskListener listener) throws InterruptedException { + try { + if (xmlReport.exists()) { + XpathReader xr = new XpathReader(xmlReport); + NodeList nodes = xr.getNodeListFromNode(RUN_API_TEST_XPATH_EXPRESSION, xr.getDoc()); + for (int x = 0; x < nodes.getLength(); x++) { + String val = nodes.item(x).getTextContent(); + if (val.startsWith(ST_RES)) { + stResFolders.add(val.substring(3)); + } + } + } + } catch(NullPointerException | XPathExpressionException | IOException | SAXException | ParserConfigurationException e) { + listener.error(FAILED_TO_PROCESS_XML_REPORT + e); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/RichReportAction.java b/src/main/java/com/microfocus/application/automation/tools/results/RichReportAction.java new file mode 100644 index 0000000000..aed3ff586a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/RichReportAction.java @@ -0,0 +1,155 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.FilePath; +import hudson.model.Action; +import hudson.model.DirectoryBrowserSupport; +import hudson.model.Run; +import hudson.tasks.test.TestResultProjectAction; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + + +public class RichReportAction implements Action, SimpleBuildStep.LastBuildAction { + + private static final String RICH_REPORT_FOLDER = "RichReport"; + private static final String REPORT_INDEX = "report.index"; + + private Map richReportMap = new LinkedHashMap(); + private final List projectActionList; + + + private final Run build; + + public RichReportAction(Run build) throws IOException { + this.build = build; + File reportFolder = new File(build.getRootDir(), RICH_REPORT_FOLDER); + if (reportFolder.exists()) { + File indexFile = new File(reportFolder, REPORT_INDEX); + if (indexFile.exists()) { + File file = new File(build.getRootDir(), RICH_REPORT_FOLDER); + DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, new FilePath(file), "report", "graph.gif", false); + + + createRichIndexFile(build, indexFile, dbs); + } + } + projectActionList = new ArrayList(); + } + + /** + * Reads data from report.index and displays a table with: + * scenario name, duration, transactions passed and failed + */ + private void createRichIndexFile(Run build, File indexFile, DirectoryBrowserSupport dbs) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(indexFile)); + String line; + boolean rolling = true; + while ((line = br.readLine()) != null) { + String[] values = line.split("\t"); + if (values.length < 1) + continue; + DetailReport report = new DetailReport(build, values[0], dbs); + if (rolling) { + report.setColor("#FFF"); + rolling = false; + } else { + report.setColor("#F1F1F1"); + rolling = true; + } + //Set detailed report information + switch (values.length) { + case 4: + report.updateReport(values[1], values[2], values[3]); + break; + case 3: + report.updateReport(values[1], values[2], "##"); + break; + case 2: + report.updateReport(values[1], "##", "##"); + } + richReportMap.put(values[0], report); + } + br.close(); + } + + @Override + public String getIconFileName() { + return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/LoadRunner.png"; + } + + @Override + public String getDisplayName() { + return "Rich Report"; + } + + @Override + public String getUrlName() { + return "RichReport"; + } + + @SuppressWarnings("squid:S1452") + public Run getBuild() { + return build; + } + + public Map getRichReportMap() { + return richReportMap; + } + + + public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { + if (richReportMap.containsKey(name)) + return richReportMap.get(name); + return null; + } + + @Override + public Collection getProjectActions() { + return Collections.emptySet(); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/RunResultRecorder.java b/src/main/java/com/microfocus/application/automation/tools/results/RunResultRecorder.java new file mode 100644 index 0000000000..a96592c5a9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/RunResultRecorder.java @@ -0,0 +1,1640 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import com.microfocus.application.automation.tools.JenkinsUtils; +import com.microfocus.application.automation.tools.common.RuntimeUtils; +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; +import com.microfocus.application.automation.tools.results.projectparser.performance.*; +import com.microfocus.application.automation.tools.run.PcBuilder; +import com.microfocus.application.automation.tools.run.RunFromAlmBuilder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import com.microfocus.application.automation.tools.run.SseBuilder; +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.matrix.MatrixAggregatable; +import hudson.matrix.MatrixAggregator; +import hudson.matrix.MatrixBuild; +import hudson.model.*; +import hudson.remoting.VirtualChannel; +import hudson.tasks.*; +import hudson.tasks.junit.*; +import hudson.tasks.test.TestResultAggregator; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.filefilter.AgeFileFilter; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.kohsuke.stapler.DataBoundConstructor; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.annotation.Nonnull; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.*; +import java.util.*; + +import static com.microfocus.application.automation.tools.results.projectparser.performance.XmlParserUtil.getNode; +import static com.microfocus.application.automation.tools.results.projectparser.performance.XmlParserUtil.getNodeAttr; + +/** + * using {@link JUnitResultArchiver}; + * + * @author Thomas Maurel + */ +public class RunResultRecorder extends Recorder implements Serializable, MatrixAggregatable, SimpleBuildStep { + + public static final String REPORT_NAME_FIELD = "report"; + public static final int SECS_IN_DAY = 86400; + public static final int SECS_IN_HOUR = 3600; + public static final int SECS_IN_MINUTE = 60; + public static final String SLA_ULL_NAME = "FullName"; + public static final String ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR = + "Archiving test reports failed due to xml parsing error: "; + private static final long serialVersionUID = 1L; + private static final String PERFORMANCE_REPORT_FOLDER = "PerformanceReport"; + private static final String IE_REPORT_FOLDER = "IE"; + private static final String HTML_REPORT_FOLDER = "HTML"; + private static final String LRA_FOLDER = "LRA"; + private static final String INDEX_HTML_NAME = "index.html"; + private static final String REPORT_INDEX_NAME = "report.index"; + private static final String TRANSACTION_SUMMARY_FOLDER = "TransactionSummary"; + private static final String RICH_REPORT_FOLDER = "RichReport"; + private static final String TRANSACTION_REPORT_NAME = "TransactionReport"; + private static final String SLA_ACTUAL_VALUE_LABEL = "ActualValue"; + private static final String SLA_GOAL_VALUE_LABEL = "GoalValue"; + private static final String NO_RICH_REPORTS_ERROR = "Template contains no rich reports."; + private static final String NO_TRANSACTION_SUMMARY_REPORT_ERROR = "Template contains no transaction summary " + + "report."; + private static final String PARALLEL_RESULT_FILE = "parallelrun_results.html"; + private static final String REPORT_ARCHIVE_SUFFIX = "_Report.zip"; + private static final String RUN_RESULTS_XML = "run_results.xml"; + private static final String RESULT = "Result"; + + private final ResultsPublisherModel _resultsPublisherModel; + private List runReportList; + + + /** + * Instantiates a new Run result recorder. + * + * @param archiveTestResultsMode the archive test results mode + */ + @DataBoundConstructor + public RunResultRecorder(String archiveTestResultsMode) { + + _resultsPublisherModel = new ResultsPublisherModel(archiveTestResultsMode); + + } + + private static void addTimeRanges(TimeRangeResult transactionTimeRange, Element slaRuleElement) { + Node timeRangeNode; + Element timeRangeElement; + NodeList timeRanges = slaRuleElement.getElementsByTagName("TimeRangeInfo"); + if (timeRanges == null || timeRanges.getLength() == 0) { + return; + } + // Taking the goal per transaction - + double generalGoalValue = Double.parseDouble(((Element) timeRanges.item(0)).getAttribute(SLA_GOAL_VALUE_LABEL)); + transactionTimeRange.setGoalValue(generalGoalValue); + + for (int k = 0; k < timeRanges.getLength(); k++) { + timeRangeNode = timeRanges.item(k); + timeRangeElement = (Element) timeRangeNode; + double actualValue = Double.parseDouble(timeRangeElement.getAttribute(SLA_ACTUAL_VALUE_LABEL)); + double goalValue = Double.parseDouble(timeRangeElement.getAttribute(SLA_GOAL_VALUE_LABEL)); + int loadValue = Integer.parseInt(timeRangeElement.getAttribute("LoadValue")); + double startTime = Double.parseDouble(timeRangeElement.getAttribute("StartTime")); + double endTIme = Double.parseDouble(timeRangeElement.getAttribute("EndTime")); + transactionTimeRange.incActualValue(actualValue); + LrTest.SLA_STATUS slaStatus = LrTest.SLA_STATUS + .checkStatus(timeRangeElement.getFirstChild().getTextContent()); + TimeRange timeRange = new TimeRange(actualValue, goalValue, slaStatus, loadValue, startTime, endTIme); + transactionTimeRange.getTimeRanges().add(timeRange); + } + } + + @Override + public DescriptorImpl getDescriptor() { + + return (DescriptorImpl) super.getDescriptor(); + } + + /** + * Pipeline perform. + * + * @param build the build + * @param workspace the workspace + * @param launcher the launcher + * @param listener the listener + * @param builderResultNames the builder result names + * @throws IOException the io exception + * @throws InterruptedException the interrupted exception + */ + // temporary solution to deal with lack of support in builder list when Project + // is replaced by job type in pipeline. + // Should be dealt with general refactoring - making this a job property or + // change folder structure to scan instead + // of passing file name from builder. + @SuppressWarnings("squid:S1160") + public void pipelinePerform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener, @Nonnull Map builderResultNames) + throws IOException, InterruptedException { + final List mergedResultNames = new ArrayList(); + runReportList = new ArrayList(); + final List fileSystemResultNames = new ArrayList(); + fileSystemResultNames.add(builderResultNames.get(RunFromFileBuilder.class.getName())); + + mergedResultNames.addAll(builderResultNames.values()); + + if (mergedResultNames.isEmpty()) { + listener.getLogger().println("RunResultRecorder: no results xml File provided"); + return; + } + + recordRunResults(build, workspace, launcher, listener, mergedResultNames, fileSystemResultNames); + return; + } + + /** + * Records LR test results copied in JUnit format + * + * @param build + * @param workspace + * @param launcher + * @param listener + * @param mergedResultNames + * @param fileSystemResultNames + * @throws InterruptedException + * @throws IOException + */ + private void recordRunResults(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener, List mergedResultNames, List fileSystemResultNames) + throws InterruptedException, IOException { + + for (String resultFile : mergedResultNames) { + JUnitResultArchiver jUnitResultArchiver = new JUnitResultArchiver(resultFile); + jUnitResultArchiver.setKeepLongStdio(true); + jUnitResultArchiver.setAllowEmptyResults(true); + jUnitResultArchiver.setSkipMarkingBuildUnstable(true); + jUnitResultArchiver.perform(build, workspace, launcher, listener); + } + + final TestResultAction tempAction = build.getAction(TestResultAction.class); + + if (tempAction == null || tempAction.getResult() == null) { + listener.getLogger().println("RunResultRecorder: didn't find any test results to record"); + return; + } + + TestResult result = tempAction.getResult(); + + try { + archiveTestsReport(build, listener, fileSystemResultNames, result, workspace); + } catch (ParserConfigurationException | SAXException e) { + listener.error(ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR + e); + } + + if ((runReportList != null) && !(runReportList.isEmpty())) { + LrJobResults jobDataSet = null; + try { + jobDataSet = buildJobDataset(listener); + } catch (ParserConfigurationException | SAXException e) { + listener.error(ARCHIVING_TEST_REPORTS_FAILED_DUE_TO_XML_PARSING_ERROR + e); + } + + if ((jobDataSet != null && !jobDataSet.getLrScenarioResults().isEmpty())) { + PerformanceJobReportAction performanceJobReportAction = build + .getAction(PerformanceJobReportAction.class); + if (performanceJobReportAction != null) { + performanceJobReportAction.mergeResults(jobDataSet); + } else { + performanceJobReportAction = new PerformanceJobReportAction(build, jobDataSet); + } + build.replaceAction(performanceJobReportAction); + } + } + publishLrReports(build); + } + + /** + * Adds the html reports actions to the left side menu. + * + * @param build + */ + private void publishLrReports(@Nonnull Run build) throws IOException { + File reportDirectory = new File(build.getRootDir(), PERFORMANCE_REPORT_FOLDER); + if (reportDirectory.exists()) { + File htmlIndexFile = new File(reportDirectory, INDEX_HTML_NAME); + if (htmlIndexFile.exists()) { + build.replaceAction(new PerformanceReportAction(build)); + } + } + + File summaryDirectory = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); + if (summaryDirectory.exists()) { + File htmlIndexFile = new File(summaryDirectory, INDEX_HTML_NAME); + if (htmlIndexFile.exists()) { + build.replaceAction(new TransactionSummaryAction(build)); + } + } + + File richDirectory = new File(build.getRootDir(), RICH_REPORT_FOLDER); + if (richDirectory.exists()) { + File htmlIndexFile = new File(richDirectory, INDEX_HTML_NAME); + if (htmlIndexFile.exists()) { + build.replaceAction(new RichReportAction(build)); + } + } + } + + /** + * checks if the given report path is a parallel runner report + * + * @param reportPath the path containing the report files + * @throws IOException + * @throws InterruptedException + */ + private boolean isParallelRunnerReportPath(FilePath reportPath) throws IOException, InterruptedException { + FilePath parallelRunnerResultsFile = new FilePath(reportPath, PARALLEL_RESULT_FILE); + return parallelRunnerResultsFile.exists(); + } + + /** + * copies, archives and creates the Test reports of LR and UFT runs. + * + * @param build + * @param listener + * @param resultFiles + * @param testResult + * @param runWorkspace + * @throws ParserConfigurationException + * @throws SAXException + * @throws IOException + * @throws InterruptedException + */ + @SuppressWarnings({ "squid:S134", "squid:S135" }) + private void archiveTestsReport(Run build, TaskListener listener, List resultFiles, + TestResult testResult, FilePath runWorkspace) + throws ParserConfigurationException, SAXException, IOException, InterruptedException { + + if ((resultFiles == null) || (resultFiles.isEmpty())) { return; } + + ArrayList zipFileNames = new ArrayList(); + ArrayList reportFolders = new ArrayList(); + List reportNames = new ArrayList(); + + listener.getLogger() + .println("Report archiving mode is set to: " + _resultsPublisherModel.getArchiveTestResultsMode()); + + // if user specified not to archive report + if (_resultsPublisherModel.getArchiveTestResultsMode() + .equals(ResultsPublisherModel.dontArchiveResults.getValue())) + return; + + FilePath projectWS = runWorkspace; + + // get the artifacts directory where we will upload the zipped report + // folder + File artifactsDir = new File(build.getRootDir(), "archive"); + artifactsDir.mkdirs(); + + // read each result.xml + /* + * The structure of the result file is: + * + * + * + * + */ + + // add previous report names for aggregation when using pipelines. + PerformanceJobReportAction performanceJobReportAction = build.getAction(PerformanceJobReportAction.class); + if (performanceJobReportAction != null) { + reportNames.addAll(performanceJobReportAction.getLrResultBuildDataset().getLrScenarioResults().keySet()); + } + EnvVars env = build.getEnvironment(listener); + hudson.model.Node node = Jenkins.get().getNode(env.get("NODE_NAME")); + VirtualChannel channel; + String nodeName = ""; + if (node != null) { + channel = node.getChannel(); + nodeName = node.getNodeName(); + } else { + channel = projectWS.getChannel(); + try { + node = JenkinsUtils.getCurrentNode(runWorkspace); + nodeName = node != null ? node.getNodeName() : ""; + listener.getLogger().println("Node name = " + nodeName); + } catch (Exception e) { + listener.getLogger().println("Failed to get the current Node: " + e.getMessage()); + } + } + for (String resultsFilePath : resultFiles) { + FilePath resultsFile = projectWS.child(resultsFilePath); + List ReportInfoToCollect = new ArrayList(); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + + Document doc = dBuilder.parse(resultsFile.read()); + doc.getDocumentElement().normalize(); + + Node testSuiteNode = doc.getElementsByTagName("testsuite").item(0); + Element testSuiteElement = (Element) testSuiteNode; + if (testSuiteElement.hasAttribute("name") && testSuiteElement.getAttribute("name").endsWith(".lrs")) { // LR + // test + NodeList testSuiteNodes = doc.getElementsByTagName("testsuite"); + for (int i = 0; i < testSuiteNodes.getLength(); i++) { + testSuiteNode = testSuiteNodes.item(i); + testSuiteElement = (Element) testSuiteNode; + if (!testSuiteElement.hasAttribute("name")) { + continue; + } + String testFolderPath = testSuiteElement.getAttribute("name"); + int testPathArr = testFolderPath.lastIndexOf('\\'); + String testName = testFolderPath.substring(testPathArr + 1); + reportNames.add(testName); + String testStatus = ("0".equals(testSuiteElement.getAttribute("failures"))) ? "pass" : "fail"; + + Node testCaseNode = testSuiteElement.getElementsByTagName("testcase").item(0); + if (testCaseNode == null) { + listener.getLogger().println("No report folder was found in results"); + return; + } + if (testCaseNode.getNodeType() == Node.ELEMENT_NODE) { + + Element testCaseElement = (Element) testCaseNode; + + if (!testCaseElement.hasAttribute(REPORT_NAME_FIELD)) { + continue; + } + + String reportFolderPath = testCaseElement.getAttribute(REPORT_NAME_FIELD); + + FilePath reportFolder = new FilePath(projectWS.getChannel(), reportFolderPath); + reportFolders.add(reportFolder); + + FilePath testFolder = new FilePath(projectWS.getChannel(), testFolderPath); + String zipFileName = getUniqueZipFileNameInFolder(zipFileNames, testFolder.getName(), "LR"); + FilePath archivedFile = new FilePath(new FilePath(artifactsDir), zipFileName); + + if (archiveFolder(reportFolder, testStatus, archivedFile, listener)) { + zipFileNames.add(zipFileName); + } + + createRichReports(reportFolder, testFolderPath, artifactsDir, reportNames, testResult, + listener); + createHtmlReport(reportFolder, testFolderPath, artifactsDir, reportNames, testResult); + createTransactionSummary(reportFolder, testFolderPath, artifactsDir, reportNames, testResult); + try { + FilePath testSla = copyRunReport(reportFolder, build.getRootDir(), testFolder.getName()); + if (testSla == null) { + listener.getLogger().println("no RunReport.xml file was created"); + } else { + runReportList.add(testSla); + } + } catch (IOException | InterruptedException e) { + listener.getLogger().println(e); + } + } + } + } else { // UFT Test + boolean isHtmlReport = false; + NodeList testCasesNodes = ((Element) testSuiteNode).getElementsByTagName("testcase"); + + // to keep counting how many times this TestName have appeared, used for counting the correct count of appearance + Map fileNameCount = new HashMap<>(); + // to keep counting how many times this TestPath have appeared, used for accessing the correct Report dir + Map filePathCount = new HashMap<>(); + + for (int i = 0; i < testCasesNodes.getLength(); i++) { + Node nNode = testCasesNodes.item(i); + + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + + Element eElement = (Element) nNode; + + if (!eElement.hasAttribute(REPORT_NAME_FIELD)) { + continue; + } + + String reportFolderPath = eElement.getAttribute(REPORT_NAME_FIELD); // e.g. "C:\UFTTest\GuiTest1\Report" + + String testFolderPath = eElement.getAttribute("name"); // e.g. "C:\UFTTest\GuiTest1" + String testStatus = eElement.getAttribute("status"); // e.g. "pass" + Node nodeSystemInfo = eElement.getElementsByTagName("system-out").item(0); + String sysInfo = nodeSystemInfo.getFirstChild().getNodeValue(); + String testDateTime = sysInfo.substring(0, 19); + FilePath testFileFullName = new FilePath(channel, testFolderPath); + + if(!testFileFullName.exists()){ + break; + } + + String testName = testFileFullName.getName(); + + int nameCount = 1; + if (fileNameCount.containsKey(testName)) { + nameCount = fileNameCount.get(testName) + 1; + } + // update the count for this file + fileNameCount.put(testName, nameCount); + testName += "[" + nameCount + "]"; + + String testPath = testFileFullName.getRemote(); + + int pathCount = 1; + if (filePathCount.containsKey(testPath)) { + pathCount = filePathCount.get(testPath) + 1; + } + // update the count for this path + filePathCount.put(testPath, pathCount); + + String reportIndex = ""; + if (filePathCount.get(testPath) != null) { + reportIndex = Integer.toString(filePathCount.get(testPath)); + } else { + reportIndex = "1"; + } + + FilePath reportFolder = new FilePath(channel, reportFolderPath + reportIndex); + if (!reportFolder.exists()) { + reportFolder = new FilePath(channel, reportFolderPath); + } + if(!reportFolder.exists()){ + listener.getLogger().println("Report folder does not exist."); + } + + boolean isParallelRunnerReport = isParallelRunnerReportPath(reportFolder); + reportFolders.add(reportFolder); + + String archiveTestResultMode = _resultsPublisherModel.getArchiveTestResultsMode(); + boolean archiveTestResult; + + // check for the new html report + FilePath htmlReport = new FilePath(reportFolder, + isParallelRunnerReport ? PARALLEL_RESULT_FILE : "run_results.html"); + ReportMetaData reportMetaData = new ReportMetaData(); + if (htmlReport.exists()) { + isHtmlReport = true; + String htmlReportDir = reportFolder.getRemote(); + reportMetaData.setFolderPath(htmlReportDir); + reportMetaData.setIsHtmlReport(true); + reportMetaData.setDateTime(testDateTime); + reportMetaData.setStatus(testStatus); + reportMetaData.setIsParallelRunnerReport(isParallelRunnerReport); // we need to handle + + // the type for this report + String resourceUrl = "artifact/UFTReport/" + (StringUtils.isBlank(nodeName) ? "" : nodeName + "/") + testName + "/Result"; + reportMetaData.setResourceURL(resourceUrl); + reportMetaData.setDisPlayName(testName); // use the name, not the full path + reportMetaData.computeStResFolders(new FilePath(reportFolder, RUN_RESULTS_XML), listener); + + // don't know reportMetaData's URL path yet, we will generate it later. + ReportInfoToCollect.add(reportMetaData); + } + + archiveTestResult = isArchiveTestResult(testStatus, archiveTestResultMode); + if (archiveTestResult) { + if (reportFolder.exists()) { + FilePath testFolder = new FilePath(channel, testFolderPath); + String zipFileName = getUniqueZipFileNameInFolder(zipFileNames, (StringUtils.isBlank(nodeName) ? "" : nodeName + "_") + testFolder.getName(), "UFT"); + zipFileNames.add(zipFileName); + try (ByteArrayOutputStream outStr = new ByteArrayOutputStream()) { + + // don't use FileFilter for zip, or it will cause bug when files are on slave + reportFolder.zip(outStr); + + /* + * I did't use copyRecursiveTo or copyFrom due to bug in + * jekins:https://issues.jenkins-ci.org/browse /JENKINS-9189 //(which is + * cleaimed to have been fixed, but not. So I zip the folder to stream and copy + * it to the master. + */ + + try (InputStream instr = new ByteArrayInputStream(outStr.toByteArray())) { + FilePath archivedFile = new FilePath(new FilePath(artifactsDir), zipFileName); + archivedFile.copyFrom(instr); + } + } + + // add to Report list + String zipFileUrlName = "artifact/" + zipFileName; + reportMetaData.setArchiveUrl(zipFileUrlName); + + } else { + listener.getLogger().println("No report folder was found in: " + reportFolderPath); + } + } + + } + } + + if (isHtmlReport && !ReportInfoToCollect.isEmpty()) { + collectAndPrepareHtmlReports(build, listener, ReportInfoToCollect, runWorkspace, nodeName); + } + + if (!ReportInfoToCollect.isEmpty()) { + int index = 1; + String reportName = "report_metadata" + "_" + index + ".xml"; + // serialize report metadata + synchronized (HtmlBuildReportAction.class) { + while (new File(artifactsDir.getParent(), reportName).exists()) { + index++; + reportName = "report_metadata" + "_" + index + ".xml"; + } + File reportMetaDataXmlFile = new File(artifactsDir.getParent(), reportName); + String reportMetaDataXml = reportMetaDataXmlFile.getAbsolutePath(); + writeReportMetaData2XML(ReportInfoToCollect, reportMetaDataXml, listener); + + // Add UFT report action + try { + listener.getLogger().println("Adding a report action to the current build."); + HtmlBuildReportAction reportAction = new HtmlBuildReportAction(build, reportName, index); + build.addAction(reportAction); + } catch (IOException | SAXException | ParserConfigurationException ex) { + listener.getLogger().println("a problem adding action: " + ex); + } + } + } + } + } + } + + private void writeReportMetaData2XML(List htmlReportsInfo, String xmlFile, TaskListener _logger) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + _logger.error("Failed creating xml doc report: " + e); + return; + } + Document doc = builder.newDocument(); + Element root = doc.createElement("reports_data"); + doc.appendChild(root); + int currentReport = 1; + for (ReportMetaData htmlReportInfo : htmlReportsInfo) { + String disPlayName = htmlReportInfo.getDisPlayName(); + String urlName = htmlReportInfo.getUrlName(); + String resourceURL = htmlReportInfo.getResourceURL(); + String dateTime = htmlReportInfo.getDateTime(); + String status = htmlReportInfo.getStatus(); + String isHtmlReport = htmlReportInfo.getIsHtmlReport() ? "true" : "false"; + String isParallelRunnerReport = htmlReportInfo.getIsParallelRunnerReport() ? "true" : "false"; + String archiveUrl = htmlReportInfo.getArchiveUrl(); + Element elmReport = doc.createElement(REPORT_NAME_FIELD); + elmReport.setAttribute("disPlayName", disPlayName); + elmReport.setAttribute("urlName", urlName); + elmReport.setAttribute("resourceURL", resourceURL); + elmReport.setAttribute("dateTime", dateTime); + elmReport.setAttribute("status", status); + elmReport.setAttribute("isHtmlreport", isHtmlReport); + elmReport.setAttribute("isParallelRunnerReport", isParallelRunnerReport); + elmReport.setAttribute("archiveUrl", archiveUrl); + root.appendChild(elmReport); + currentReport++; + } + + try { + write2XML(doc, xmlFile); + } catch (TransformerException e) { + _logger.error("Failed transforming xml file: " + e); + _logger.getLogger().println("Failed transforming xml file: " + e); + } catch (FileNotFoundException e) { + _logger.error("Failed to find " + xmlFile + ": " + e); + _logger.getLogger().println("Failed to find " + xmlFile + ": " + e); + } + } + + private void write2XML(Document document, String filename) + throws TransformerException, FileNotFoundException { + document.normalize(); + + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + + DOMSource source = new DOMSource(document); + PrintWriter pw = new PrintWriter(new FileOutputStream(filename)); + StreamResult result = new StreamResult(pw); + transformer.transform(source, result); + + } + + private void renamePath(FilePath src, FilePath dest, TaskListener listener, int idxOfRetry) { + try { + if (idxOfRetry > 5) { + listener.getLogger().println("Failed to rename report path [" + src.getRemote() + "] as [" + dest.getRemote() + "] after 5 retries."); + return; + } + Thread.sleep(1500); + src.renameTo(dest); + if (idxOfRetry > 0) { + String msg = String.format("Successfully renamed report path as [%s] after %d %s.", dest.getRemote(), idxOfRetry, (idxOfRetry == 1 ? "retry" : "retries")); + listener.getLogger().println(msg); + } + } catch(Exception e) { + renamePath(src, dest, listener, ++idxOfRetry); + } + } + + private Boolean collectAndPrepareHtmlReports(Run build, TaskListener listener, List htmlReportsInfo, FilePath runWorkspace, String nodeName) { + File reportMainDir = new File(new File(build.getRootDir(), "archive"), "UFTReport"); + if (StringUtils.isNotBlank(nodeName)) { + reportMainDir = new File(reportMainDir, nodeName); + } + + try { + for (ReportMetaData htmlReportInfo : htmlReportsInfo) { + // make sure it's a html report + if (!htmlReportInfo.getIsHtmlReport()) { + continue; + } + + String testName = htmlReportInfo.getDisPlayName(); // like "GuiTest1" + File reportDir = new File(reportMainDir, testName); + String htmlReportDir = htmlReportInfo.getFolderPath(); // C:\UFTTest\GuiTest1\Report + try { + for (String subdir : htmlReportInfo.getStResFolders()) { + File dir = new File(htmlReportDir); + String testFolderPath = dir.getPath().substring(0, dir.getPath().lastIndexOf('\\')); + String stResPath = new File(testFolderPath, subdir).getAbsolutePath(); + if (UftToolUtils.getFilePath(nodeName, stResPath).exists()) { + archiveAndCopyReportFolder(runWorkspace, reportDir, stResPath); + } + } + } catch (Exception e){ + listener.getLogger().println("Path to test folder not found"); + } + //for example: C:\Program Files (x86)\Jenkins\workspace\job_name + + // archive and copy to the subdirs of master + archiveAndCopyReportFolder(runWorkspace, reportDir, htmlReportDir); + // zip copy and unzip + // now,all the files are in the C:\Program Files (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\Report** + // we need to rename the above path to targetPath. + // So at last we got files in C:\Program Files (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\GuiTest\Result + String unzippedFileName = FilenameUtils.getName(htmlReportDir); + + FilePath rootTarget = new FilePath(reportDir); + FilePath targetPath = new FilePath(rootTarget, RESULT); + if(targetPath.exists()){ + continue; + } + // C:\Program Files (x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\GuiTest1" + FilePath unzippedFolderPath = new FilePath(rootTarget, unzippedFileName); + + // C:\Program Files\(x86)\Jenkins\jobs\testAction\builds\35\archive\UFTReport\Report + // rename unzippedFolderPath to targetPath + renamePath(unzippedFolderPath, targetPath, listener, 0); + + // fill in the urlName of this report. we need a network path not a FS path + String resourceUrl = htmlReportInfo.getResourceURL(); + + //parallel runner + FilePath source = new FilePath(runWorkspace, htmlReportDir); + + // if it's a parallel runner report path, we must change the resFileName + boolean isParallelRunner = isParallelRunnerReportPath(source); + + String resFileName = isParallelRunner ? "/parallelrun_results.html" : "/run_results.html"; + + String urlName = resourceUrl + resFileName; // like artifact/UFTReport/GuiTest1/run_results.html + // or for Parallel runner /GuiTest1[1]/parallelrun_results.html + + htmlReportInfo.setUrlName(urlName); + } + } catch (Exception ex) { + listener.getLogger().println("catch exception in collectAndPrepareHtmlReports: " + ex); + listener.getLogger().println(ex.getMessage()); + listener.getLogger().println(ex.getCause()); + listener.getLogger().println(ex.getStackTrace()); + } + + return true; + } + + private void archiveAndCopyReportFolder(FilePath runWorkspace, File reportDir, String htmlReportDir) throws IOException, InterruptedException { + FilePath rootTarget = new FilePath(reportDir); + + FilePath source = new FilePath(runWorkspace, htmlReportDir); + + String zipFileName = "UFT_Report_HTML_tmp.zip"; + FilePath archivedFile = new FilePath(rootTarget, zipFileName); + + try (ByteArrayOutputStream outStr = new ByteArrayOutputStream()) { + source.zip(outStr); + + try (ByteArrayInputStream inStr = new ByteArrayInputStream(outStr.toByteArray())) { + //copy from slave to master + archivedFile.copyFrom(inStr); + } + // end zip copy and unzip + archivedFile.unzip(rootTarget); + + //delete temporary archive UFT_Report_HTML_tmp.zip + archivedFile.delete(); + } + } + + /** + * Copies the run report from the executing node to the Jenkins master for + * processing. + * + * @param reportFolder + * @param buildDir + * @param scenarioName + * @return + * @throws IOException + * @throws InterruptedException + */ + private FilePath copyRunReport(FilePath reportFolder, File buildDir, String scenarioName) + throws IOException, InterruptedException { + FilePath slaReportFilePath = new FilePath(reportFolder, "RunReport.xml"); + if (slaReportFilePath.exists()) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + slaReportFilePath.zip(baos); + File slaDirectory = new File(buildDir, "RunReport"); + if (!slaDirectory.exists()) { + slaDirectory.mkdir(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + FilePath slaDirectoryFilePath = new FilePath(slaDirectory); + FilePath tmpZipFile = new FilePath(slaDirectoryFilePath, "runReport.zip"); + tmpZipFile.copyFrom(bais); + bais.close(); + baos.close(); + tmpZipFile.unzip(slaDirectoryFilePath); + FilePath slaFile = new FilePath(slaDirectoryFilePath, "RunReport.xml"); + slaFile.getBaseName(); + slaFile.renameTo(new FilePath(slaDirectoryFilePath, scenarioName + ".xml")); + + slaFile = new FilePath(slaDirectoryFilePath, scenarioName + ".xml"); + + return slaFile; + } + return null; + } + + private boolean archiveFolder(FilePath reportFolder, String testStatus, FilePath archivedFile, + TaskListener listener) throws IOException, InterruptedException { + String archiveTestResultMode = _resultsPublisherModel.getArchiveTestResultsMode(); + boolean archiveTestResult; + + archiveTestResult = isArchiveTestResult(testStatus, archiveTestResultMode); + + if (archiveTestResult) { + + if (reportFolder.exists()) { + + listener.getLogger().println("Zipping report folder: " + reportFolder); + + ByteArrayOutputStream outstr = new ByteArrayOutputStream(); + reportFolder.zip(outstr); + + /* + * I did't use copyRecursiveTo or copyFrom due to bug in + * jekins:https://issues.jenkins-ci.org/browse /JENKINS-9189 //(which is + * cleaimed to have been fixed, but not. So I zip the folder to stream and copy + * it to the master. + */ + + ByteArrayInputStream instr = new ByteArrayInputStream(outstr.toByteArray()); + + archivedFile.copyFrom(instr); + + outstr.close(); + instr.close(); + return true; + } else { + listener.getLogger().println("No report folder was found in: " + reportFolder); + } + } + + return false; + } + + private boolean isArchiveTestResult(String testStatus, String archiveTestResultMode) { + if (archiveTestResultMode.equals(ResultsPublisherModel.alwaysArchiveResults.getValue()) + || archiveTestResultMode.equals(ResultsPublisherModel.CreateHtmlReportResults.getValue())) { + return true; + } else if (archiveTestResultMode.equals(ResultsPublisherModel.ArchiveFailedTestsResults.getValue())) { + if ("fail".equals(testStatus)) { + return true; + } else if (archiveTestResultMode.equals(ResultsPublisherModel.dontArchiveResults.getValue())) { + return false; + } + } + return false; + } + + /** + * Copy Summary Html reports created by LoadRunner + * + * @param reportFolder + * @param testFolderPath + * @param artifactsDir + * @param reportNames + * @param testResult + * @throws IOException + * @throws InterruptedException + */ + @SuppressWarnings("squid:S134") + private void createHtmlReport(FilePath reportFolder, String testFolderPath, File artifactsDir, + List reportNames, TestResult testResult) throws IOException, InterruptedException { + String archiveTestResultMode = _resultsPublisherModel.getArchiveTestResultsMode(); + boolean createReport = archiveTestResultMode.equals(ResultsPublisherModel.CreateHtmlReportResults.getValue()); + + if (createReport) { + File testFolderPathFile = new File(testFolderPath); + FilePath srcDirectoryFilePath = new FilePath(reportFolder, HTML_REPORT_FOLDER); + if (srcDirectoryFilePath.exists()) { + FilePath srcFilePath = new FilePath(srcDirectoryFilePath, IE_REPORT_FOLDER); + if (srcFilePath.exists()) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + srcFilePath.zip(baos); + File reportDirectory = new File(artifactsDir.getParent(), PERFORMANCE_REPORT_FOLDER); + if (!reportDirectory.exists()) { + reportDirectory.mkdir(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + FilePath reportDirectoryFilePath = new FilePath(reportDirectory); + FilePath tmpZipFile = new FilePath(reportDirectoryFilePath, "tmp.zip"); + tmpZipFile.copyFrom(bais); + bais.close(); + baos.close(); + tmpZipFile.unzip(reportDirectoryFilePath); + String newFolderName = org.apache.commons.io.FilenameUtils.getName(testFolderPathFile.getPath()); + FileUtils.moveDirectory(new File(reportDirectory, IE_REPORT_FOLDER), + new File(reportDirectory, newFolderName)); + tmpZipFile.delete(); + outputReportFiles(reportNames, reportDirectory, testResult, "Performance Report", + HTML_REPORT_FOLDER); + } + } + } + } + + /** + * Create a new directory RichReport/scenario_name on master and copy the .pdf + * files from slave LRA folder + */ + private void createRichReports(FilePath reportFolder, String testFolderPath, File artifactsDir, + List reportNames, TestResult testResult, TaskListener listener) { + try { + File testFolderPathFile = new File(testFolderPath); + FilePath htmlReportPath = new FilePath(reportFolder, LRA_FOLDER); + if (htmlReportPath.exists()) { + File reportDirectory = new File(artifactsDir.getParent(), RICH_REPORT_FOLDER); + if (!reportDirectory.exists()) { + reportDirectory.mkdir(); + } + String newFolderName = org.apache.commons.io.FilenameUtils.getName(testFolderPathFile.getPath()); + File testDirectory = new File(reportDirectory, newFolderName); + if (!testDirectory.exists()) { + testDirectory.mkdir(); + } + + FilePath dstReportPath = new FilePath(testDirectory); + FileFilter reportFileFilter = new WildcardFileFilter("*.pdf"); + List reportFiles = htmlReportPath.list(reportFileFilter); + List richReportNames = new ArrayList(); + for (FilePath fileToCopy : reportFiles) { + FilePath dstFilePath = new FilePath(dstReportPath, fileToCopy.getName()); + fileToCopy.copyTo(dstFilePath); + richReportNames.add(dstFilePath.getName()); + } + + outputReportFiles(reportNames, reportDirectory, testResult, "Rich Reports", INDEX_HTML_NAME); + createRichReportHtml(testDirectory, richReportNames); + } + } catch (IOException | InterruptedException ex) { + listener.getLogger().println("Exception caught while creating rich reports: " + ex); + } + } + + private void createErrorHtml(File htmlDirectory, String error) throws IOException { + String htmlFileContents = "" + "" + + "" + + "Rich Report" + "" + "" + error + ""; + + writeToFile(htmlDirectory, htmlFileContents); + } + + private void createRichReportHtml(File reportDirectory, List richReportNames) throws IOException { + String htmlFileContents = "" + "" + + "" + + "Rich Report" + "" + ""; + + if (richReportNames.size() == 0) { + htmlFileContents += NO_RICH_REPORTS_ERROR; + } else { + for (String richReportName : richReportNames) { + htmlFileContents += ""; + } + } + + htmlFileContents += ""; + + File richReportsHtml = new File(reportDirectory, HTML_REPORT_FOLDER + ".html"); + writeToFile(richReportsHtml, htmlFileContents); + } + + private void writeToFile(File file, String contents) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write(contents); + writer.flush(); + writer.close(); + } + + /** + * creates index files as index for the different scenarios. + * + * @param reportNames + * @param reportDirectory + * @param testResult + * @throws IOException + */ + private void outputReportFiles(List reportNames, File reportDirectory, TestResult testResult, String title, + String htmlFileName) throws IOException { + if (reportNames.isEmpty()) { + return; + } + File htmlIndexFile = new File(reportDirectory, INDEX_HTML_NAME); + BufferedWriter writer = new BufferedWriter(new FileWriter(htmlIndexFile)); + writer.write("%n"); + writer.write("%n"); + writer.write("%n"); + writer.write(String.format("%s%n", title)); + writer.write("%n"); + writer.write("%n"); + writer.write( + "%n"); + writer.write("%n"); + boolean rolling = true; + for (String report : reportNames) { + if (rolling) { + writer.write(String + .format("%n", report, htmlFileName, report)); + rolling = false; + } else { + writer.write(String + .format("%n", report, htmlFileName, report)); + rolling = true; + } + } + + writer.write("
Name
%s
%s
%n"); + writer.write("%n"); + writer.flush(); + writer.close(); + + File indexFile = new File(reportDirectory, REPORT_INDEX_NAME); + try { + writer = new BufferedWriter(new FileWriter(indexFile)); + Iterator resultIterator = null; + if ((testResult != null) && (!testResult.getSuites().isEmpty())) { + resultIterator = testResult.getSuites().iterator();// get the first + } + for (String report : reportNames) { + SuiteResult suitResult = null; + if ((resultIterator != null) && resultIterator.hasNext()) { + suitResult = resultIterator.next(); + } + if (suitResult == null) { + writer.write(report + "\t##\t##\t##%n"); + } else { + int iDuration = (int) suitResult.getDuration(); + StringBuilder bld = new StringBuilder(); + String duration = ""; + if ((iDuration / SECS_IN_DAY) > 0) { + bld.append(String.format("%dday ", iDuration / SECS_IN_DAY)); + iDuration = iDuration % SECS_IN_DAY; + } + if ((iDuration / SECS_IN_HOUR) > 0) { + bld.append(String.format("%02dhr ", iDuration / SECS_IN_HOUR)); + iDuration = iDuration % SECS_IN_HOUR; + } else if (!duration.isEmpty()) { + bld.append("00hr "); + } + if ((iDuration / SECS_IN_MINUTE) > 0) { + bld.append(String.format("%02dmin ", iDuration / SECS_IN_MINUTE)); + iDuration = iDuration % SECS_IN_MINUTE; + } else if (!duration.isEmpty()) { + bld.append("00min "); + } + bld.append(String.format("%02dsec", iDuration)); + duration = bld.toString(); + int iPassCount = 0; + int iFailCount = 0; + for (Iterator i = suitResult.getCases().iterator(); i.hasNext();) { + CaseResult caseResult = (CaseResult) i.next(); + iPassCount += caseResult.getPassCount(); + iFailCount += caseResult.getFailCount(); + } + writer.write(String.format("%s\t%s\t%d\t%d%n", report, duration, iPassCount, iFailCount)); + } + } + } finally { + writer.flush(); + writer.close(); + } + } + + /** + * Copies and creates the transaction summery on the master + * + * @param reportFolder + * @param testFolderPath + * @param artifactsDir + * @param reportNames + * @param testResult + * @throws IOException + * @throws InterruptedException + */ + private void createTransactionSummary(FilePath reportFolder, String testFolderPath, File artifactsDir, + List reportNames, TestResult testResult) throws IOException, InterruptedException { + + File testFolderPathFile = new File(testFolderPath); + String subFolder = HTML_REPORT_FOLDER + File.separator + IE_REPORT_FOLDER + File.separator + HTML_REPORT_FOLDER; + FilePath htmlReportPath = new FilePath(reportFolder, subFolder); + if (htmlReportPath.exists()) { + File reportDirectory = new File(artifactsDir.getParent(), TRANSACTION_SUMMARY_FOLDER); + if (!reportDirectory.exists()) { + reportDirectory.mkdir(); + } + String newFolderName = org.apache.commons.io.FilenameUtils.getName(testFolderPathFile.getPath()); + File testDirectory = new File(reportDirectory, newFolderName); + if (!testDirectory.exists()) { + testDirectory.mkdir(); + } + + FilePath dstReportPath = new FilePath(testDirectory); + FilePath transSummaryReport, transSummaryReportExcel; + if ((transSummaryReport = getTransactionSummaryReport(htmlReportPath)) != null) { + FilePath dstFilePath = new FilePath(dstReportPath, TRANSACTION_REPORT_NAME + ".html"); + transSummaryReport.copyTo(dstFilePath); + + // Copy the .xls which is being referenced by the report + if ((transSummaryReportExcel = getTransactionSummaryReportExcel(htmlReportPath, + transSummaryReport.getName())) != null) { + dstFilePath = new FilePath(dstReportPath, transSummaryReportExcel.getName()); + transSummaryReportExcel.copyTo(dstFilePath); + } + } else { + File htmlIndexFile = new File(testDirectory, TRANSACTION_REPORT_NAME + ".html"); + createErrorHtml(htmlIndexFile, NO_TRANSACTION_SUMMARY_REPORT_ERROR); + } + + FilePath cssFilePath = new FilePath(htmlReportPath, "Properties.css"); + if (cssFilePath.exists()) { + FilePath dstFilePath = new FilePath(dstReportPath, cssFilePath.getName()); + cssFilePath.copyTo(dstFilePath); + } + FilePath pngFilePath = new FilePath(htmlReportPath, "tbic_toexcel.png"); + if (pngFilePath.exists()) { + FilePath dstFilePath = new FilePath(dstReportPath, pngFilePath.getName()); + pngFilePath.copyTo(dstFilePath); + } + + FilePath jsDstReportPath = new FilePath(testDirectory); + FileFilter jsReportFileFilter = new WildcardFileFilter("*.js"); + List jsReporFiles = htmlReportPath.list(jsReportFileFilter); + for (FilePath fileToCopy : jsReporFiles) { + FilePath dstFilePath = new FilePath(jsDstReportPath, fileToCopy.getName()); + fileToCopy.copyTo(dstFilePath); + } + + outputReportFiles(reportNames, reportDirectory, testResult, "Transaction Summary", + TRANSACTION_REPORT_NAME + ".html"); + } + } + + /** + * Scan the LRA folder from slave to find the report containting Transaction + * Summary as title (or title variants based on language packs) + */ + private FilePath getTransactionSummaryReport(FilePath htmlReportPath) throws IOException, InterruptedException { + String[] transactionSummaryNames = { "Transaction Summary", // eng + "トランザクション サマリ", // jpn + "트랜잭션 요약", // kor + "事务摘要", // chs + "Transaktionsübersicht", // deu + "Resumen de transacciones", // spn + "Riepilogo transazioni", // ita + "Récapitulatif des transactions", // fr + "Сводка транзакций", // rus + }; + + FileFilter reportFileFilter = new WildcardFileFilter("Report*.html"); + List reportFiles = htmlReportPath.list(reportFileFilter); + for (FilePath fileToCopy : reportFiles) { + Scanner scanner = new Scanner(fileToCopy.read()).useDelimiter("\\A"); + + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + for (String transactionSummaryName : transactionSummaryNames) { + if (line.contains(transactionSummaryName)) { + return fileToCopy; + } + } + } + } + + return null; + } + + private FilePath getTransactionSummaryReportExcel(FilePath htmlReportPath, String reportName) + throws IOException, InterruptedException { + FileFilter reportFileFilter = new WildcardFileFilter(reportName.replace("html", "xls")); + List reportFiles = htmlReportPath.list(reportFileFilter); + + if (!reportFiles.isEmpty()) { + return reportFiles.get(0); + } + + return null; + } + + /* + * if we have a directory with file name "file.zip" we will return "file_1.zip" + */ + private String getUniqueZipFileNameInFolder(ArrayList names, String fileName, String productName) { + + String result = fileName + REPORT_ARCHIVE_SUFFIX; + int index = 1; + if(productName.equals("UFT") && names.indexOf(result) == -1){ + result = fileName + "_" + index + REPORT_ARCHIVE_SUFFIX; + } + while (names.indexOf(result) > -1) { + result = fileName + "_" + (++index) + REPORT_ARCHIVE_SUFFIX; + } + + return result; + } + + private LrJobResults buildJobDataset(TaskListener listener) + throws ParserConfigurationException, SAXException, IOException, InterruptedException { + listener.getLogger().println("Parsing test run dataset for performance report"); + LrJobResults jobResults = new LrJobResults(); + + // read each RunReport.xml + for (FilePath reportFilePath : runReportList) { + JobLrScenarioResult jobLrScenarioResult = parseScenarioResults(reportFilePath); + jobResults.addScenario(jobLrScenarioResult); + } + + return jobResults; + } + + private JobLrScenarioResult parseScenarioResults(FilePath slaFilePath) + throws ParserConfigurationException, SAXException, IOException, InterruptedException { + JobLrScenarioResult jobLrScenarioResult = new JobLrScenarioResult(slaFilePath.getBaseName()); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + + Document doc = dBuilder.parse(slaFilePath.read()); + + processSLA(jobLrScenarioResult, doc); + processLrScenarioStats(jobLrScenarioResult, doc); + // TODO: add fail / Pass count + return jobLrScenarioResult; + } + + private void processLrScenarioStats(JobLrScenarioResult jobLrScenarioResult, Document doc) { + + NodeList rootNodes = doc.getChildNodes(); + Node root = getNode("Runs", rootNodes); + Element generalNode = (Element) getNode("General", root.getChildNodes()); + NodeList generalNodeChildren = generalNode.getChildNodes(); + + extractVUserScenarioReult(jobLrScenarioResult, generalNodeChildren); + extractTransactionScenarioResult(jobLrScenarioResult, generalNodeChildren); + extractConnectionsScenarioResult(jobLrScenarioResult, generalNodeChildren); + extractDuration(jobLrScenarioResult, generalNodeChildren); + } + + private void extractDuration(JobLrScenarioResult jobLrScenarioResult, NodeList generalNodeChildren) { + Node ScenrioDurationNode = getNode("Time", generalNodeChildren); + String scenarioDurationAttr = getNodeAttr("Duration", ScenrioDurationNode); + jobLrScenarioResult.setScenarioDuration(Long.valueOf(scenarioDurationAttr)); + } + + private void extractConnectionsScenarioResult(JobLrScenarioResult jobLrScenarioResult, + NodeList generalNodeChildren) { + Node connections = getNode("Connections", generalNodeChildren); + jobLrScenarioResult.setConnectionMax(Integer.valueOf(getNodeAttr("MaxCount", connections))); + } + + private void extractTransactionScenarioResult(JobLrScenarioResult jobLrScenarioResult, + NodeList generalNodeChildren) { + int atrrCount; + Node transactions = getNode("Transactions", generalNodeChildren); + atrrCount = transactions.getAttributes().getLength(); + for (int atrrIndx = 0; atrrIndx < atrrCount; atrrIndx++) { + Node vUserAttr = transactions.getAttributes().item(atrrIndx); + jobLrScenarioResult.transactionSum.put(vUserAttr.getNodeName(), Integer.valueOf(vUserAttr.getNodeValue())); + } + + NodeList transactionNodes = transactions.getChildNodes(); + int transactionNodesCount = transactionNodes.getLength(); + for (int transIdx = 0; transIdx < transactionNodesCount; transIdx++) { + if (transactionNodes.item(transIdx).getNodeType() != Node.ELEMENT_NODE) { + continue; + } + Element transaction = (Element) transactionNodes.item(transIdx); + TreeMap transactionData = new TreeMap(); + transactionData.put("Pass", Integer.valueOf(transaction.getAttribute("Pass"))); + transactionData.put("Fail", Integer.valueOf(transaction.getAttribute("Fail"))); + transactionData.put("Stop", Integer.valueOf(transaction.getAttribute("Stop"))); + jobLrScenarioResult.transactionData.put(transaction.getAttribute("Name"), transactionData); + } + } + + private void extractVUserScenarioReult(JobLrScenarioResult jobLrScenarioResult, NodeList generalNodeChildren) { + Node vUser = getNode("VUsers", generalNodeChildren); + int atrrCount = vUser.getAttributes().getLength(); + for (int atrrIndx = 0; atrrIndx < atrrCount; atrrIndx++) { + Node vUserAttr = vUser.getAttributes().item(atrrIndx); + jobLrScenarioResult.vUserSum.put(vUserAttr.getNodeName(), Integer.valueOf(vUserAttr.getNodeValue())); + } + } + + private void processSLA(JobLrScenarioResult jobLrScenarioResult, Document doc) { + Node slaRuleNode; + Element slaRuleElement; + + NodeList rootNodes = doc.getChildNodes(); + Node root = getNode("Runs", rootNodes); + Element slaRoot = (Element) getNode("SLA", root.getChildNodes()); + NodeList slaRuleResults = slaRoot.getChildNodes(); + + for (int j = 0; j < slaRuleResults.getLength(); j++) { + slaRuleNode = slaRuleResults.item(j); + if (slaRuleNode.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + slaRuleElement = (Element) slaRuleNode; + // check type by mesurment field: + LrTest.SLA_GOAL slaGoal = LrTest.SLA_GOAL.checkGoal(slaRuleElement.getAttribute("Measurement")); + + processSlaRule(jobLrScenarioResult, slaRuleElement, slaGoal); + } + + } + + private void processSlaRule(JobLrScenarioResult jobLrScenarioResult, Element slaRuleElement, + LrTest.SLA_GOAL slaGoal) { + switch (slaGoal) { + case AverageThroughput: + WholeRunResult averageThroughput = new WholeRunResult(); + averageThroughput.setSlaGoal(LrTest.SLA_GOAL.AverageThroughput); + averageThroughput.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); + averageThroughput.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); + averageThroughput.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + averageThroughput + .setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); + jobLrScenarioResult.scenarioSlaResults.add(averageThroughput); + break; + case TotalThroughput: + WholeRunResult totalThroughput = new WholeRunResult(); + totalThroughput.setSlaGoal(LrTest.SLA_GOAL.TotalThroughput); + totalThroughput.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); + totalThroughput.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); + totalThroughput.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + totalThroughput + .setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); + jobLrScenarioResult.scenarioSlaResults.add(totalThroughput); + + break; + case AverageHitsPerSecond: + WholeRunResult averageHitsPerSecond = new WholeRunResult(); + averageHitsPerSecond.setSlaGoal(LrTest.SLA_GOAL.AverageHitsPerSecond); + averageHitsPerSecond.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); + averageHitsPerSecond.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); + averageHitsPerSecond.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + averageHitsPerSecond + .setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); + jobLrScenarioResult.scenarioSlaResults.add(averageHitsPerSecond); + + break; + case TotalHits: + WholeRunResult totalHits = new WholeRunResult(); + totalHits.setSlaGoal(LrTest.SLA_GOAL.TotalHits); + totalHits.setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); + totalHits.setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); + totalHits.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + totalHits.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); + jobLrScenarioResult.scenarioSlaResults.add(totalHits); + + break; + case ErrorsPerSecond: + TimeRangeResult errPerSec = new AvgTransactionResponseTime(); + errPerSec.setSlaGoal(LrTest.SLA_GOAL.ErrorsPerSecond); + errPerSec.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + errPerSec.setLoadThrashold(slaRuleElement.getAttribute("SLALoadThresholdValue")); + errPerSec.setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); // Might + // not + // work + // due + // to + // time + // ranges + addTimeRanges(errPerSec, slaRuleElement); + jobLrScenarioResult.scenarioSlaResults.add(errPerSec); + + break; + case PercentileTRT: + PercentileTransactionWholeRun percentileTransactionWholeRun = new PercentileTransactionWholeRun(); + percentileTransactionWholeRun.setSlaGoal(LrTest.SLA_GOAL.PercentileTRT); + percentileTransactionWholeRun.setName(slaRuleElement.getAttribute("TransactionName")); + percentileTransactionWholeRun + .setActualValue(Double.valueOf(slaRuleElement.getAttribute(SLA_ACTUAL_VALUE_LABEL))); + percentileTransactionWholeRun + .setGoalValue(Double.valueOf(slaRuleElement.getAttribute(SLA_GOAL_VALUE_LABEL))); + percentileTransactionWholeRun.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + percentileTransactionWholeRun.setPrecentage(Double.valueOf(slaRuleElement.getAttribute("Percentile"))); + percentileTransactionWholeRun + .setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); + jobLrScenarioResult.scenarioSlaResults.add(percentileTransactionWholeRun); + + break; + case AverageTRT: + AvgTransactionResponseTime transactionTimeRange = new AvgTransactionResponseTime(); + transactionTimeRange.setSlaGoal(LrTest.SLA_GOAL.AverageTRT); + transactionTimeRange.setName(slaRuleElement.getAttribute("TransactionName")); + transactionTimeRange.setFullName(slaRuleElement.getAttribute(SLA_ULL_NAME)); + transactionTimeRange.setLoadThrashold(slaRuleElement.getAttribute("SLALoadThresholdValue")); + transactionTimeRange + .setStatus(LrTest.SLA_STATUS.checkStatus(slaRuleElement.getLastChild().getTextContent().trim())); // Might + // not + // work + // due + // to + // time + // ranges + addTimeRanges(transactionTimeRange, slaRuleElement); + jobLrScenarioResult.scenarioSlaResults.add(transactionTimeRange); + break; + case Bad: + break; + } + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) + throws InterruptedException, IOException { + + runReportList = new ArrayList(); + final Set mergedResultNames = new HashSet(); + final List almResultNames = new ArrayList(); + final List fileSystemResultNames = new ArrayList(); + final List almSSEResultNames = new ArrayList(); + final List pcResultNames = new ArrayList(); + + // Get the TestSet report files names of the current build + if (build instanceof WorkflowRun) { // it comes from a Pipeline build flow + List paramActions = build.getActions(ParametersAction.class); + for(ParametersAction paramAction : paramActions){ + if (paramAction != null && paramAction.getAllParameters() != null) { + ParameterValue buildStepNameParam = paramAction.getParameter("buildStepName"); + if (buildStepNameParam != null) { + String buildStepName = ((StringParameterValue)buildStepNameParam).getValue(); + ParameterValue resFileParam; + switch (buildStepName) { + case "RunFromAlmBuilder": + resFileParam = paramAction.getParameter("resultsFilename"); + if (resFileParam != null) { + almResultNames.add(((StringParameterValue)resFileParam).getValue()); + } + break; + case "RunFromAlmLabManagementBuilder": + resFileParam = paramAction.getParameter("resultsFilename"); + if (resFileParam != null) { + almSSEResultNames.add(((StringParameterValue)resFileParam).getValue()); + } + break; + case "PcBuilder": + resFileParam = paramAction.getParameter("resultsFilename"); + if (resFileParam != null) { + pcResultNames.add(((StringParameterValue)resFileParam).getValue()); + } + break; + + default: + // default case should not be used, if necessary to handle a new builder, please create a specific case + break; + } + } + } + } + } else { // it comes from a FreeStyle Project build flow + Project project = RuntimeUtils.cast(build.getParent()); + List builders = project.getBuilders(); + for (Builder builder : builders) { + if (builder instanceof RunFromAlmBuilder) { + almResultNames.add(((RunFromAlmBuilder) builder).getRunResultsFileName()); + } else if (builder instanceof SseBuilder) { + String resultsFileName = ((SseBuilder) builder).getRunResultsFileName(); + if (resultsFileName != null) { + almSSEResultNames.add(resultsFileName); + } + } else if (builder instanceof PcBuilder) { + String resultsFileName = ((PcBuilder) builder).getRunResultsFileName(); + if (resultsFileName != null) { + pcResultNames.add(resultsFileName); + } + } + } + } + + IOFileFilter byBuildNumberFileFilter = new WildcardFileFilter(Arrays.asList(String.format("*_%d.xml", build.getNumber()), String.format("*%d", build.getNumber()), "*-Report.xml")); + IOFileFilter byBuildStartedFileFilter = new AgeFileFilter(build.getStartTimeInMillis(), false); + IOFileFilter fileFilter = FileFilterUtils.and(byBuildNumberFileFilter, byBuildStartedFileFilter); + + listFilesWithFilterRecursive(workspace, "", fileFilter, fileSystemResultNames); + + mergedResultNames.addAll(almResultNames); + mergedResultNames.addAll(fileSystemResultNames); + mergedResultNames.addAll(almSSEResultNames); + mergedResultNames.addAll(pcResultNames); + + // Has any QualityCenter builder been set up? + if (mergedResultNames.isEmpty()) { + listener.getLogger().println("RunResultRecorder: no results xml File provided"); + return; + } + + recordRunResults(build, workspace, launcher, listener, new ArrayList<>(mergedResultNames), fileSystemResultNames); + return; + } + + private void listFilesWithFilterRecursive(FilePath path, String basePath, IOFileFilter fileFilter, List fileSystemResultNames) throws IOException, InterruptedException { + List fileSystemResultsPath = path.list(fileFilter); + for (FilePath fileSystemResultPath : fileSystemResultsPath) { + if (!fileSystemResultPath.isDirectory()) { + fileSystemResultNames.add(basePath + fileSystemResultPath.getName()); + } else { + listFilesWithFilterRecursive(fileSystemResultPath, fileSystemResultPath.getName() + File.separator, fileFilter, fileSystemResultNames); + } + } + } + + @Override + public MatrixAggregator createAggregator(MatrixBuild build, Launcher launcher, BuildListener listener) { + + return new TestResultAggregator(build, launcher, listener); + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + /** + * Gets results publisher model. + * + * @return the results publisher model + */ + public ResultsPublisherModel getResultsPublisherModel() { + + return _resultsPublisherModel; + } + + public String getArchiveTestResultsMode() { + return _resultsPublisherModel.getArchiveTestResultsMode(); + } + + /** + * The type Descriptor. + */ + @Symbol("publishMicroFocusTestResults") + @Extension + public static class DescriptorImpl extends BuildStepDescriptor { + + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { + + load(); + } + + @Override + public String getDisplayName() { + + return "Publish OpenText tests result"; + } + + @Override + public boolean isApplicable(@SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + /** + * Gets report archive modes. + * + * @return the report archive modes + */ + public List getReportArchiveModes() { + + return ResultsPublisherModel.archiveModes; + } + } + + /** + * The type Rrv file filter. + */ + public class RRVFileFilter implements FileFilter { + private final String[] excludedFilenames = new String[] { "run_results.xml", "run_results.html", "diffcompare", + "Resources" }; + private final String[] excludedDirnames = new String[] { "diffcompare", "Resources", "CheckPoints", + "Snapshots" }; + + @Override + public boolean accept(File file) { + boolean bRet = true; + + for (String filename : excludedFilenames) { + if (file.getName().equals(filename)) { + bRet = false; + break; + } + } + + if (bRet) { + for (String parentname : excludedDirnames) { + if (file.getParent().contains(parentname)) { + bRet = false; + break; + } + } + } + return bRet; + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/SlaRuleTypes.java b/src/main/java/com/microfocus/application/automation/tools/results/SlaRuleTypes.java new file mode 100644 index 0000000000..4b5266c877 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/SlaRuleTypes.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +/** + * Created by kazaky on 07/07/2016. + */ +public enum SlaRuleTypes +{ + SIMPLE_WHOLE_RUN, + WHOLE_RUN, + TIME_RANGE_TRANSACTION, + SIMPLE_TIME_RANGE, + TRANSACTION_PERCENTILE; +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/results/SummaryReport.java b/src/main/java/com/microfocus/application/automation/tools/results/SummaryReport.java new file mode 100644 index 0000000000..0372705296 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/SummaryReport.java @@ -0,0 +1,179 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.model.DirectoryBrowserSupport; +import hudson.model.ModelObject; +import hudson.model.Run; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Models the HTML summary reports + */ +public class SummaryReport implements ModelObject { + + private String name = ""; + private String color = ""; + private String duration = ""; + private String pass = ""; + private String fail = ""; + private Run build = null; + private DirectoryBrowserSupport _directoryBrowserSupport = null; + + /** + * Instantiates a new Summary report. + * + * @param build the build + * @param name the name + * @param directoryBrowserSupport the directory browser support + */ + public SummaryReport(Run build, String name, DirectoryBrowserSupport directoryBrowserSupport) { + this.build = build; + this.name = name; + _directoryBrowserSupport = directoryBrowserSupport; + } + + @Override + public String getDisplayName() { + return name; + } + + /** + * Gets build. + * + * @return the build + */ + public Run getBuild() { + return build; + } + + /** + * Gets name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Do dynamic. + * + * @param req the req + * @param rsp the rsp + * @throws IOException the io exception + * @throws ServletException the servlet exception + */ + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + + if (_directoryBrowserSupport != null) + _directoryBrowserSupport.generateResponse(req, rsp, this); + } + + /** + * Gets color. + * + * @return the color + */ + public String getColor() { + return color; + } + + /** + * Sets color. + * + * @param value the value + */ + public void setColor(String value) { + color = value; + } + + /** + * Gets duration. + * + * @return the duration + */ + public String getDuration() { + return duration; + } + + /** + * Sets duration. + * + * @param value the value + */ + public void setDuration(String value) { + duration = value; + } + + /** + * Gets pass. + * + * @return the pass + */ + public String getPass() { + return pass; + } + + /** + * Sets pass. + * + * @param value the value + */ + public void setPass(String value) { + pass = value; + } + + /** + * Gets fail. + * + * @return the fail + */ + public String getFail() { + return fail; + } + + /** + * Sets fail. + * + * @param value the value + */ + public void setFail(String value) { + fail = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/TestResultToALMUploader.java b/src/main/java/com/microfocus/application/automation/tools/results/TestResultToALMUploader.java new file mode 100644 index 0000000000..5420ac822d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/TestResultToALMUploader.java @@ -0,0 +1,556 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.cloudbees.plugins.credentials.matchers.IdMatcher; +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.results.service.AlmRestInfo; +import com.microfocus.application.automation.tools.results.service.AlmRestTool; +import com.microfocus.application.automation.tools.results.service.AttachmentUploadService; +import com.microfocus.application.automation.tools.results.service.ExternalEntityUploadLogger; +import com.microfocus.application.automation.tools.results.service.IExternalEntityUploadService; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Util; +import hudson.matrix.MatrixAggregatable; +import hudson.matrix.MatrixAggregator; +import hudson.matrix.MatrixBuild; +import hudson.model.Action; +import hudson.model.BuildListener; +import hudson.model.AbstractProject; +import hudson.model.Item; +import hudson.model.Queue; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.model.queue.Tasks; +import hudson.security.ACL; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.tasks.test.TestResultAggregator; +import hudson.tasks.test.TestResultProjectAction; +import hudson.util.FormValidation; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.Serializable; +import java.net.HttpURLConnection; +import java.util.List; + +import hudson.util.ListBoxModel; +import hudson.util.VariableResolver; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; +import org.apache.tools.ant.DirectoryScanner; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import com.microfocus.application.automation.tools.model.UploadTestResultToAlmModel; +import com.microfocus.application.automation.tools.results.service.DefaultExternalEntityUploadServiceImpl; + +/** + + * + * @author Jacky Zhu + */ +public class TestResultToALMUploader extends Recorder implements Serializable, MatrixAggregatable, SimpleBuildStep { + + private static final long serialVersionUID = 1L; + private UploadTestResultToAlmModel uploadTestResultToAlmModel; + private String almServerName; + private String credentialsId; + private String almDomain; + private String clientType; + private String almProject; + private String testingFramework; + private String testingTool; + private String almTestFolder; + private String almTestSetFolder; + private String almTimeout; + private String testingResultFile; + private String testingAttachments; + private String jenkinsServerUrl; + + // These getters setters work for reading config.xml. + public UploadTestResultToAlmModel getUploadTestResultToAlmModel() { + return uploadTestResultToAlmModel; + } + + public void setUploadTestResultToAlmModel(UploadTestResultToAlmModel uploadTestResultToAlmModel) { + this.uploadTestResultToAlmModel = uploadTestResultToAlmModel; + } + + public String getAlmServerName() { + return almServerName; + } + + public void setAlmServerName(String almServerName) { + this.almServerName = almServerName; + } + + public String getCredentialsId() { + return credentialsId; + } + + public void setCredentialsId(String credentialsId) { + this.credentialsId = credentialsId; + } + + public String getAlmDomain() { + return almDomain; + } + + public void setAlmDomain(String almDomain) { + this.almDomain = almDomain; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public String getAlmProject() { + return almProject; + } + + public void setAlmProject(String almProject) { + this.almProject = almProject; + } + + public String getTestingFramework() { + return testingFramework; + } + + public void setTestingFramework(String testingFramework) { + this.testingFramework = testingFramework; + } + + public String getTestingTool() { + return testingTool; + } + + public void setTestingTool(String testingTool) { + this.testingTool = testingTool; + } + + public String getAlmTestFolder() { + return almTestFolder; + } + + public void setAlmTestFolder(String almTestFolder) { + this.almTestFolder = almTestFolder; + } + + public String getAlmTestSetFolder() { + return almTestSetFolder; + } + + public void setAlmTestSetFolder(String almTestSetFolder) { + this.almTestSetFolder = almTestSetFolder; + } + + public String getAlmTimeout() { + return almTimeout; + } + + public void setAlmTimeout(String almTimeout) { + this.almTimeout = almTimeout; + } + + public String getTestingResultFile() { + return testingResultFile; + } + + public void setTestingResultFile(String testingResultFile) { + this.testingResultFile = testingResultFile; + } + + public String getTestingAttachments() { + return testingAttachments; + } + + public void setTestingAttachments(String testingAttachments) { + this.testingAttachments = testingAttachments; + } + + public String getJenkinsServerUrl() { + return jenkinsServerUrl; + } + + public void setJenkinsServerUrl(String jenkinsServerUrl) { + this.jenkinsServerUrl = jenkinsServerUrl; + } + + @DataBoundConstructor + public TestResultToALMUploader( + String almServerName, + String credentialsId, + String almDomain, + String clientType, + String almProject, + String testingFramework, + String testingTool, + String almTestFolder, + String almTestSetFolder, + String almTimeout, + String testingResultFile, + String testingAttachments, + String jenkinsServerUrl) { + + this.almServerName = almServerName; + this.credentialsId = credentialsId; + this.almDomain = almDomain; + this.clientType = clientType; + this.almProject = almProject; + this.testingFramework = testingFramework; + this.testingTool = testingTool; + this.almTestFolder = almTestFolder; + this.almTestSetFolder = almTestSetFolder; + this.almTimeout = almTimeout; + this.testingResultFile = testingResultFile; + this.testingAttachments = testingAttachments; + this.jenkinsServerUrl = jenkinsServerUrl; + } + + @Override + public void perform(Run build, FilePath workspace, Launcher launcher, + TaskListener listener) throws InterruptedException, IOException { + + ExternalEntityUploadLogger logger = new ExternalEntityUploadLogger(listener.getLogger()); + + // Credentials id maybe can't be blank + if (StringUtils.isBlank(credentialsId)) { + logger.log("INFO: credentials is not configured."); + build.setResult(Result.UNSTABLE); + return; + } + UsernamePasswordCredentials credentials = getCredentialsById(credentialsId, build, logger); + + + logger.log(String.format("INFO: 'Upload test result to ALM' Post Build Step is being invoked by %s.", + credentials.getUsername())); + + List importedTestsetIds = null; + + uploadTestResultToAlmModel = new UploadTestResultToAlmModel( + almServerName, + credentials.getUsername(), + credentials.getPassword().getPlainText(), + almDomain, + clientType, + almProject, + testingFramework, + testingTool, + almTestFolder, + almTestSetFolder, + almTimeout, + testingResultFile, + testingAttachments, + jenkinsServerUrl); + + VariableResolver varResolver = new VariableResolver.ByMap(build.getEnvironment(listener)); + + String serverUrl = getAlmServerUrl(uploadTestResultToAlmModel.getAlmServerName()); + String runUrl = ""; + String tempUrl = Util.replaceMacro(uploadTestResultToAlmModel.getJenkinsServerUrl(), varResolver); + if(tempUrl != null && tempUrl.length() >0 ) { + if(tempUrl.charAt(tempUrl.length() -1) != '/') { + runUrl= tempUrl + "/" + build.getUrl(); + } else { + runUrl = tempUrl + build.getUrl(); + } + } + + File root = build.getRootDir(); + DirectoryScanner ds = new DirectoryScanner(); + ds.setBasedir(root); + ds.setIncludes( new String[] {uploadTestResultToAlmModel.getTestingResultFile()}); + ds.scan(); + if (ds.getIncludedFilesCount() == 0) { + logger.log("INFO: No Test Report found."); + build.setResult(Result.UNSTABLE); + } else { + logger.log("INFO: "+ ds.getIncludedFilesCount() +" test result file found."); + String[] files = ds.getIncludedFiles(); + + AlmRestInfo loginInfo = new AlmRestInfo( + serverUrl, + Util.replaceMacro(uploadTestResultToAlmModel.getAlmDomain(), varResolver), + clientType, + Util.replaceMacro(uploadTestResultToAlmModel.getAlmProject(), varResolver), + uploadTestResultToAlmModel.getAlmUserName(), + uploadTestResultToAlmModel.getAlmPassword(), + Util.replaceMacro(uploadTestResultToAlmModel.getAlmTestSetFolder(), varResolver) + ); + AlmRestTool almRestTool = new AlmRestTool(loginInfo, logger); + + for (String fileName : files) { + String fullpath = root.getAbsolutePath() + File.separator + fileName; + logger.log("INFO: Start to upload "+fullpath); + IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(almRestTool, workspace, logger); + try { + importedTestsetIds = service.uploadExternalTestSet(loginInfo, + fullpath, + Util.replaceMacro(uploadTestResultToAlmModel.getAlmTestSetFolder(), varResolver), + Util.replaceMacro(uploadTestResultToAlmModel.getAlmTestFolder(), varResolver), + uploadTestResultToAlmModel.getTestingFramework(), + uploadTestResultToAlmModel.getTestingTool(), + String.valueOf(build.getNumber()), + build.getParent().getDisplayName(), + runUrl + ); + logger.log("INFO: Uploaded "+fullpath + "."); + } catch (Exception e) { + logger.log("ERR: There's exception while uploading " + fullpath + ". " + e.getMessage()); + build.setResult(Result.UNSTABLE); + } + } + + // Upload attachment. + String testingAttachment = uploadTestResultToAlmModel.getTestingAttachments(); + if (importedTestsetIds != null + && !importedTestsetIds.isEmpty() + && testingAttachment != null + && !testingAttachment.isEmpty()) { + + AttachmentUploadService.init(build, workspace, almRestTool.getRestClient(), logger); + if (!AttachmentUploadService.getInstance().upload(testingAttachment, "test-sets", importedTestsetIds.get(0))) { + build.setResult(Result.UNSTABLE); + } + } + } + logger.log("INFO: 'Upload test result to ALM' Completed."); + } + + /** + * Get user name password credentials by id. + */ + private UsernamePasswordCredentials getCredentialsById(String credentialsId, Run run, ExternalEntityUploadLogger logger) { + UsernamePasswordCredentials credentials = CredentialsProvider.findCredentialById(credentialsId, + StandardUsernamePasswordCredentials.class, + run, + URIRequirementBuilder.create().build()); + + if (credentials == null) { + logger.log("Can not find credentials with the credentialsId:" + credentialsId); + } + return credentials; + } + + private String getAlmServerUrl(String almServerName) { + AlmServerSettingsModel[] almServers = AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + if(almServers != null && almServers.length >0) { + for(AlmServerSettingsModel almServerModel: almServers) { + if(almServerName.equalsIgnoreCase(almServerModel.getAlmServerName())) { + return almServerModel.getAlmServerUrl(); + } + } + } + return ""; + } + + /** + * This works for jelly + * + * @return + */ + public AlmServerSettingsModel getAlmServerSettingsModel() { + for (AlmServerSettingsModel almServer : getDescriptor().getAlmServers()) { + if (this.almServerName.equals(almServer.getAlmServerName())) { + return almServer; + } + } + return null; + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public Action getProjectAction(AbstractProject project) { + + return new TestResultProjectAction(project); + } + + @Override + public MatrixAggregator createAggregator( + MatrixBuild build, + Launcher launcher, + BuildListener listener) { + + return new TestResultAggregator(build, launcher, listener); + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + + return BuildStepMonitor.BUILD; + } + + @Extension + // To expose this builder in the Snippet Generator. + @Symbol("uploadResultToALM") + public static class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + + load(); + } + + @Override + public String getDisplayName() { + + return "Upload test result to ALM"; + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + public boolean hasAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().hasAlmServers(); + } + + public AlmServerSettingsModel[] getAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + public FormValidation doCheckAlmUserName(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("User name must be set"); + } + + return FormValidation.ok(); + } + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Domain must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Project must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmTestFolder(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("TestFolder are missing"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmTestSetFolder(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("TestSetFolder are missing"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckTestingResultFile(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Testing result file must be set"); + } + + return FormValidation.ok(); + } + + public List getTestingFrameworks() { + return UploadTestResultToAlmModel.testingFrameworks; + } + + /** + * To fill in the credentials drop down list which's field is 'credentialsId'. + * This method's name works with tag . + */ + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + if (project == null || !project.hasPermission(Item.CONFIGURE)) { + return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); + } + return new StandardUsernameListBoxModel() + .includeEmptyValue() + .includeAs( + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + project, + StandardUsernamePasswordCredentials.class, + URIRequirementBuilder.create().build()) + .includeCurrentValue(credentialsId); + } + + public FormValidation doCheckCredentialsId(@AncestorInPath Item project, @QueryParameter String value) { + for (ListBoxModel.Option o : CredentialsProvider.listCredentials( + StandardUsernamePasswordCredentials.class, + project, + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + URIRequirementBuilder.create().build(), + new IdMatcher(value))) { + + if (StringUtils.equals(value, o.value)) { + return FormValidation.ok(); + } + } + // no credentials available, can't check + return FormValidation.warning("Cannot find any credentials with id " + value); + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/TransactionSummaryAction.java b/src/main/java/com/microfocus/application/automation/tools/results/TransactionSummaryAction.java new file mode 100644 index 0000000000..2ed10e803d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/TransactionSummaryAction.java @@ -0,0 +1,175 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results; + +import hudson.FilePath; +import hudson.model.Action; +import hudson.model.DirectoryBrowserSupport; +import hudson.model.Run; +import hudson.tasks.test.TestResultProjectAction; +import jenkins.tasks.SimpleBuildStep; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Generates the transaction summary reports and adds them to the run + */ +public class TransactionSummaryAction implements Action, SimpleBuildStep.LastBuildAction { + + private static final String TRANSACTION_SUMMARY_FOLDER = "TransactionSummary"; + private static final String REPORT_INDEX = "report.index"; + + private Map summaryReportMap = new LinkedHashMap(); + private final List projectActionList; + + private Run build; + + /** + * Instantiates a new Transaction summary action. + * + * @param build the build + */ + public TransactionSummaryAction(Run build) throws IOException { + this.build = build; + File reportFolder = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); + if (reportFolder.exists()) { + File indexFile = new File(reportFolder, REPORT_INDEX); + if (indexFile.exists()) { + File file = new File(build.getRootDir(), TRANSACTION_SUMMARY_FOLDER); + DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, new FilePath(file), "report", "graph.gif", false); + + + createTransactionIndex(build, indexFile, dbs); + + + } + } + projectActionList = new ArrayList(); + } + + private void createTransactionIndex(Run build, File indexFile, DirectoryBrowserSupport dbs) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(indexFile)); + String line; + boolean rolling = true; + while ((line = br.readLine()) != null) { + String[] values = line.split("\t"); + if (values.length < 1) + continue; + SummaryReport report = new SummaryReport(build, values[0], dbs); + if (rolling) { + report.setColor("#FFF"); + rolling = false; + } else { + report.setColor("#F1F1F1"); + rolling = true; + } + if (values.length >= 2) + report.setDuration(values[1]); + else + report.setDuration("##"); + if (values.length >= 3) + report.setPass(values[2]); + else + report.setPass("##"); + if (values.length >= 4) + report.setFail(values[3]); + else + report.setFail("##"); + summaryReportMap.put(values[0], report); + } + br.close(); + } + + @Override + public String getIconFileName() { + return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/LoadRunner.png"; + } + + @Override + public String getDisplayName() { + return "Transaction Summary"; + } + + @Override + public String getUrlName() { + return "TransactionSummary"; + } + + /** + * Gets build. + * + * @return the build + */ + public Run getBuild() { + return build; + } + + /** + * Gets summary report map. + * + * @return the summary report map + */ + public Map getSummaryReportMap() { + return summaryReportMap; + } + + /** + * Gets dynamic. + * + * @param name the name + * @param req the req + * @param rsp the rsp + * @return the dynamic + */ + public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { + if (summaryReportMap.containsKey(name)) + return summaryReportMap.get(name); + return null; + } + + @Override + public Collection getProjectActions() { + return Collections.emptySet(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReport.java b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReport.java new file mode 100644 index 0000000000..08247dd17f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReport.java @@ -0,0 +1,117 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.lrscriptresultparser; + +/** + * Created by kazaky on 28/03/2017. + */ + +/** + * Stores the information on html report for specific report + */ +@SuppressWarnings("squid:S1068") +public class LrScriptHtmlReport { + public static final String LR_REPORT_FOLDER = "LRReport"; + public static final String BASE_LR_REPORT_URL = "artifact/LRReport/"; + private final String scriptLocalPath; //Created for future use and allow backward compatibility + private String scriptName; + private String htmlUrl; + private String scriptFolderPath; + + /** + * Instantiates a new Lr script html report. + * + * @param scriptName the script name + * @param htmlUrl the html url + */ + public LrScriptHtmlReport(String scriptName, String htmlUrl, String scriptLocalPath) { + this.scriptName = scriptName; + this.scriptFolderPath = BASE_LR_REPORT_URL + scriptName; + this.htmlUrl = scriptFolderPath + htmlUrl; + this.scriptLocalPath = scriptLocalPath; + } + + /** + * Gets script name. + * + * @return the script name + */ + public String getScriptName() { + return scriptName; + } + + /** + * Sets script name. + * + * @param scriptName the script name + */ + public void setScriptName(String scriptName) { + this.scriptName = scriptName; + } + + /** + * Gets html url. + * + * @return the html url + */ + public String getHtmlUrl() { + return htmlUrl; + } + + /** + * Sets html url. + * + * @param htmlUrl the html url + */ + public void setHtmlUrl(String htmlUrl) { + this.htmlUrl = htmlUrl; + } + + /** + * Gets script folder path. + * + * @return the script folder path + */ + public String getScriptFolderPath() { + return this.scriptFolderPath; + } + + /** + * Sets script folder path. + * + * @param scriptFolderPath the script folder path + */ + public void setScriptFolderPath(String scriptFolderPath) { + this.scriptFolderPath = scriptFolderPath; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction.java b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction.java new file mode 100644 index 0000000000..080c1a6b68 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction.java @@ -0,0 +1,107 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.lrscriptresultparser; + +import hudson.model.Action; +import hudson.model.Run; +import jenkins.util.VirtualFile; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Created by kazaky on 27/03/2017. + */ + +/** + * Presents the LR script HTML report + */ +public class LrScriptHtmlReportAction implements Action { + private final VirtualFile basePath; + private Run build; + private HashSet scripts = new HashSet(); + private List reportMetaDataList = new ArrayList(); + + public LrScriptHtmlReportAction(Run build) { + this.build = build; + this.basePath = build.getArtifactManager().root().child(LrScriptHtmlReport.LR_REPORT_FOLDER); + } + + @SuppressWarnings("squid:S1452") + public final Run getBuild() { + return build; + } + + protected File reportFile() { + return getBuildHtmlReport(); + } + + private File getBuildHtmlReport() { + return new File(basePath.child("index.html").toURI()); + } + + @Override + public String getIconFileName() { + return "/plugin/hp-application-automation-tools-plugin/PerformanceReport/VuGen.png"; + } + + @Override + public String getDisplayName() { + return "LR VuGen Report"; + } + + @Override + public String getUrlName() { + return "LRReport"; + } + + // other property of the report + public List getAllReports() { + return this.reportMetaDataList; + } + + public void mergeResult(Run build, String scriptName) { + if (this.scripts == null) { + this.reportMetaDataList = new ArrayList(); + this.scripts = new HashSet(); + } + this.scripts.add(scriptName); + String scriptResultPath = build.getArtifactManager().root().child("LRReport").child(scriptName).toString(); + LrScriptHtmlReport lrScriptHtmlReport = new LrScriptHtmlReport(scriptName,"/result.html", scriptResultPath); + this.reportMetaDataList.add(lrScriptHtmlReport); + } + + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptResultsSanitizer.java b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptResultsSanitizer.java new file mode 100644 index 0000000000..3bf1835dde --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptResultsSanitizer.java @@ -0,0 +1,112 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.lrscriptresultparser; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Created by kazaky on 27/03/2017. + */ +public class LrScriptResultsSanitizer extends FilterReader { + /** + * Creates a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + * @throws NullPointerException if in is null + */ + public LrScriptResultsSanitizer(Reader in) { + super(in); + } + + /** + * This is another no-op read() method we have to implement. We implement it + * in terms of the method above. Our superclass implements the remaining + * read() methods in terms of these two. + */ + @Override + public int read() throws IOException { + char[] buf = new char[1]; + int result = read(buf, 0, 1); + if (result == -1) { + return -1; + } else { + return (int) buf[0]; + } + } + + @Override + public int read(char[] buf, int from, int len) throws IOException { + int numchars = 0; // how many characters have been read + // Loop, because we might read a bunch of characters, then strip them + // all out, leaving us with zero characters to return. + while (numchars == 0) { + numchars = in.read(buf, from, len); // Read characters + if (numchars == -1) + return -1; // Check for EOF and handle it. + + // Loop through the characters we read, stripping out HTML tags. + // Characters not in tags are copied over previous tags + int last = from; // Index of last non-HTML char + for (int i = from; i < from + numchars; i++) { + + if(!isBadXMLChar(buf[i])) + { + buf[last] = buf[i]; + last++; + } + } + + + numchars = last - from; // Figure out how many characters remain + } // And if it is more than zero characters + return numchars; // Then return that number. + } + + @SuppressWarnings("squid:S109") + private static boolean isBadXMLChar(char current) + { + switch(current){ + case 9: + case 10: + case 13: + return false; + default: + break; + } + + return !(((current >= 57344) && (current <= 0xfffd)) || ((current >= 32) && (current <= 55295))); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParseException.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParseException.java new file mode 100644 index 0000000000..5fbefd4a5b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParseException.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +public class ReportParseException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ReportParseException(){ + + } + + public ReportParseException(Throwable cause) { + + super(cause); + } + + public ReportParseException(String message) { + + super(message); + } + + public ReportParseException(String message, Throwable cause) { + + super(message, cause); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParser.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParser.java new file mode 100644 index 0000000000..900caa8991 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParser.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; + +public interface ReportParser { + String TESTING_FRAMEWORK_JUNIT = "JUnit"; + String EXTERNAL_TEST_TYPE = "EXTERNAL-TEST"; + String REPORT_FORMAT_JENKINS_JUNIT_PLUGIN = "Jenkins JUnit Plugin"; + String REPORT_FORMAT_ANT = "Ant"; + String REPORT_FORMAT_MAVEN_SUREFIRE_PLUGIN = "Maven Surefire Plugin"; + String EXTERNAL_TEST_SET_TYPE_ID = "hp.qc.test-set.external"; + String EXTERNAL_TEST_INSTANCE_TYPE_ID = "hp.qc.test-instance.external-test"; + String EXTERNAL_RUN_TYPE_ID = "hp.qc.run.external-test"; + + List parseTestSets(InputStream reportInputStream, String testingFramework, String testingTool) throws ReportParseException; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParserManager.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParserManager.java new file mode 100644 index 0000000000..8992c07695 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/ReportParserManager.java @@ -0,0 +1,99 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import com.microfocus.application.automation.tools.results.parser.antjunit.AntJUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.parser.jenkinsjunit.JenkinsJUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.parser.mavensurefire.MavenSureFireReportParserImpl; +import com.microfocus.application.automation.tools.results.parser.nunit.NUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.parser.nunit3.NUnit3ReportParserImpl; +import com.microfocus.application.automation.tools.results.parser.testngxml.TestNGXmlReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import hudson.FilePath; + +public class ReportParserManager { + + private static ReportParserManager instance = new ReportParserManager(); + + private List parserList; + private FilePath workspace; + private Logger logger; + + private ReportParserManager() {} + + public static ReportParserManager getInstance(FilePath workspace, Logger logger) { + if (instance.workspace == null) { + instance.workspace = workspace; + } + if (instance.logger == null) { + instance.logger = logger; + } + return instance; + } + + public List parseTestSets(String reportFilePath, String testingFramework, String testingTool) { + init(); + List testsets = null; + for (ReportParser reportParser : parserList) { + try { + InputStream in = new FileInputStream(reportFilePath); + testsets = reportParser.parseTestSets(in, testingFramework, testingTool); + break; + } catch (Exception e) { + logger.log("Failed to parse file with: " + reportParser.getClass().getName()); + } + } + return testsets; + } + + private void init() { + if (parserList == null) { + parserList = new ArrayList(); + } + + if (parserList.isEmpty()) { + parserList.add(new JenkinsJUnitReportParserImpl()); + parserList.add(new MavenSureFireReportParserImpl()); + parserList.add(new TestNGXmlReportParserImpl()); + parserList.add(new NUnit3ReportParserImpl(workspace)); + parserList.add(new NUnitReportParserImpl()); + parserList.add(new AntJUnitReportParserImpl()); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java new file mode 100644 index 0000000000..a6b34aa6b7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/AntJUnitReportParserImpl.java @@ -0,0 +1,161 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.util.ParserUtil; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +public class AntJUnitReportParserImpl implements ReportParser { + + public List parseTestSets(InputStream reportInputStream, + String testingFramework, String testingTool) throws ReportParseException { + + try { + return parseTestSetsFromAntJUnitReport(reportInputStream, testingFramework, testingTool); + + } catch (Exception e) { + throw new ReportParseException(e); + + } finally { + try { + if (reportInputStream != null) { + reportInputStream.close(); + } + } catch (IOException e) { + throw new ReportParseException(e); + } + } + } + + private Testsuites parseFromAntJUnitReport(InputStream reportInputStream) throws JAXBException { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(AntJUnitReportParserImpl.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(Testsuites.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + return (Testsuites)unmarshaller.unmarshal(reportInputStream); + } + + private AlmTest createExternalTestForAntJUnit(Testcase tc, String testingFramework, String testingTool) { + + return ParserUtil.createExternalTest(tc.getClassname(), tc.getName(), testingFramework, testingTool); + } + + private String getRunDetail(Testcase tc){ + String detail = ParserUtil.marshallerObject(Testcase.class, tc); + return Base64Encoder.encode(detail.getBytes()); + } + + + private ArrayList parseTestSetsFromAntJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { + Testsuites testsuites = parseFromAntJUnitReport(reportInputStream); + + ArrayList testSets = new ArrayList(); + + for(Testsuite ts : testsuites.getTestsuite()) { + AlmTestSet testSet = new AlmTestSetImpl(); + testSet.setFieldValue(AlmTestSet.TESTSET_NAME, ParserUtil.replaceInvalidCharsForTestSetName(ts.getName())); + testSet.setFieldValue(AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); + testSets.add(testSet); + + for (Testcase tc: ts.getTestcase()) { + AlmTestInstance testInstance = new AlmTestInstanceImpl(); + testInstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); + testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); + + AlmTest test = createExternalTestForAntJUnit(tc, testingFramework, testingTool); + testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); + + AlmRun run = ParserUtil.createRun(getRunStatus(tc), + ts.getTimestamp(), + tc.getTime(), + getRunDetail (tc)); + testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); + } + } + + return testSets; + } + + private String getRunStatus(Testcase testcase) { + if (testcase.getError().size() > 0) { + return IAlmConsts.IStatuses.FAILED.value(); + } + if (testcase.getFailure().size() > 0) { + return IAlmConsts.IStatuses.FAILED.value(); + } + + String result = null; + String status = testcase.getStatus(); + if (status == null) { + result = IAlmConsts.IStatuses.PASSED.value(); + } else { + status = status.trim(); + if (status.length() > 0) { + try { + result = IAlmConsts.IStatuses.valueOf(status.toUpperCase()).value(); + } catch (IllegalArgumentException e) { + result = status; + } + } else { + result = IAlmConsts.IStatuses.PASSED.value(); + } + } + return result; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Error.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Error.java new file mode 100644 index 0000000000..da2b25b421 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Error.java @@ -0,0 +1,155 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "content" +}) +@XmlRootElement(name = "error") +public class Error { + + @XmlValue + protected String content; + @XmlAttribute(name = "type") + protected String type; + @XmlAttribute(name = "message") + protected String message; + + /** + * Gets the value of the content property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Failure.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Failure.java new file mode 100644 index 0000000000..fae0eba889 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Failure.java @@ -0,0 +1,155 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "content" +}) +@XmlRootElement(name = "failure") +public class Failure { + + @XmlValue + protected String content; + @XmlAttribute(name = "type") + protected String type; + @XmlAttribute(name = "message") + protected String message; + + /** + * Gets the value of the content property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/ObjectFactory.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/ObjectFactory.java new file mode 100644 index 0000000000..3fc2ad4fd3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/ObjectFactory.java @@ -0,0 +1,161 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; +import java.lang.*; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the generated package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _SystemOut_QNAME = new QName("", "system-out"); + private final static QName _Skipped_QNAME = new QName("", "skipped"); + private final static QName _SystemErr_QNAME = new QName("", "system-err"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link Failure } + * + */ + public Failure createFailure() { + return new Failure(); + } + + /** + * Create an instance of {@link Testsuites } + * + */ + public Testsuites createTestsuites() { + return new Testsuites(); + } + + /** + * Create an instance of {@link Testsuite } + * + */ + public Testsuite createTestsuite() { + return new Testsuite(); + } + + /** + * Create an instance of {@link Properties } + * + */ + public Properties createProperties() { + return new Properties(); + } + + /** + * Create an instance of {@link Property } + * + */ + public Property createProperty() { + return new Property(); + } + + /** + * Create an instance of {@link Testcase } + * + */ + public Testcase createTestcase() { + return new Testcase(); + } + + /** + * Create an instance of {@link Error } + * + */ + public Error createError() { + return new Error(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "system-out") + public JAXBElement createSystemOut(String value) { + return new JAXBElement(_SystemOut_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "skipped") + public JAXBElement createSkipped(String value) { + return new JAXBElement(_Skipped_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "system-err") + public JAXBElement createSystemErr(String value) { + return new JAXBElement(_SystemErr_QNAME, String.class, null, value); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Properties.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Properties.java new file mode 100644 index 0000000000..059ecdc884 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Properties.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}property" maxOccurs="unbounded"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "property" +}) +@XmlRootElement(name = "properties") +public class Properties { + + @XmlElement(required = true) + protected List property; + + /** + * Gets the value of the property property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the property property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getProperty().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Property } + * + * + */ + public List getProperty() { + if (property == null) { + property = new ArrayList(); + } + return this.property; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Property.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Property.java new file mode 100644 index 0000000000..5e3064a7ec --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Property.java @@ -0,0 +1,126 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "property") +public class Property { + + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "value", required = true) + protected String value; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testcase.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testcase.java new file mode 100644 index 0000000000..c84f56e6ba --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testcase.java @@ -0,0 +1,371 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import java.lang.*; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}skipped" minOccurs="0"/>
+ *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "skipped", + "error", + "failure", + "systemOut", + "systemErr" +}) +@XmlRootElement(name = "testcase") +public class Testcase { + + protected String skipped; + protected List error; + protected List failure; + @XmlElement(name = "system-out") + protected List systemOut; + @XmlElement(name = "system-err") + protected List systemErr; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "assertions") + protected String assertions; + @XmlAttribute(name = "time") + protected String time; + @XmlAttribute(name = "classname") + protected String classname; + @XmlAttribute(name = "status") + protected String status; + + /** + * Gets the value of the skipped property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the error property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the error property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getError().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Error } + * + * + */ + public List getError() { + if (error == null) { + error = new ArrayList(); + } + return this.error; + } + + /** + * Gets the value of the failure property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the failure property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getFailure().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Failure } + * + * + */ + public List getFailure() { + if (failure == null) { + failure = new ArrayList(); + } + return this.failure; + } + + /** + * Gets the value of the systemOut property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the systemOut property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSystemOut().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getSystemOut() { + if (systemOut == null) { + systemOut = new ArrayList(); + } + return this.systemOut; + } + + /** + * Gets the value of the systemErr property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the systemErr property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSystemErr().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getSystemErr() { + if (systemErr == null) { + systemErr = new ArrayList(); + } + return this.systemErr; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the assertions property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAssertions() { + return assertions; + } + + /** + * Sets the value of the assertions property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAssertions(String value) { + this.assertions = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the classname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getClassname() { + return classname; + } + + /** + * Sets the value of the classname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setClassname(String value) { + this.classname = value; + } + + /** + * Gets the value of the status property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStatus(String value) { + this.status = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuite.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuite.java new file mode 100644 index 0000000000..1e3a527518 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuite.java @@ -0,0 +1,490 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}properties" minOccurs="0"/>
+ *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" minOccurs="0"/>
+ *         <element ref="{}system-err" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "properties", + "testcase", + "systemOut", + "systemErr" +}) +@XmlRootElement(name = "testsuite") +public class Testsuite { + + protected Properties properties; + protected List testcase; + @XmlElement(name = "system-out") + protected String systemOut; + @XmlElement(name = "system-err") + protected String systemErr; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "tests", required = true) + protected String tests; + @XmlAttribute(name = "failures") + protected String failures; + @XmlAttribute(name = "errors") + protected String errors; + @XmlAttribute(name = "time") + protected String time; + @XmlAttribute(name = "disabled") + protected String disabled; + @XmlAttribute(name = "skipped") + protected String skipped; + @XmlAttribute(name = "timestamp") + protected String timestamp; + @XmlAttribute(name = "hostname") + protected String hostname; + @XmlAttribute(name = "id") + protected String id; + @XmlAttribute(name = "package") + protected String _package; + + /** + * Gets the value of the properties property. + * + * @return + * possible object is + * {@link Properties } + * + */ + public Properties getProperties() { + return properties; + } + + /** + * Sets the value of the properties property. + * + * @param value + * allowed object is + * {@link Properties } + * + */ + public void setProperties(Properties value) { + this.properties = value; + } + + /** + * Gets the value of the testcase property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testcase property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestcase().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Testcase } + * + * + */ + public List getTestcase() { + if (testcase == null) { + testcase = new ArrayList(); + } + return this.testcase; + } + + /** + * Gets the value of the systemOut property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSystemOut() { + return systemOut; + } + + /** + * Sets the value of the systemOut property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSystemOut(String value) { + this.systemOut = value; + } + + /** + * Gets the value of the systemErr property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSystemErr() { + return systemErr; + } + + /** + * Sets the value of the systemErr property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSystemErr(String value) { + this.systemErr = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the tests property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTests() { + return tests; + } + + /** + * Sets the value of the tests property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTests(String value) { + this.tests = value; + } + + /** + * Gets the value of the failures property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFailures(String value) { + this.failures = value; + } + + /** + * Gets the value of the errors property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrors() { + return errors; + } + + /** + * Sets the value of the errors property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrors(String value) { + this.errors = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the disabled property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDisabled() { + return disabled; + } + + /** + * Sets the value of the disabled property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDisabled(String value) { + this.disabled = value; + } + + /** + * Gets the value of the skipped property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the timestamp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTimestamp() { + return timestamp; + } + + /** + * Sets the value of the timestamp property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTimestamp(String value) { + this.timestamp = value; + } + + /** + * Gets the value of the hostname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getHostname() { + return hostname; + } + + /** + * Sets the value of the hostname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setHostname(String value) { + this.hostname = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + /** + * Gets the value of the package property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPackage() { + return _package; + } + + /** + * Sets the value of the package property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPackage(String value) { + this._package = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuites.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuites.java new file mode 100644 index 0000000000..8ffe7505dd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/antjunit/Testsuites.java @@ -0,0 +1,271 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.01.26 at 05:00:04 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.antjunit; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}testsuite" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="tests" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "testsuite" +}) +@XmlRootElement(name = "testsuites") +public class Testsuites { + + protected List testsuite; + @XmlAttribute(name = "name") + protected String name; + @XmlAttribute(name = "time") + protected String time; + @XmlAttribute(name = "tests") + protected String tests; + @XmlAttribute(name = "failures") + protected String failures; + @XmlAttribute(name = "disabled") + protected String disabled; + @XmlAttribute(name = "errors") + protected String errors; + + /** + * Gets the value of the testsuite property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testsuite property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestsuite().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Testsuite } + * + * + */ + public List getTestsuite() { + if (testsuite == null) { + testsuite = new ArrayList(); + } + return this.testsuite; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the tests property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTests() { + return tests; + } + + /** + * Sets the value of the tests property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTests(String value) { + this.tests = value; + } + + /** + * Gets the value of the failures property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFailures(String value) { + this.failures = value; + } + + /** + * Gets the value of the disabled property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDisabled() { + return disabled; + } + + /** + * Sets the value of the disabled property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDisabled(String value) { + this.disabled = value; + } + + /** + * Gets the value of the errors property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrors() { + return errors; + } + + /** + * Sets the value of the errors property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrors(String value) { + this.errors = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java new file mode 100644 index 0000000000..3181f062d5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/JenkinsJUnitReportParserImpl.java @@ -0,0 +1,146 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.jenkinsjunit; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.util.ParserUtil; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +public class JenkinsJUnitReportParserImpl implements ReportParser { + + public List parseTestSets(InputStream reportInputStream, + String testingFramework, String testingTool) throws ReportParseException { + + try { + return parseTestSetsFromJenkinsPluginJUnitReport(reportInputStream, testingFramework, testingTool); + } catch (Exception e) { + + //e.printStackTrace(); + throw new ReportParseException(); + } + } + + private Result parseFromJenkinsPluginJUnitReport(InputStream reportInputStream) throws JAXBException { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(JenkinsJUnitReportParserImpl.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(Result.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + return (Result)unmarshaller.unmarshal(reportInputStream); + } + + private AlmTest createExternalTestForJenkinsPluginJUnit(Result.Suites.Suite.Cases.Case c, String testingFramework, String testingTool) { + + return ParserUtil.createExternalTest(c.getClassName(), c.getTestName(), testingFramework, testingTool); + } + + private String getRunDetail(Result.Suites.Suite.Cases.Case c){ + String detail = ParserUtil.marshallerObject(Result.Suites.Suite.Cases.Case.class, c); + return Base64Encoder.encode(detail.getBytes()); + } + + private ArrayList parseTestSetsFromJenkinsPluginJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { + Result result = parseFromJenkinsPluginJUnitReport(reportInputStream); + ArrayList testSets = new ArrayList(); + + for (Result.Suites suites : result.getSuites()) { + for (Result.Suites.Suite suite : suites.getSuite()) { + AlmTestSet testSet = new AlmTestSetImpl(); + testSet.setFieldValue(AlmTestSet.TESTSET_NAME, ParserUtil.replaceInvalidCharsForTestSetName(suite.getName())); + testSet.setFieldValue(AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); + testSets.add(testSet); + + for (Result.Suites.Suite.Cases cases : suite.getCases()) { + for (Result.Suites.Suite.Cases.Case c : cases.getCase()){ + AlmTestInstance testInstance = new AlmTestInstanceImpl(); + testInstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); + testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); + + AlmTest test = createExternalTestForJenkinsPluginJUnit(c, testingFramework, testingTool); + testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); + + AlmRun run = ParserUtil.createRun(getRunStatus(c), + suite.getTimestamp(), + c.getDuration(), + getRunDetail (c)); + testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); + } + } + } + } + + return testSets; + } + + private String getRunStatus(Result.Suites.Suite.Cases.Case c) { + String result; + if (c.getSkipped() != null && c.getSkipped().equals("true")) { + result = IAlmConsts.IStatuses.NO_RUN.value(); + + } else if (c.getErrorStackTrace() != null && c.getErrorStackTrace().length() > 0) { + result = IAlmConsts.IStatuses.FAILED.value(); + + } else if (c.getErrorDetails() != null && c.getErrorDetails().length() > 0) { + result = IAlmConsts.IStatuses.FAILED.value(); + + } else if (c.getFailedSince() != null && c.getFailedSince().equals("0")) { + result = IAlmConsts.IStatuses.PASSED.value(); + + } else { + result = IAlmConsts.IStatuses.FAILED.value(); + } + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java new file mode 100644 index 0000000000..90fce589c5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/NewDataSet.java @@ -0,0 +1,109 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.23 at 04:30:11 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.jenkinsjunit; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice maxOccurs="unbounded" minOccurs="0">
+ *         <element ref="{}result"/>
+ *       </choice>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "result" +}) +@XmlRootElement(name = "NewDataSet") +public class NewDataSet { + + protected List result; + + /** + * Gets the value of the result property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the result property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getResult().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Result } + * + * + */ + public List getResult() { + if (result == null) { + result = new ArrayList(); + } + return this.result; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java new file mode 100644 index 0000000000..361fd52e10 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/ObjectFactory.java @@ -0,0 +1,120 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.jenkinsjunit; +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.23 at 04:30:11 PM CST +// + + + + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.hp.alm.qc.qualitymanagement.entities.reportparsing.jenkinsjunitreport package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.hp.alm.qc.qualitymanagement.entities.reportparsing.jenkinsjunitreport + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link Result } + * + */ + public Result createResult() { + return new Result(); + } + + /** + * Create an instance of {@link Result.Suites } + * + */ + public Result.Suites createResultSuites() { + return new Result.Suites(); + } + + /** + * Create an instance of {@link Result.Suites.Suite } + * + */ + public Result.Suites.Suite createResultSuitesSuite() { + return new Result.Suites.Suite(); + } + + /** + * Create an instance of {@link Result.Suites.Suite.Cases } + * + */ + public Result.Suites.Suite.Cases createResultSuitesSuiteCases() { + return new Result.Suites.Suite.Cases(); + } + + /** + * Create an instance of {@link NewDataSet } + * + */ + public NewDataSet createNewDataSet() { + return new NewDataSet(); + } + + /** + * Create an instance of {@link Result.Suites.Suite.Cases.Case } + * + */ + public Result.Suites.Suite.Cases.Case createResultSuitesSuiteCasesCase() { + return new Result.Suites.Suite.Cases.Case(); + } + +} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/Result.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/Result.java similarity index 94% rename from src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/Result.java rename to src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/Result.java index 3f632b2d89..b5f80c9870 100644 --- a/src/main/java/com/hp/application/automation/tools/results/parser/jenkinsjunit/Result.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/jenkinsjunit/Result.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 // See http://java.sun.com/xml/jaxb @@ -6,7 +38,7 @@ // -package com.hp.application.automation.tools.results.parser.jenkinsjunit; +package com.microfocus.application.automation.tools.results.parser.jenkinsjunit; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Error.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Error.java new file mode 100644 index 0000000000..d45be8f2ab --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Error.java @@ -0,0 +1,155 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "content" +}) +@XmlRootElement(name = "error") +public class Error { + + @XmlValue + protected String content; + @XmlAttribute(name = "type") + protected String type; + @XmlAttribute(name = "message") + protected String message; + + /** + * Gets the value of the content property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Failure.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Failure.java new file mode 100644 index 0000000000..56381d1bf4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Failure.java @@ -0,0 +1,155 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "content" +}) +@XmlRootElement(name = "failure") +public class Failure { + + @XmlValue + protected String content; + @XmlAttribute(name = "type") + protected String type; + @XmlAttribute(name = "message") + protected String message; + + /** + * Gets the value of the content property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java new file mode 100644 index 0000000000..4d81d3a38e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/MavenSureFireReportParserImpl.java @@ -0,0 +1,149 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.util.ParserUtil; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +public class MavenSureFireReportParserImpl implements ReportParser { + + public List parseTestSets(InputStream reportInputStream, + String testingFramework, String testingTool) throws ReportParseException { + + try { + return parseTestSetsFromMavenSurefirePluginJUnitReport(reportInputStream, testingFramework, testingTool); + } catch (Exception e) { + + throw new ReportParseException(); + } + } + + private Testsuite parseFromMavenSurefirePluginJUnitReport(InputStream reportInputStream) throws JAXBException { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(MavenSureFireReportParserImpl.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(Testsuite.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + return (Testsuite)unmarshaller.unmarshal(reportInputStream); + } + + private AlmTest createExternalTestForMavenSurefirePluginJUnit(Testcase tc, String testingFramework, String testingTool) { + + return ParserUtil.createExternalTest(tc.getClassname(), tc.getName(), testingFramework, testingTool); + } + + private ArrayList parseTestSetsFromMavenSurefirePluginJUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { + Testsuite testsuite = parseFromMavenSurefirePluginJUnitReport(reportInputStream); + ArrayList testSets = new ArrayList(); + + AlmTestSet testSet = new AlmTestSetImpl(); + testSet.setFieldValue( AlmTestSet.TESTSET_NAME, testsuite.getName()); + testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); + testSets.add(testSet); + + for (Testcase tc: testsuite.getTestcase()) { + AlmTestInstance testInstance = new AlmTestInstanceImpl(); + testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); + testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); + + AlmTest test = createExternalTestForMavenSurefirePluginJUnit(tc, testingFramework, testingTool); + testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); + + AlmRun run = ParserUtil.createRun(getRunStatus(tc), + testsuite.getTimestamp(), + tc.getTime(), + getRunDetail(tc)); + testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); + } + + return testSets; + } + + private String getRunStatus(Testcase testcase) { + if (testcase.getError().size() > 0) { + return IAlmConsts.IStatuses.FAILED.value(); + } + if (testcase.getFailure().size() > 0) { + return IAlmConsts.IStatuses.FAILED.value(); + } + if (testcase.getStatus() == null) { + return IAlmConsts.IStatuses.PASSED.value(); + } + + String result; + String status = testcase.getStatus(); + if (status != null) { + status = status.trim(); + if (status.length() > 0) { + try { + result = IAlmConsts.IStatuses.valueOf(status.toUpperCase()).value(); + } catch (IllegalArgumentException e) { + result = status; + } + } else { + result = IAlmConsts.IStatuses.PASSED.value(); + } + } else { + result = IAlmConsts.IStatuses.PASSED.value(); + } + return result; + } + + private String getRunDetail(Testcase testcase) { + String detail = ParserUtil.marshallerObject(Testcase.class, testcase); + return Base64Encoder.encode(detail.getBytes()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java new file mode 100644 index 0000000000..40bf3c69ac --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/ObjectFactory.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; +import java.lang.*; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.hp.alm.qc.qualitymanagement.entities.reportparsing.mavensurefirereport package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _SystemOut_QNAME = new QName("", "system-out"); + private final static QName _Skipped_QNAME = new QName("", "skipped"); + private final static QName _SystemErr_QNAME = new QName("", "system-err"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.hp.alm.qc.qualitymanagement.entities.reportparsing.mavensurefirereport + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link Failure } + * + */ + public Failure createFailure() { + return new Failure(); + } + + /** + * Create an instance of {@link Error } + * + */ + public Error createError() { + return new Error(); + } + + /** + * Create an instance of {@link Property } + * + */ + public Property createProperty() { + return new Property(); + } + + /** + * Create an instance of {@link Properties } + * + */ + public Properties createProperties() { + return new Properties(); + } + + /** + * Create an instance of {@link Testsuite } + * + */ + public Testsuite createTestsuite() { + return new Testsuite(); + } + + /** + * Create an instance of {@link Testcase } + * + */ + public Testcase createTestcase() { + return new Testcase(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "system-out") + public JAXBElement createSystemOut(String value) { + return new JAXBElement(_SystemOut_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "skipped") + public JAXBElement createSkipped(String value) { + return new JAXBElement(_Skipped_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "system-err") + public JAXBElement createSystemErr(String value) { + return new JAXBElement(_SystemErr_QNAME, String.class, null, value); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Properties.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Properties.java new file mode 100644 index 0000000000..025b21d967 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Properties.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}property" maxOccurs="unbounded"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "property" +}) +@XmlRootElement(name = "properties") +public class Properties { + + @XmlElement(required = true) + protected List property; + + /** + * Gets the value of the property property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the property property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getProperty().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Property } + * + * + */ + public List getProperty() { + if (property == null) { + property = new ArrayList(); + } + return this.property; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Property.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Property.java new file mode 100644 index 0000000000..f9e566754e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Property.java @@ -0,0 +1,126 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "property") +public class Property { + + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "value", required = true) + protected String value; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testcase.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testcase.java new file mode 100644 index 0000000000..dc421db780 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testcase.java @@ -0,0 +1,371 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}skipped" minOccurs="0"/>
+ *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "skipped", + "error", + "failure", + "systemOut", + "systemErr" +}) +@XmlRootElement(name = "testcase") +public class Testcase { + + protected String skipped; + protected List error; + protected List failure; + @XmlElement(name = "system-out") + protected List systemOut; + @XmlElement(name = "system-err") + protected List systemErr; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "assertions") + protected String assertions; + @XmlAttribute(name = "time") + protected String time; + @XmlAttribute(name = "classname") + protected String classname; + @XmlAttribute(name = "status") + protected String status; + + /** + * Gets the value of the skipped property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the error property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the error property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getError().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Error } + * + * + */ + public List getError() { + if (error == null) { + error = new ArrayList(); + } + return this.error; + } + + /** + * Gets the value of the failure property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the failure property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getFailure().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Failure } + * + * + */ + public List getFailure() { + if (failure == null) { + failure = new ArrayList(); + } + return this.failure; + } + + /** + * Gets the value of the systemOut property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the systemOut property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSystemOut().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getSystemOut() { + if (systemOut == null) { + systemOut = new ArrayList(); + } + return this.systemOut; + } + + /** + * Gets the value of the systemErr property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the systemErr property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSystemErr().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getSystemErr() { + if (systemErr == null) { + systemErr = new ArrayList(); + } + return this.systemErr; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the assertions property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAssertions() { + return assertions; + } + + /** + * Sets the value of the assertions property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAssertions(String value) { + this.assertions = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the classname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getClassname() { + return classname; + } + + /** + * Sets the value of the classname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setClassname(String value) { + this.classname = value; + } + + /** + * Gets the value of the status property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStatus(String value) { + this.status = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testsuite.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testsuite.java new file mode 100644 index 0000000000..1c4b503cbc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/mavensurefire/Testsuite.java @@ -0,0 +1,490 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.03.25 at 02:54:53 PM CST +// + + +package com.microfocus.application.automation.tools.results.parser.mavensurefire; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}properties" minOccurs="0"/>
+ *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" minOccurs="0"/>
+ *         <element ref="{}system-err" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "properties", + "testcase", + "systemOut", + "systemErr" +}) +@XmlRootElement(name = "testsuite") +public class Testsuite { + + protected Properties properties; + protected List testcase; + @XmlElement(name = "system-out") + protected String systemOut; + @XmlElement(name = "system-err") + protected String systemErr; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "tests", required = true) + protected String tests; + @XmlAttribute(name = "failures") + protected String failures; + @XmlAttribute(name = "errors") + protected String errors; + @XmlAttribute(name = "time") + protected String time; + @XmlAttribute(name = "disabled") + protected String disabled; + @XmlAttribute(name = "skipped") + protected String skipped; + @XmlAttribute(name = "timestamp") + protected String timestamp; + @XmlAttribute(name = "hostname") + protected String hostname; + @XmlAttribute(name = "id") + protected String id; + @XmlAttribute(name = "package") + protected String _package; + + /** + * Gets the value of the properties property. + * + * @return + * possible object is + * {@link Properties } + * + */ + public Properties getProperties() { + return properties; + } + + /** + * Sets the value of the properties property. + * + * @param value + * allowed object is + * {@link Properties } + * + */ + public void setProperties(Properties value) { + this.properties = value; + } + + /** + * Gets the value of the testcase property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testcase property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestcase().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Testcase } + * + * + */ + public List getTestcase() { + if (testcase == null) { + testcase = new ArrayList(); + } + return this.testcase; + } + + /** + * Gets the value of the systemOut property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSystemOut() { + return systemOut; + } + + /** + * Sets the value of the systemOut property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSystemOut(String value) { + this.systemOut = value; + } + + /** + * Gets the value of the systemErr property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSystemErr() { + return systemErr; + } + + /** + * Sets the value of the systemErr property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSystemErr(String value) { + this.systemErr = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the tests property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTests() { + return tests; + } + + /** + * Sets the value of the tests property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTests(String value) { + this.tests = value; + } + + /** + * Gets the value of the failures property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFailures(String value) { + this.failures = value; + } + + /** + * Gets the value of the errors property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrors() { + return errors; + } + + /** + * Sets the value of the errors property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrors(String value) { + this.errors = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the disabled property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDisabled() { + return disabled; + } + + /** + * Sets the value of the disabled property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDisabled(String value) { + this.disabled = value; + } + + /** + * Gets the value of the skipped property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the timestamp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTimestamp() { + return timestamp; + } + + /** + * Sets the value of the timestamp property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTimestamp(String value) { + this.timestamp = value; + } + + /** + * Gets the value of the hostname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getHostname() { + return hostname; + } + + /** + * Sets the value of the hostname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setHostname(String value) { + this.hostname = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + /** + * Gets the value of the package property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPackage() { + return _package; + } + + /** + * Sets the value of the package property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPackage(String value) { + this._package = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoriesType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoriesType.java new file mode 100644 index 0000000000..22d7b9d441 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoriesType.java @@ -0,0 +1,108 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for categoriesType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="categoriesType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="category" type="{}categoryType" maxOccurs="unbounded"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "categoriesType", propOrder = { + "category" +}) +public class CategoriesType { + + @XmlElement(required = true) + protected List category; + + /** + * Gets the value of the category property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the category property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getCategory().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CategoryType } + * + * + */ + public List getCategory() { + if (category == null) { + category = new ArrayList(); + } + return this.category; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoryType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoryType.java new file mode 100644 index 0000000000..a3ca408ee5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/CategoryType.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for categoryType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="categoryType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "categoryType") +public class CategoryType { + + @XmlAttribute(name = "name", required = true) + protected String name; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/FailureType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/FailureType.java new file mode 100644 index 0000000000..d444591771 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/FailureType.java @@ -0,0 +1,129 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for failureType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="failureType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}message"/>
+ *         <element ref="{}stack-trace"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "failureType", propOrder = { + "message", + "stackTrace" +}) +public class FailureType { + + @XmlElement(required = true) + protected String message; + @XmlElement(name = "stack-trace", required = true) + protected String stackTrace; + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + + /** + * Gets the value of the stackTrace property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStackTrace() { + return stackTrace; + } + + /** + * Sets the value of the stackTrace property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStackTrace(String value) { + this.stackTrace = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java new file mode 100644 index 0000000000..29f23ed2bf --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/NUnitReportParserImpl.java @@ -0,0 +1,306 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import java.io.InputStream; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.util.ParserUtil; +import com.microfocus.application.automation.tools.results.parser.util.TimeUtil; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +public class NUnitReportParserImpl implements ReportParser { + + public List parseTestSets(InputStream reportInputStream, + String testingFramework, String testingTool) throws ReportParseException { + + try { + return parseTestSetFromNUnitReport(reportInputStream, testingFramework, testingTool); + } catch (Throwable e) { + throw new ReportParseException(); + } + } + + private ResultType parseFromNUnitReport(InputStream reportInputStream) throws JAXBException { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(NUnitReportParserImpl.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(ResultType.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + return (ResultType)unmarshaller.unmarshal(reportInputStream); + } + + private AlmTest createExternalTestForNUnitReport(TestCaseType testcase, String testingFramework, String testingTool) { + + String temp = testcase.getName(); + String methodName = ""; + String className = ""; + int indexMethod = temp.lastIndexOf("."); + if(indexMethod >= 0) { + methodName = temp.substring(indexMethod+1); + className = temp.substring(0, indexMethod); + } + return ParserUtil.createExternalTest(className, methodName, testingFramework, testingTool); + } + + private void createTestSetAndTest(TestSuiteType testSuite, + String uplevelSuiteName, + String execDate, + String execTime, + List testsets, + String testingFramework, + String testingTool) { + ResultsType resultsOfSuite = testSuite.getResults(); + List testcases = resultsOfSuite.getTestCase(); + List testSuites = resultsOfSuite.getTestSuite(); + + + String currentSuiteName = testSuite.getName(); + int index = currentSuiteName.lastIndexOf("\\"); + if(index >=0 ) { + currentSuiteName = currentSuiteName.substring(index+1); + } + + String testsetName = currentSuiteName; + + if(uplevelSuiteName!=null && uplevelSuiteName.length() >0) { + testsetName = uplevelSuiteName+"_"+currentSuiteName; + } + + if(testcases != null && testcases.size() >0) { + AlmTestSet testSet = new AlmTestSetImpl(); + testSet.setFieldValue( AlmTestSet.TESTSET_NAME,testsetName ); + testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); + testsets.add(testSet); + + for(TestCaseType testcase: testcases) { + AlmTestInstance testInstance = new AlmTestInstanceImpl(); + testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); + testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); + + AlmTest test = createExternalTestForNUnitReport( testcase, testingFramework, testingTool); + testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); + + String execDateTime = ""; + if(execDate != null && execTime != null){ + execDateTime = execDate +" " +execTime; + } + AlmRun run = ParserUtil.createRun(getRunStatus(testcase), + execDateTime, + String.valueOf(testcase.getTime()), + getRunDetail(testcase)); + testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); + } + } + + for(TestSuiteType s: testSuites){ + createTestSetAndTest(s, testsetName, execDate, execTime, testsets, testingFramework, testingTool); + } + } + + private Date getDate( int dateFormat, String dateStr) { + + DateFormat df = DateFormat.getDateInstance(dateFormat); + Date date = null; + try { + date = df.parse(dateStr); + return date; + } catch( Exception e) { + + } + return null; + } + + private Date getTime( int timeFormat, String dateStr) { + + DateFormat df = DateFormat.getTimeInstance(timeFormat); + Date date = null; + try { + date = df.parse(dateStr); + return date; + } catch( Exception e) { + + } + return null; + } + private static String supportedDateFormat [] = { + "yyyy-MM-dd", + "yyyy/MM/dd" + }; + private static String supportedTimeFormat [] = { + "HH:mm:ss", + "hh:mm:ss" + }; + private Date getDateBySupportedDateFormat(String dateStr) { + + for(String format : supportedDateFormat) { + try { + Date date = TimeUtil.getDateFormatter(format).parse(dateStr); + return date; + }catch (Exception e) { + + } + } + return null; + } + + private Date getTimeBySupportedTimeFormat(String timeStr) { + + for(String format : supportedTimeFormat) { + try { + Date date = TimeUtil.getDateFormatter(format).parse(timeStr); + return date; + }catch (Exception e) { + + } + } + return null; + } + + private String convertDateString(String dateStr) { + Date date = null; + date = getDate(DateFormat.LONG, dateStr); + if(date == null) { + date = getDate(DateFormat.MEDIUM, dateStr); + } + + if(date == null) { + date = getDate(DateFormat.SHORT, dateStr); + } + + if(date == null) { + date = getDate(DateFormat.FULL, dateStr); + } + + if(date == null) { + date = getDateBySupportedDateFormat(dateStr); + } + + if(date != null) { + return TimeUtil.getDateFormatter().format(date); + } else { + return null; + } + } + + private String convertTimeString(String timeStr) { + Date time = null; + time = getTime(DateFormat.LONG, timeStr); + + if(time == null) { + time = getTime(DateFormat.MEDIUM, timeStr); + } + + if(time == null) { + time = getTime(DateFormat.SHORT, timeStr); + } + + if(time == null) { + time = getTime(DateFormat.FULL, timeStr); + } + + if(time == null) { + time = getTimeBySupportedTimeFormat(timeStr); + } + + if(time != null) { + return TimeUtil.getTimeFormatter().format(time); + } else { + return null; + } + } + + + private ArrayList parseTestSetFromNUnitReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { + + ResultType results = parseFromNUnitReport(reportInputStream); + + TestSuiteType testSuite = results.getTestSuite(); + String dateStr = results.getDate(); + String timeStr = results.getTime(); + String convertedDate = convertDateString(dateStr); + String convertedTime = convertTimeString(timeStr); + + if(convertedDate == null || convertedTime == null) { + Date executeDate = new Date(System.currentTimeMillis()); + convertedDate = TimeUtil.dateToString(executeDate); + convertedTime = TimeUtil.timeToString(executeDate); + } + + ArrayList testSets = new ArrayList(); + createTestSetAndTest(testSuite, "", convertedDate, convertedTime, testSets, testingFramework, testingTool); + return testSets; + } + + private String getRunStatus(TestCaseType testcase) { + String executed = testcase.getExecuted(); + if("True".equalsIgnoreCase(executed)) { + String success = testcase.getSuccess(); + + if("True".equalsIgnoreCase(success)) { + return IAlmConsts.IStatuses.PASSED.value(); + } else { + return IAlmConsts.IStatuses.FAILED.value(); + } + } else { + return IAlmConsts.IStatuses.NO_RUN.value(); + } + } + + private String getRunDetail(TestCaseType testcase){ + String detail = ParserUtil.marshallerObject(TestCaseType.class, testcase); + return Base64Encoder.encode(detail.getBytes()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ObjectFactory.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ObjectFactory.java new file mode 100644 index 0000000000..e981f4ea56 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ObjectFactory.java @@ -0,0 +1,168 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the generated package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _Message_QNAME = new QName("", "message"); + private final static QName _TestResults_QNAME = new QName("", "test-results"); + private final static QName _StackTrace_QNAME = new QName("", "stack-trace"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link ResultType } + * + */ + public ResultType createResultType() { + return new ResultType(); + } + + /** + * Create an instance of {@link FailureType } + * + */ + public FailureType createFailureType() { + return new FailureType(); + } + + /** + * Create an instance of {@link TestSuiteType } + * + */ + public TestSuiteType createTestSuiteType() { + return new TestSuiteType(); + } + + /** + * Create an instance of {@link ReasonType } + * + */ + public ReasonType createReasonType() { + return new ReasonType(); + } + + /** + * Create an instance of {@link TestCaseType } + * + */ + public TestCaseType createTestCaseType() { + return new TestCaseType(); + } + + /** + * Create an instance of {@link CategoriesType } + * + */ + public CategoriesType createCategoriesType() { + return new CategoriesType(); + } + + /** + * Create an instance of {@link CategoryType } + * + */ + public CategoryType createCategoryType() { + return new CategoryType(); + } + + /** + * Create an instance of {@link ResultsType } + * + */ + public ResultsType createResultsType() { + return new ResultsType(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "message") + public JAXBElement createMessage(String value) { + return new JAXBElement(_Message_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ResultType }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "test-results") + public JAXBElement createTestResults(ResultType value) { + return new JAXBElement(_TestResults_QNAME, ResultType.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stack-trace") + public JAXBElement createStackTrace(String value) { + return new JAXBElement(_StackTrace_QNAME, String.class, null, value); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ReasonType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ReasonType.java new file mode 100644 index 0000000000..1ababfa492 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ReasonType.java @@ -0,0 +1,101 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for reasonType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="reasonType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}message"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "reasonType", propOrder = { + "message" +}) +public class ReasonType { + + @XmlElement(required = true) + protected String message; + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultType.java new file mode 100644 index 0000000000..a30634ae9e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultType.java @@ -0,0 +1,267 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import java.math.BigDecimal; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for resultType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="resultType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="test-suite" type="{}test-suiteType"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="total" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
+ *       <attribute name="failures" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
+ *       <attribute name="not-run" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
+ *       <attribute name="date" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlRootElement(name = "test-results") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "resultType", propOrder = { + "testSuite" +}) +public class ResultType { + + @XmlElement(name = "test-suite", required = true) + protected TestSuiteType testSuite; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "total", required = true) + protected BigDecimal total; + @XmlAttribute(name = "failures", required = true) + protected BigDecimal failures; + @XmlAttribute(name = "not-run", required = true) + protected BigDecimal notRun; + @XmlAttribute(name = "date", required = true) + protected String date; + @XmlAttribute(name = "time", required = true) + protected String time; + + /** + * Gets the value of the testSuite property. + * + * @return + * possible object is + * {@link TestSuiteType } + * + */ + public TestSuiteType getTestSuite() { + return testSuite; + } + + /** + * Sets the value of the testSuite property. + * + * @param value + * allowed object is + * {@link TestSuiteType } + * + */ + public void setTestSuite(TestSuiteType value) { + this.testSuite = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the total property. + * + * @return + * possible object is + * {@link BigDecimal } + * + */ + public BigDecimal getTotal() { + return total; + } + + /** + * Sets the value of the total property. + * + * @param value + * allowed object is + * {@link BigDecimal } + * + */ + public void setTotal(BigDecimal value) { + this.total = value; + } + + /** + * Gets the value of the failures property. + * + * @return + * possible object is + * {@link BigDecimal } + * + */ + public BigDecimal getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is + * {@link BigDecimal } + * + */ + public void setFailures(BigDecimal value) { + this.failures = value; + } + + /** + * Gets the value of the notRun property. + * + * @return + * possible object is + * {@link BigDecimal } + * + */ + public BigDecimal getNotRun() { + return notRun; + } + + /** + * Sets the value of the notRun property. + * + * @param value + * allowed object is + * {@link BigDecimal } + * + */ + public void setNotRun(BigDecimal value) { + this.notRun = value; + } + + /** + * Gets the value of the date property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDate() { + return date; + } + + /** + * Sets the value of the date property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDate(String value) { + this.date = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultsType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultsType.java new file mode 100644 index 0000000000..1b26f0aa26 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/ResultsType.java @@ -0,0 +1,141 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for resultsType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="resultsType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice>
+ *         <element name="test-suite" type="{}test-suiteType" maxOccurs="unbounded"/>
+ *         <element name="test-case" type="{}test-caseType" maxOccurs="unbounded" minOccurs="0"/>
+ *       </choice>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "resultsType", propOrder = { + "testSuite", + "testCase" +}) +public class ResultsType { + + @XmlElement(name = "test-suite") + protected List testSuite; + @XmlElement(name = "test-case") + protected List testCase; + + /** + * Gets the value of the testSuite property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testSuite property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestSuite().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link TestSuiteType } + * + * + */ + public List getTestSuite() { + if (testSuite == null) { + testSuite = new ArrayList(); + } + return this.testSuite; + } + + /** + * Gets the value of the testCase property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testCase property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestCase().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link TestCaseType } + * + * + */ + public List getTestCase() { + if (testCase == null) { + testCase = new ArrayList(); + } + return this.testCase; + } + +} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestCaseType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestCaseType.java similarity index 77% rename from src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestCaseType.java rename to src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestCaseType.java index e311d6fcf8..e4da9ff77b 100644 --- a/src/main/java/com/hp/application/automation/tools/results/parser/nunit/TestCaseType.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestCaseType.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 // See http://java.sun.com/xml/jaxb @@ -6,7 +38,7 @@ // -package com.hp.application.automation.tools.results.parser.nunit; +package com.microfocus.application.automation.tools.results.parser.nunit; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestSuiteType.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestSuiteType.java new file mode 100644 index 0000000000..72e6dcc51b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit/TestSuiteType.java @@ -0,0 +1,264 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:45:43 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.nunit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for test-suiteType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="test-suiteType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="categories" type="{}categoriesType" minOccurs="0"/>
+ *         <element name="results" type="{}resultsType"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="description" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="success" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="asserts" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "test-suiteType", propOrder = { + "categories", + "results" +}) +public class TestSuiteType { + + protected CategoriesType categories; + @XmlElement(required = true) + protected ResultsType results; + @XmlAttribute(name = "name", required = true) + protected String name; + @XmlAttribute(name = "description") + protected String description; + @XmlAttribute(name = "success", required = true) + protected String success; + @XmlAttribute(name = "time", required = true) + protected String time; + @XmlAttribute(name = "asserts") + protected String asserts; + + /** + * Gets the value of the categories property. + * + * @return + * possible object is + * {@link CategoriesType } + * + */ + public CategoriesType getCategories() { + return categories; + } + + /** + * Sets the value of the categories property. + * + * @param value + * allowed object is + * {@link CategoriesType } + * + */ + public void setCategories(CategoriesType value) { + this.categories = value; + } + + /** + * Gets the value of the results property. + * + * @return + * possible object is + * {@link ResultsType } + * + */ + public ResultsType getResults() { + return results; + } + + /** + * Sets the value of the results property. + * + * @param value + * allowed object is + * {@link ResultsType } + * + */ + public void setResults(ResultsType value) { + this.results = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the description property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDescription() { + return description; + } + + /** + * Sets the value of the description property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDescription(String value) { + this.description = value; + } + + /** + * Gets the value of the success property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSuccess() { + return success; + } + + /** + * Sets the value of the success property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSuccess(String value) { + this.success = value; + } + + /** + * Gets the value of the time property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the asserts property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAsserts() { + return asserts; + } + + /** + * Sets the value of the asserts property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAsserts(String value) { + this.asserts = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit3/NUnit3ReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit3/NUnit3ReportParserImpl.java new file mode 100644 index 0000000000..9a1eff595f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/nunit3/NUnit3ReportParserImpl.java @@ -0,0 +1,109 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.nunit3; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.antjunit.AntJUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import hudson.FilePath; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +/** + * NUnit3 Report Parser implement. + * It will convert Nunit 3 report to Junit report with xsl then start AntJunit parser. + */ +public class NUnit3ReportParserImpl implements ReportParser { + + private static final String TEMP_JUNIT_FILE_PREFIX = "temp-junit"; + private static final String TEMP_JUNIT_FILE_SUFFIX = ".xml"; + private static final String NUNIT_TO_JUNIT_XSLFILE = "nunit-to-junit.xsl"; + + private FilePath workspace; + + public NUnit3ReportParserImpl(FilePath workspace) { + this.workspace = workspace; + } + + @Override + public List parseTestSets(InputStream reportInputStream, String testingFramework, String testingTool) + throws ReportParseException { + + // Use the xsl to convert the nunit3 and nunit to junit and then parse with junit logic. + // This can be extended to cover all kinds of result format. + // When new format comes, only need to provide a xsl, no need to change any code. + + FileOutputStream fileOutputStream = null; + try { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer nunitTransformer = transformerFactory.newTransformer( + new StreamSource(this.getClass().getResourceAsStream(NUNIT_TO_JUNIT_XSLFILE))); + File junitTargetFile = new File(workspace.createTempFile(TEMP_JUNIT_FILE_PREFIX, TEMP_JUNIT_FILE_SUFFIX).toURI()); + fileOutputStream = new FileOutputStream(junitTargetFile); + nunitTransformer.transform(new StreamSource(reportInputStream), new StreamResult(fileOutputStream)); + + InputStream in = new FileInputStream(junitTargetFile); + return new AntJUnitReportParserImpl().parseTestSets(in, testingFramework, testingTool); + + } catch (Exception e) { + throw new ReportParseException(e); + + } finally { + try { + if (reportInputStream != null) { + reportInputStream.close(); + } + } catch (IOException e) { + throw new ReportParseException(e); + } + + try { + if (fileOutputStream != null) { + fileOutputStream.close(); + } + } catch (IOException e) { + throw new ReportParseException(e); + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/NewDataSet.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/NewDataSet.java new file mode 100644 index 0000000000..e509c35f56 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/NewDataSet.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:25:36 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.testngxml; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice maxOccurs="unbounded" minOccurs="0">
+ *         <element ref="{}testng-results"/>
+ *       </choice>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "testngResults" +}) +@XmlRootElement(name = "NewDataSet") +public class NewDataSet { + + @XmlElement(name = "testng-results") + protected List testngResults; + + /** + * Gets the value of the testngResults property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the testngResults property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getTestngResults().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link TestngResults } + * + * + */ + public List getTestngResults() { + if (testngResults == null) { + testngResults = new ArrayList(); + } + return this.testngResults; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/ObjectFactory.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/ObjectFactory.java new file mode 100644 index 0000000000..53568fdbfc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/ObjectFactory.java @@ -0,0 +1,151 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2015.05.13 at 09:25:36 AM CST +// + + +package com.microfocus.application.automation.tools.results.parser.testngxml; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the generated package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link TestngResults } + * + */ + public TestngResults createTestngResults() { + return new TestngResults(); + } + + /** + * Create an instance of {@link TestngResults.Suite } + * + */ + public TestngResults.Suite createTestngResultsSuite() { + return new TestngResults.Suite(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Test } + * + */ + public TestngResults.Suite.Test createTestngResultsSuiteTest() { + return new TestngResults.Suite.Test(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Test.Class } + * + */ + public TestngResults.Suite.Test.Class createTestngResultsSuiteTestClass() { + return new TestngResults.Suite.Test.Class(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Test.Class.TestMethod } + * + */ + public TestngResults.Suite.Test.Class.TestMethod createTestngResultsSuiteTestClassTestMethod() { + return new TestngResults.Suite.Test.Class.TestMethod(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Groups } + * + */ + public TestngResults.Suite.Groups createTestngResultsSuiteGroups() { + return new TestngResults.Suite.Groups(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Groups.Group } + * + */ + public TestngResults.Suite.Groups.Group createTestngResultsSuiteGroupsGroup() { + return new TestngResults.Suite.Groups.Group(); + } + + /** + * Create an instance of {@link NewDataSet } + * + */ + public NewDataSet createNewDataSet() { + return new NewDataSet(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Test.Class.TestMethod.Exception } + * + */ + public TestngResults.Suite.Test.Class.TestMethod.Exception createTestngResultsSuiteTestClassTestMethodException() { + return new TestngResults.Suite.Test.Class.TestMethod.Exception(); + } + + /** + * Create an instance of {@link TestngResults.Suite.Groups.Group.Method } + * + */ + public TestngResults.Suite.Groups.Group.Method createTestngResultsSuiteGroupsGroupMethod() { + return new TestngResults.Suite.Groups.Group.Method(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java new file mode 100644 index 0000000000..ac1ee6c49f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestNGXmlReportParserImpl.java @@ -0,0 +1,145 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.testngxml; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParseException; +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.parser.testngxml.TestngResults.Suite; +import com.microfocus.application.automation.tools.results.parser.testngxml.TestngResults.Suite.Test; +import com.microfocus.application.automation.tools.results.parser.testngxml.TestngResults.Suite.Test.Class.TestMethod; +import com.microfocus.application.automation.tools.results.parser.util.ParserUtil; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; + +public class TestNGXmlReportParserImpl implements ReportParser { + + public List parseTestSets(InputStream reportInputStream, + String testingFramework, String testingTool) throws ReportParseException { + + try { + return parseTestSetFromTestNGXmlReport(reportInputStream, testingFramework, testingTool); + } catch (Throwable e) { + + throw new ReportParseException(); + } + } + + private TestngResults parseFromTestNGXmlReport(InputStream reportInputStream) throws JAXBException { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(TestNGXmlReportParserImpl.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(TestngResults.class); + } finally { + t.setContextClassLoader(orig); + } + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + return (TestngResults)unmarshaller.unmarshal(reportInputStream); + } + + private AlmTest createExternalTestForTestNGXmlReport(String className, String methodName, String testingFramework, String testingTool) { + + return ParserUtil.createExternalTest(className, methodName, testingFramework, testingTool); + } + + private ArrayList parseTestSetFromTestNGXmlReport(InputStream reportInputStream, String testingFramework, String testingTool) throws JAXBException { + + TestngResults testngresults = parseFromTestNGXmlReport(reportInputStream); + + ArrayList testSets = new ArrayList(); + for( Suite suite : testngresults.suite) { + AlmTestSet testSet = new AlmTestSetImpl(); + testSet.setFieldValue( AlmTestSet.TESTSET_NAME, suite.getName()); + testSet.setFieldValue( AlmTestSet.TESTSET_SUB_TYPE_ID, EXTERNAL_TEST_SET_TYPE_ID); + testSets.add(testSet); + + + for (Test t: suite.getTest()) { + + for(TestngResults.Suite.Test.Class c: t.getClazz() ) { + + for(TestMethod tm : c.getTestMethod()) { + AlmTestInstance testInstance = new AlmTestInstanceImpl(); + testInstance.setFieldValue( AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID, EXTERNAL_TEST_INSTANCE_TYPE_ID); + testSet.addRelatedEntity(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION, testInstance); + + AlmTest test = createExternalTestForTestNGXmlReport( c.getName(), tm.getName(), testingFramework, testingTool); + testInstance.addRelatedEntity(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION, test); + + AlmRun run = ParserUtil.createRun(getRunStatus(tm), tm.getStartedAt(), String.valueOf(tm.getDurationMs()), getRunDetail(tm)); + testInstance.addRelatedEntity(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION, run); + } + } + } + } + return testSets; + } + + private String getRunStatus(TestMethod tm) { + String status = tm.getStatus(); + if(status != null && status.length()>0){ + status = status.trim(); + + if("PASS".equalsIgnoreCase(status)) { + return IAlmConsts.IStatuses.PASSED.value(); + } else if ("FAIL".equalsIgnoreCase(status)) { + return IAlmConsts.IStatuses.FAILED.value(); + } else { + return IAlmConsts.IStatuses.NO_RUN.value(); + } + } else { + return IAlmConsts.IStatuses.NO_RUN.value(); + } + } + + private String getRunDetail(TestMethod tm){ + String detail = ParserUtil.marshallerObject(TestMethod.class, tm); + return Base64Encoder.encode(detail.getBytes()); + } +} diff --git a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestngResults.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestngResults.java similarity index 97% rename from src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestngResults.java rename to src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestngResults.java index b36b57751f..45c47071c1 100644 --- a/src/main/java/com/hp/application/automation/tools/results/parser/testngxml/TestngResults.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/testngxml/TestngResults.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 // See http://java.sun.com/xml/jaxb @@ -6,7 +38,7 @@ // -package com.hp.application.automation.tools.results.parser.testngxml; +package com.microfocus.application.automation.tools.results.parser.testngxml; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/util/ParserUtil.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/util/ParserUtil.java new file mode 100644 index 0000000000..30cf59aedf --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/util/ParserUtil.java @@ -0,0 +1,161 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.util; + +import java.io.StringWriter; +import java.util.Date; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import com.microfocus.application.automation.tools.results.parser.ReportParser; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRunImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestImpl; + +public class ParserUtil { + public static char nameConnector = '_'; + public static char[] testNameInvalidChars = new char[] { '\\', '/', ':', '"', '?', '\'', '<', '>', '|', '*', '%' }; + public static char[] testSetNameInvalidChars = new char[] { '\\', '^', ',', '"', '*' }; + + public static String repaceInvalidChars(char[] invalidChars, char newChar, String source) + { + StringBuffer temp = new StringBuffer(source); + + for (int i=0; i= 0) { + packageName = temp.substring(0, indexDot); + className = temp.substring(indexDot+1); + } + + String testName = className + "_" + methodName; + test.setFieldValue( AlmTest.TS_UT_PACKAGE_NAME, packageName); + test.setFieldValue( AlmTest.TEST_NAME, testName ); + test.setFieldValue( AlmTest.TEST_TYPE, ReportParser.EXTERNAL_TEST_TYPE); + test.setFieldValue( AlmTest.TS_TESTING_FRAMEWORK, testingFramework); + test.setFieldValue( AlmTest.TS_TESTING_TOOL, testingTool); + test.setFieldValue( AlmTest.TS_UT_CLASS_NAME, className); + test.setFieldValue( AlmTest.TS_UT_METHOD_NAME, methodName); + return test; + } + + public static String marshallerObject(Class c, Object o){ + String s = ""; + try { + JAXBContext jaxbContext; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(ParserUtil.class.getClassLoader()); + try { + jaxbContext = JAXBContext.newInstance(c); + } finally { + t.setContextClassLoader(orig); + } + + Marshaller marshaller = jaxbContext.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_ENCODING,"utf-8"); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); + + StringWriter baos = new StringWriter(); + marshaller.marshal(o, baos); + s += baos.toString(); + }catch (Exception e) { + } + return s; + } + + public static AlmRun createRun(String runStatus, String execDateTime, String duration, String detail) { + AlmRun run = new AlmRunImpl(); + run.setFieldValue( AlmRun.RUN_SUBTYPE_ID, ReportParser.EXTERNAL_RUN_TYPE_ID); + run.setFieldValue( AlmRun.RUN_STATUS, runStatus); + run.setFieldValue( AlmRun.RUN_DETAIL, detail); + Date executeDate; + if(execDateTime != null && execDateTime.length() >0 ) { + execDateTime = execDateTime.replaceAll("T", " "); + executeDate = TimeUtil.stringToDate(execDateTime); + } else { + executeDate = new Date(System.currentTimeMillis()); + } + + run.setFieldValue( AlmRun.RUN_EXECUTION_DATE, + TimeUtil.dateToString(executeDate)); + run.setFieldValue( AlmRun.RUN_EXECUTION_TIME, + TimeUtil.timeToString(executeDate)); + + if(duration != null && duration.length() >0 ) { + Float durationTime = 0.0f; + try { + durationTime = Float.valueOf(duration); + } catch (NumberFormatException e) { + //the exception may be ignored. + } + run.setFieldValue( AlmRun.RUN_DURATION, String.valueOf(durationTime.intValue())); + } else { + run.setFieldValue( AlmRun.RUN_DURATION, String.valueOf(0) ); + } + + return run; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/parser/util/TimeUtil.java b/src/main/java/com/microfocus/application/automation/tools/results/parser/util/TimeUtil.java new file mode 100644 index 0000000000..4ee811e5f3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/parser/util/TimeUtil.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser.util; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class TimeUtil { + public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_FORMAT = "yyyy-MM-dd"; // "MM/dd/yyyy"); + public static final String TIME_FORMAT = "HH:mm:ss"; + + public static SimpleDateFormat getDateFormatter() { + return new SimpleDateFormat(DATE_FORMAT); + } + + public static SimpleDateFormat getDateFormatter(String format) { + return new SimpleDateFormat(format); + } + + public static String dateToString(java.util.Date date) { + try { + return ((date == null) ? "" : getDateFormatter().format(date)); + } catch (Exception e) { + return ""; + } + } + + public static java.util.Date stringToDate(String source) { + TimeZone localTimeZone = getDateFormatter().getTimeZone(); + return stringToDate(source, localTimeZone); + } + + public static DateFormat getFullTimestampFormatter(Locale locale) { + DateFormat dateFormat = + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale); + + String localeString = locale.toString(); + if (localeString.equals("zh_SG")) { + return new SimpleDateFormat("dd/MM/yyyy a hh:mm"); + } else if (localeString.equals("ko")) { + return changeDateFormatPattern(dateFormat, "y+\\. *M+\\. *d+", "yyyy-MM-dd"); + } + + // change year format to long format (e.g. 2012) + return changeDateFormatPattern(dateFormat, "y+", "yyyy"); + } + + private static DateFormat changeDateFormatPattern( + final DateFormat dateFormat, + String regex, + String replacement) { + if (dateFormat instanceof SimpleDateFormat) { + SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat; + + String pattern = simpleDateFormat.toPattern().replaceAll(regex, replacement); + simpleDateFormat.applyPattern(pattern); + + return simpleDateFormat; + } + return dateFormat; + } + + public static SimpleDateFormat getFullTimestampFormatter() { + return new SimpleDateFormat(DATE_TIME_FORMAT); // m_fullTimestampFormatter; + } + + + public static SimpleDateFormat getTimeFormatter() { + return new SimpleDateFormat(TIME_FORMAT); // m_timeFormatter; + } + + public static java.util.Date stringToDate(String source, TimeZone timeZone) { + // check input + if (source == null) { + throw new IllegalArgumentException("null argument not allowed"); + } + + java.util.Date result; + try { + boolean hasColon = (source.indexOf(':') != -1); + boolean hasMinusSign = (source.indexOf('-') != -1); + int length = source.length(); + + // datetime format + if ((length == DATE_TIME_FORMAT.length()) + || (hasColon && hasMinusSign)) { + SimpleDateFormat fullTimestampFormatter = + getFullTimestampFormatter(); + fullTimestampFormatter.setTimeZone(timeZone); + result = fullTimestampFormatter.parse(source); + // date format + } else if ((source.length() == DATE_FORMAT.length()) + || (hasMinusSign)) { + SimpleDateFormat dateFormatter = getDateFormatter(); + dateFormatter.setTimeZone(timeZone); + result = dateFormatter.parse(source); + // time format + } else if ((source.length() == TIME_FORMAT.length()) || (hasColon)) { + SimpleDateFormat timeFormatter = getTimeFormatter(); + timeFormatter.setTimeZone(timeZone); + result = timeFormatter.parse(source); + } else { + throw new IllegalArgumentException("unsupported date format: \"" + source + "\""); + } + } catch (java.text.ParseException e) { + return new Date(); + } + + return result; + } + + public static String timeToString(java.util.Date date) { + try { + return ((date == null) ? "" : getTimeFormatter().format(date)); + } catch (Exception e) { + return ""; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/package-info.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/package-info.java new file mode 100644 index 0000000000..f361175d77 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/package-info.java @@ -0,0 +1,36 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +/** + * Created by kazaky on 07/07/2016. + */ +package com.microfocus.application.automation.tools.results.projectparser; \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java new file mode 100644 index 0000000000..d51945ba3d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/AvgTransactionResponseTime.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * Created by kazaky on 07/07/2016. + */ +public class AvgTransactionResponseTime extends TimeRangeResult { + + public AvgTransactionResponseTime() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + protected String name = ""; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/GoalResult.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/GoalResult.java new file mode 100644 index 0000000000..e0b32cde52 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/GoalResult.java @@ -0,0 +1,81 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * Created by kazaky on 07/07/2016. + */ + + +public abstract class GoalResult implements LrTest{ + + public SLA_STATUS getStatus() { + return _status; + } + + public void setStatus(SLA_STATUS _status) { + this._status = _status; + } + + public SLA_GOAL getSlaGoal() { + return _slaGoal; + } + + public void setSlaGoal(SLA_GOAL _slaGoal) { + this._slaGoal = _slaGoal; + } + + public double getDuration() { + return _duration; +} + + public void setDuration(double _duration) { + this._duration = _duration; + } + + private SLA_GOAL _slaGoal; + private SLA_STATUS _status; + + public String getFullName() { + return _fullName; + } + + public void setFullName(String _fullName) { + this._fullName = _fullName; + } + + private String _fullName; + private double _duration; + + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java new file mode 100644 index 0000000000..44e31419ae --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/JobLrScenarioResult.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +import java.util.ArrayList; +import java.util.Map; +import java.util.TreeMap; + + +/** + * Holds information on the SLA's of one scenario (per job / run / build) + */ +public class JobLrScenarioResult extends LrScenario { + public static final int DEFAULT_CONNECTION_MAX = -1; + public static final int DEFAULT_SCENARIO_DURATION = -1; + public ArrayList scenarioSlaResults; + public Map vUserSum; + public TreeMap transactionSum; + public TreeMap> transactionData; + private int connectionMax; + private long scenarioDuration; + + public JobLrScenarioResult(String scenarioName) { + super.setScenrioName(scenarioName); + connectionMax = DEFAULT_CONNECTION_MAX; + scenarioDuration = DEFAULT_SCENARIO_DURATION; + vUserSum = new TreeMap(); + transactionSum = new TreeMap(); + transactionData = new TreeMap<>(); + scenarioSlaResults = new ArrayList(0); + } + + public long getScenarioDuration() { + return scenarioDuration; + } + + public void setScenarioDuration(long scenarioDuration) { + this.scenarioDuration = scenarioDuration; + } + + public int getConnectionMax() { + return connectionMax; + } + + public void setConnectionMax(int connectionMax) { + this.connectionMax = connectionMax; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrJobResults.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrJobResults.java new file mode 100644 index 0000000000..16176ef3ef --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrJobResults.java @@ -0,0 +1,60 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +import java.util.HashMap; +import java.util.Map; + + +public class LrJobResults extends LrRunResults implements LrTest { + + private Map _scenarioResults; + + public LrJobResults() { + _scenarioResults = new HashMap(); + } + + public Map getLrScenarioResults() { + return _scenarioResults; + } + + public JobLrScenarioResult addScenario(JobLrScenarioResult scenario) { + JobLrScenarioResult jobLrScenarioResult = _scenarioResults.put(scenario.getScenarioName(), scenario); + if (jobLrScenarioResult != null) { + _totalErrors += scenario.getTotalErrors(); + _totalFailures += scenario.getTotalFailures(); + _time += getTime(); + } + return jobLrScenarioResult; + } +} diff --git a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java similarity index 79% rename from src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java rename to src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java index d9e5ec6610..895a1688e5 100644 --- a/src/main/java/com/hp/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrProjectScenarioResults.java @@ -1,31 +1,38 @@ /* + * 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 (c) 2016 Hewlett-Packard Development Company, L.P. + * Copyright 2012-2023 Open Text * - * 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 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. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * 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. * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.results.projectparser.performance; +package com.microfocus.application.automation.tools.results.projectparser.performance; import java.util.HashSet; -import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrRunResults.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrRunResults.java new file mode 100644 index 0000000000..90a66df930 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrRunResults.java @@ -0,0 +1,118 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +public class LrRunResults { + protected int _totalFailures; + protected int _totalErrors; + protected double _time; + private int TotalNoData; + private int TotalPassed; + private int TestCount; + + public LrRunResults() { + _totalFailures = 0; + _totalErrors = 0; + _time = 0; + TotalNoData = 0; + TotalPassed = 0; + TestCount = 0; + } + + public int getTotalFailures() { + return _totalFailures; + } + + public void setTotalFailures(int totalFailures) { + this._totalFailures = totalFailures; + } + + public void incTotalErrors() { + _totalErrors++; + } + + public void incTotalNoData() { + TotalNoData++; + } + + public int getTotalErrors() { + return _totalErrors; + } + + public void setTotalErrors(int totalErrors) { + this._totalErrors = totalErrors; + } + + public void updateStatus(LrTest.SLA_STATUS slaStatus) { + switch (slaStatus) { + case Failed: + incTotalFailures(); + incTotalTests(); + break; + case Passed: + incTotalPassed(); + incTotalTests(); + break; + default: + break; + } + } + + public void incTotalFailures() { + _totalFailures++; + } + + public void incTotalPassed() { + TotalPassed++; + } + + public void incTotalTests() { + TestCount++; + } + + public int getTotalNoData() { + return TotalNoData; + } + + public int getTestCount() { + return TestCount; + } + + public double getTime() { + return _time; + } + + public void setTime(double time) { + this._time = time; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrScenario.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrScenario.java new file mode 100644 index 0000000000..aa2c7040f7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrScenario.java @@ -0,0 +1,74 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * The type Lr scenario. + */ +public abstract class LrScenario extends LrJobResults { + private String _scenrioName; + + /** + * Instantiates a new Lr scenario. + */ + public LrScenario() { + this(""); + } + + /** + * Instantiates a new Lr scenario. + * + * @param _scenrioName the scenrio name + */ + public LrScenario(String _scenrioName) { + this._scenrioName = _scenrioName; + } + + /** + * Gets scenario name. + * + * @return the scenario name + */ + public String getScenarioName() { + return _scenrioName; + } + + /** + * Sets scenrio name. + * + * @param scenrioName the scenrio name + */ + void setScenrioName(String scenrioName) { + _scenrioName = scenrioName; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrTest.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrTest.java new file mode 100644 index 0000000000..52e81bbe54 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/LrTest.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * Created by kazaky on 08/07/2016. + */ +public interface LrTest { + public enum SLA_STATUS { + Failed, Passed, NoData, bad; + + public static SLA_STATUS checkStatus(String status) { + if ((status.compareTo(Failed.toString()) == 0)) { + return Failed; + } else if ((status.compareTo(Passed.toString()) == 0)) { + return Passed; + } else if ((status.compareTo(NoData.toString()) == 0)) { + return NoData; + } + return bad; + } + } + + enum SLA_GOAL { + AverageThroughput, TotalThroughput, AverageHitsPerSecond, TotalHits, + ErrorsPerSecond, PercentileTRT, AverageTRT, Bad; + + public static SLA_GOAL checkGoal(String status) { + if ((status.compareTo(AverageThroughput.toString()) == 0)) { + return AverageThroughput; + } else if ((status.compareTo(TotalThroughput.toString()) == 0)) { + return TotalThroughput; + } else if ((status.compareTo(AverageHitsPerSecond.toString()) == 0)) { + return AverageHitsPerSecond; + } else if ((status.compareTo(TotalHits.toString()) == 0)) { + return TotalHits; + } else if ((status.compareTo(ErrorsPerSecond.toString()) == 0)) { + return ErrorsPerSecond; + } else if ((status.compareTo(AverageTRT.toString()) == 0)) { + return AverageTRT; + } else if ((status.compareTo(PercentileTRT.toString()) == 0)) { + return PercentileTRT; + } + return Bad; + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java new file mode 100644 index 0000000000..20a86f26db --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/PercentileTransactionWholeRun.java @@ -0,0 +1,65 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * Created by kazaky on 10/07/2016. + */ +public class PercentileTransactionWholeRun extends WholeRunResult { + + private String name; + private double _precentage; + + public PercentileTransactionWholeRun() { + _precentage = 0.0; + name = ""; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrecentage() { + return _precentage; + } + + public void setPrecentage(double precentage) { + this._precentage = precentage; + } + + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/ProjectLrResults.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/ProjectLrResults.java new file mode 100644 index 0000000000..853968323f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/ProjectLrResults.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +import java.util.SortedMap; +import java.util.TreeMap; + + +public class ProjectLrResults extends LrRunResults { + private SortedMap _scenarioResults; + + public ProjectLrResults() { + _scenarioResults = new TreeMap(); + } + + public SortedMap getScenarioResults() { + return _scenarioResults; + } + + public LrProjectScenarioResults addScenario(LrProjectScenarioResults scenario) { + LrProjectScenarioResults jobLrScenarioResult = _scenarioResults.put(scenario.getScenarioName(), scenario); + if (jobLrScenarioResult != null) { + _totalErrors += scenario.getTotalErrors(); + _totalFailures += scenario.getTotalFailures(); + _time += getTime(); + } + return jobLrScenarioResult; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRange.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRange.java new file mode 100644 index 0000000000..5956a9a5e0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRange.java @@ -0,0 +1,179 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * The type Time range. + */ +public class TimeRange { + + private LrTest.SLA_STATUS slaStatus = LrTest.SLA_STATUS.bad; + private double _actualValue; + private double _goalValue; + private int loadAmount; + private double startTime; + private double endTime; + + /** + * Instantiates a new Time range. + * + * @param _actualValue the actual value + * @param _goalValue the goal value + * @param slaStatus the sla status + * @param loadAmount the load amount + * @param startTime the start time + * @param endTime the end time + */ + public TimeRange(double _actualValue, double _goalValue, LrTest.SLA_STATUS slaStatus, int loadAmount, + double startTime, double endTime) { + this._actualValue = _actualValue; + this._goalValue = _goalValue; + this.slaStatus = slaStatus; + this.loadAmount = 0; + this.loadAmount = loadAmount; + this.startTime = 0; + this.startTime = startTime; + this.endTime = 0; + this.endTime = endTime; + } + + /** + * Gets sla status. + * + * @return the sla status + */ + public LrTest.SLA_STATUS getSlaStatus() { + return slaStatus; + } + + /** + * Sets sla status. + * + * @param slaStatus the sla status + */ + public void setSlaStatus(LrTest.SLA_STATUS slaStatus) { + this.slaStatus = slaStatus; + } + + /** + * Gets actual value. + * + * @return the actual value + */ + public double getActualValue() { + return _actualValue; + } + + /** + * Sets actual value. + * + * @param actualValue the actual value + */ + public void setActualValue(double actualValue) { + this._actualValue = actualValue; + } + + /** + * Gets goal value. + * + * @return the goal value + */ + public double getGoalValue() { + return _goalValue; + } + + /** + * Sets goal value. + * + * @param goalValue the goal value + */ + public void setGoalValue(double goalValue) { + this._goalValue = goalValue; + } + + /** + * Gets load amount. + * + * @return the load amount + */ + public int getLoadAmount() { + return loadAmount; + } + + /** + * Sets load amount. + * + * @param loadAmount the load amount + */ + public void setLoadAmount(int loadAmount) { + this.loadAmount = loadAmount; + } + + /** + * Gets start time. + * + * @return the start time + */ + public double getStartTime() { + return startTime; + } + + /** + * Sets start time. + * + * @param startTime the start time + */ + public void setStartTime(double startTime) { + this.startTime = startTime; + } + + /** + * Gets end time. + * + * @return the end time + */ + public double getEndTime() { + return endTime; + } + + /** + * Sets end time. + * + * @param endTime the end time + */ + public void setEndTime(double endTime) { + this.endTime = endTime; + } + + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRangeResult.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRangeResult.java new file mode 100644 index 0000000000..0d9aa1d5f8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/TimeRangeResult.java @@ -0,0 +1,123 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kazaky on 07/07/2016. + */ +public class TimeRangeResult extends GoalResult implements LrTest { + + + /** + * The Time ranges. + */ + private ArrayList timeRanges; + private double _avgActualValue; + private double _actualValueSum; + private double _goalValue; + private String LoadThrashold; + /** + * Instantiates a new Time range result. + */ + public TimeRangeResult() { + _actualValueSum = 0; + _goalValue = 0; + _avgActualValue = 0; + timeRanges = new ArrayList(0); + } + + public List getTimeRanges() { + return timeRanges; + } + + /** + * Gets actual value avg. + * + * @return the actual value avg + */ + public double getActualValueAvg() { + _avgActualValue = _actualValueSum / timeRanges.size(); + return _avgActualValue; + } + + /** + * Gets goal value. + * + * @return the goal value + */ + public double getGoalValue() { + return _goalValue; + } + + /** + * Sets goal value. + * + * @param goalValue the goal value + */ + public void setGoalValue(double goalValue) { + this._goalValue = goalValue; + } + + /** + * Inc actual value. + * + * @param actualValue the actual value + */ + public void incActualValue(double actualValue) { + this._actualValueSum += actualValue; + } + + /** + * Gets load thrashold. + * + * @return the load thrashold + */ + public String getLoadThrashold() { + return LoadThrashold; + } + + /** + * Sets load thrashold. + * + * @param loadThrashold the load thrashold + * @return the load thrashold + */ + public TimeRangeResult setLoadThrashold(String loadThrashold) { + LoadThrashold = loadThrashold; + return this; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/WholeRunResult.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/WholeRunResult.java new file mode 100644 index 0000000000..e8125b6e4d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/WholeRunResult.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +/** + * Created by kazaky on 07/07/2016. + */ +public class WholeRunResult extends GoalResult { + + private double _actualValue; + private double _goalValue; + + /** + * Instantiates a new Whole run result. + * + * @param _actualValue the actual value + * @param _goalValue the goal value + */ + public WholeRunResult(double _actualValue, double _goalValue) { + this._actualValue = _actualValue; + this._goalValue = _goalValue; + } + + /** + * Instantiates an empty new Whole run result. + */ + public WholeRunResult() { + this(0,0); + } + + /** + * Gets actual value. + * + * @return the actual value + */ + public double getActualValue() { + return _actualValue; + } + + /** + * Sets actual value. + * + * @param actualValue the actual value + */ + public void setActualValue(double actualValue) { + this._actualValue = actualValue; + } + + /** + * Gets goal value. + * + * @return the goal value + */ + public double getGoalValue() { + return _goalValue; + } + + /** + * Sets goal value. + * + * @param goalValue the goal value + */ + public void setGoalValue(double goalValue) { + this._goalValue = goalValue; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/XmlParserUtil.java b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/XmlParserUtil.java new file mode 100644 index 0000000000..da2fd0246b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/projectparser/performance/XmlParserUtil.java @@ -0,0 +1,107 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.projectparser.performance; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import javax.annotation.Nullable; + +/** + * Created by kazaky on 17/10/2016. + */ +public class XmlParserUtil { + + @Nullable + public static Node getNode(String tagName, NodeList nodes) { + for (int x = 0; x < nodes.getLength(); x++) { + Node node = nodes.item(x); + if (node.getNodeName().equalsIgnoreCase(tagName)) { + return node; + } + } + return null; + } + + public static String getNodeValue(Node node) { + NodeList childNodes = node.getChildNodes(); + for (int x = 0; x < childNodes.getLength(); x++) { + Node data = childNodes.item(x); + if (data.getNodeType() == Node.TEXT_NODE) + return data.getNodeValue(); + } + return ""; + } + + public static String getNodeValue(String tagName, NodeList nodes) { + for (int x = 0; x < nodes.getLength(); x++) { + Node node = nodes.item(x); + if (node.getNodeName().equalsIgnoreCase(tagName)) { + NodeList childNodes = node.getChildNodes(); + for (int y = 0; y < childNodes.getLength(); y++) { + Node data = childNodes.item(y); + if (data.getNodeType() == Node.TEXT_NODE) + return data.getNodeValue(); + } + } + } + return ""; + } + + public static String getNodeAttr(String attrName, Node node) { + NamedNodeMap attrs = node.getAttributes(); + for (int y = 0; y < attrs.getLength(); y++) { + Node attr = attrs.item(y); + if (attr.getNodeName().equalsIgnoreCase(attrName)) { + return attr.getNodeValue(); + } + } + return ""; + } + + public static String getNodeAttr(String tagName, String attrName, NodeList nodes) { + for (int x = 0; x < nodes.getLength(); x++) { + Node node = nodes.item(x); + if (node.getNodeName().equalsIgnoreCase(tagName)) { + NodeList childNodes = node.getChildNodes(); + for (int y = 0; y < childNodes.getLength(); y++) { + Node data = childNodes.item(y); + if ((data.getNodeType() == Node.ATTRIBUTE_NODE) && data.getNodeName().equalsIgnoreCase(attrName)) { + return data.getNodeValue(); + } + } + } + } + return ""; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestException.java b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestException.java new file mode 100644 index 0000000000..a468137851 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestException.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +public class AlmRestException extends Exception{ + + private static final long serialVersionUID = -5386355008323770238L; + + public AlmRestException(Throwable cause) { + + super(cause); + } + + public AlmRestException(String message) { + + super(message); + } + + public AlmRestException(String message, Throwable cause) { + + super(message, cause); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestInfo.java b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestInfo.java new file mode 100644 index 0000000000..9816212dde --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestInfo.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +public class AlmRestInfo { + + private String serverUrl; + private String userName; + private String password; + private String domain; + private String clientType; + private String project; + private String timeout; + + public AlmRestInfo(String serverUrl, String domain, String clientType, String project, String userName, String password, String timeout) { + this.serverUrl = serverUrl; + this.userName = userName; + this.password = password; + this.domain = domain; + this.clientType = clientType; + this.project = project; + this.timeout = timeout; + } + + public String getServerUrl(){ + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public String getUserName(){ + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword(){ + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDomain(){ + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public String getProject(){ + return project; + } + + public void setProject(String project){ + this.project = project; + } + + public String getTimeout() { + return timeout; + } + + public void setTimeout(String timeout){ + this.timeout = timeout; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestTool.java b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestTool.java new file mode 100644 index 0000000000..0e7058ab67 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/AlmRestTool.java @@ -0,0 +1,290 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.results.service.almentities.AlmEntity; +import com.microfocus.application.automation.tools.results.service.rest.CreateAlmEntityRequest; +import com.microfocus.application.automation.tools.results.service.rest.GetAlmEntityRequest; +import com.microfocus.application.automation.tools.results.service.rest.UpdateAlmEntityRequest; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.authenticator.AuthenticationTool; +import com.microfocus.application.automation.tools.sse.sdk.authenticator.RestAuthenticator; + +public class AlmRestTool { + + private Logger _logger ; + private RestClient restClient; + private AlmRestInfo almLoginInfo; + + private final String USERNAMEPRETAG = ""; + private final String USERNAMESUBTAG = ""; + + public AlmRestTool(RestClient restClient, Logger logger) { + this.restClient = restClient; + this._logger = logger; + } + + public AlmRestTool (AlmRestInfo almLoginInfo, Logger logger) { + this.restClient = new RestClient( + almLoginInfo.getServerUrl(), + almLoginInfo.getDomain(), + almLoginInfo.getProject(), + almLoginInfo.getUserName()); + this.almLoginInfo = almLoginInfo; + this._logger = logger; + } + + public RestClient getRestClient() { + return this.restClient; + } + + public boolean login() { + return AuthenticationTool.getInstance().authenticate(restClient, almLoginInfo.getUserName(), + almLoginInfo.getPassword(), almLoginInfo.getServerUrl(), almLoginInfo.getClientType(), _logger); + } + + /** + * If logged in with API key, should get the user name again for creating entity to ALM. + * @return Actual user name + */ + public String getActualUsername() { + Response response = + restClient.httpGet( + restClient.build(RestAuthenticator.IS_AUTHENTICATED), + null, + null, + ResourceAccessLevel.PUBLIC); + + if (!response.isOk()) { + _logger.log("ERR: Cannot get actual login username: " + response.getFailure()); + return null; + } + + String responseData = new String(response.getData()); + if (!responseData.contains(USERNAMEPRETAG) || !responseData.contains(USERNAMESUBTAG)) { + _logger.log("ERR: Response is not as expected: " + responseData); + return null; + } + + return responseData.substring( + responseData.indexOf(USERNAMEPRETAG) + USERNAMEPRETAG.length(), + responseData.indexOf(USERNAMESUBTAG) + ); + } + + /** + * Get Pair list for ALM entity fields + */ + public List> getPairListForAlmEntityFields(AlmEntity almEntity, List fieldNames){ + List> pairs = new ArrayList>(); + for(String fieldName : fieldNames) { + pairs.add(new Pair(fieldName, String.valueOf(almEntity.getFieldValue(fieldName)))); + } + return pairs; + } + + /** + * Get pair list for ALM entity fields + */ + public List> getPairListForAlmEntityFields(AlmEntity almEntity, String[] fieldNames){ + List> pairs = new ArrayList>(); + for(String fieldName : fieldNames) { + pairs.add(new Pair(fieldName, String.valueOf(almEntity.getFieldValue(fieldName)))); + } + return pairs; + } + + /** + * Get map list for ALM entity fields + */ + public List> getMapListForAlmEntityFields(AlmEntity almEntity, String[] fieldNames){ + List> fieldsMapList = new ArrayList>(); + + Map fieldsMap = new HashMap (); + + for(String fieldName : fieldNames) { + fieldsMap.put(fieldName, String.valueOf(almEntity.getFieldValue(fieldName))); + } + fieldsMapList.add(fieldsMap); + return fieldsMapList; + } + + /** + * Populate ALM entity field value + */ + public void populateAlmEntityFieldValue(Map mapFieldValue, AlmEntity almEntity) { + for(Map.Entry entry : mapFieldValue.entrySet()){ + almEntity.setFieldValue(entry.getKey(), entry.getValue()); + } + } + + /** + * Get ALM entity list + */ + public List getAlmEntityList(List> entities, Class c) { + + List entityList = new ArrayList (); + for(Map fieldValueMap: entities) { + try { + E entity = c.newInstance(); + populateAlmEntityFieldValue(fieldValueMap, entity); + entityList.add(entity); + } catch (Exception e) { + + } + } + + return entityList; + + } + + /** + * Get encode string + */ + public static String getEncodedString(String s) { + String quotedStr = "\"" + s +"\""; + try { + quotedStr = URLEncoder.encode(quotedStr, "UTF-8"); + } catch (Exception e) { + + } + return quotedStr; + } + + /** + * Get entity under parent folder + */ + public E getEntityUnderParentFolder( Class entityClass, int parentId, String entityName ){ + + String getEntityUnderParentFolderQuery = String.format("fields=id,name&query={parent-id[%s];name[%s]}", String.valueOf(parentId), getEncodedString(entityName)); + try { + AlmEntity entity = entityClass.newInstance(); + GetAlmEntityRequest getRequest = new GetAlmEntityRequest(entity, getRestClient(), getEntityUnderParentFolderQuery); + Response response = getRequest.perform(); + if(response.isOk() ) { + List> entities2 = XPathUtils.toEntities(response.toString()); + List entities = getAlmEntityList(entities2, entityClass); + + if(entities.size()>0){ + return entities.get(0); + } else { + return null; + } + } else { + _logger.log("Failed to get Entity:" +getEntityUnderParentFolderQuery ); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + /** + * Get ALM entity + */ + public List getAlmEntity( E entity, String queryString){ + + List ret = new ArrayList(); + + try { + GetAlmEntityRequest getRequest = new GetAlmEntityRequest(entity, getRestClient(), queryString); + Response response = getRequest.perform(); + if(response.isOk() && !response.toString().equals("")) { + List> entities2 = XPathUtils.toEntities(response.toString()); + List entities = getAlmEntityList(entities2, entity.getClass()); + return entities; + } else { + return ret; + } + + } catch (Exception e) { + e.printStackTrace(); + _logger.log("Failed to get Entity:" + entity.toString() +" with query string:" +queryString); + return ret; + } + + } + + /** + * Create ALM entity + */ + public E createAlmEntity (E entity, String[] fieldsForCreation) throws ExternalEntityUploadException { + + CreateAlmEntityRequest createRequest = new CreateAlmEntityRequest(getRestClient(), entity, getPairListForAlmEntityFields(entity, fieldsForCreation) ); + Response response = createRequest.perform(); + if(response.isOk() && !response.toString().equals("")){ + List> entities2 = XPathUtils.toEntities(response.toString()); + List entities = getAlmEntityList(entities2, entity.getClass()); + + if(entities.size()>0){ + + return (E)entities.get(0); + } else { + _logger.log("Failed to create Entity:" + entity.toString()); + throw new ExternalEntityUploadException("Failed to create Entity:" + entity.toString()); + } + } else { + _logger.log("Failed to create Entity:" + entity.toString()); + throw new ExternalEntityUploadException("Failed to create Entity:" + entity.toString()); + } + + } + + /** + * Update ALM entity + */ + public void updateAlmEntity (E entity, String[] fieldsForUpdate) { + + UpdateAlmEntityRequest updateRequest = new UpdateAlmEntityRequest(getRestClient(), entity, getMapListForAlmEntityFields(entity, fieldsForUpdate)) ; + Response response = updateRequest.execute(); + + if(!response.isOk()) { + _logger.log("Failed to update entity:" + entity.toString()); + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/AttachmentUploadService.java b/src/main/java/com/microfocus/application/automation/tools/results/service/AttachmentUploadService.java new file mode 100644 index 0000000000..eb70f9ea0a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/AttachmentUploadService.java @@ -0,0 +1,140 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.results.service.rest.CreateAttachment; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import hudson.FilePath; +import hudson.model.Run; +import org.apache.commons.io.IOUtils; +import org.apache.tools.ant.DirectoryScanner; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +public class AttachmentUploadService { + + private Run run; + private FilePath workspace; + private RestClient restClient; + private Logger logger; + + private static AttachmentUploadService aus; + + public static void init(Run run, FilePath workspace, RestClient restClient, Logger logger) { + aus = new AttachmentUploadService(run, workspace, restClient, logger); + } + + public static AttachmentUploadService getInstance() { + return aus; + } + + private AttachmentUploadService(Run run, FilePath workspace, RestClient restClient, Logger logger) { + this.run = run; + this.workspace = workspace; + this.restClient = restClient; + this.logger = logger; + } + + public boolean upload(String fileName, String entityCollectionName, String entityId) { + DirectoryScanner ds = new DirectoryScanner(); + ds.setBasedir(run.getRootDir()); + ds.setIncludes(new String[] {fileName}); + ds.scan(); + + boolean result = true; + + if (ds.getIncludedFilesCount() > 0) { + // Find in build folder. + for (int i = 0; i < ds.getIncludedFilesCount(); i++) { + String filePath = run.getRootDir().getAbsolutePath() + File.separator + ds.getIncludedFiles()[i]; + logger.log("INFO: Fould file: " + filePath); + + try (FileInputStream in = new FileInputStream(new File(filePath))) { + result = upload(IOUtils.toByteArray(in), ds.getIncludedFiles()[i], entityCollectionName, entityId); + } catch (IOException e) { + logger.log("ERR: Read file failed. " + e.getMessage()); + result = false; + } + } + } else { + // Find in workspace + FilePath[] fileList = new FilePath[0]; + try { + fileList = workspace.list(fileName); + } catch (IOException | InterruptedException e) { + logger.log("ERR: List " + fileName + " in workspace failed. " + e.getMessage()); + result = false; + } + + for (FilePath f : fileList) { + logger.log("INFO: Fould file: " + f.getRemote() + "| name: " + f.getName()); + + try (InputStream in = f.read()) { + logger.log("INFO: InputSteam read get: " + in.toString()); + result = upload(IOUtils.toByteArray(in), f.getName(), entityCollectionName, entityId); + } catch (IOException | InterruptedException e) { + logger.log("ERR: Read file failed. " + e.getMessage()); + result = false; + } + } + } + + return result; + } + + private boolean upload(byte[] fileContent, String filename, String entityCollectionName, String entityId) { + logger.log("INFO: Uploading file: " + filename); + CreateAttachment ca = new CreateAttachment(entityCollectionName, + restClient, + entityId, + filename, + fileContent); + Response re = ca.perform(); + + if (re.getStatusCode() != HttpURLConnection.HTTP_CREATED) { + logger.log("INFO: Stauts " + re.getStatusCode()); + logger.log("ERR: Attachment upload failed. " + re.getFailure()); + logger.log("ERR: " + new String(re.getData())); + return false; + } else { + logger.log("INFO: Attachment upload success."); + return true; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java new file mode 100644 index 0000000000..eb74dcfbe8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/DefaultExternalEntityUploadServiceImpl.java @@ -0,0 +1,489 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import com.microfocus.application.automation.tools.results.parser.ReportParserManager; +import com.microfocus.application.automation.tools.results.service.almentities.AlmCommonProperties; +import com.microfocus.application.automation.tools.results.service.almentities.AlmEntity; +import com.microfocus.application.automation.tools.results.service.almentities.AlmRun; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTest; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestConfig; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestConfigImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestFolder; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestFolderImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstance; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestInstanceImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetFolder; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetFolderImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSetImpl; +import com.microfocus.application.automation.tools.results.service.almentities.EntityRelation; +import com.microfocus.application.automation.tools.results.service.almentities.IAlmConsts; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import hudson.FilePath; + +public class DefaultExternalEntityUploadServiceImpl implements + IExternalEntityUploadService { + + Logger logger; + private AlmRestTool restTool; + private FilePath workspace; + + public DefaultExternalEntityUploadServiceImpl(AlmRestTool restTool, FilePath workspace, Logger logger) { + this.restTool = restTool; + this.logger = logger; + this.workspace = workspace; + } + + private String [] getTestCreationFields() { + + return new String [] { AlmTest.TEST_NAME, + AlmTest.TEST_TYPE, + AlmTest.TS_TESTING_FRAMEWORK, + AlmTest.TS_TESTING_TOOL, + AlmTest.TS_UT_PACKAGE_NAME, + AlmTest.TS_UT_CLASS_NAME, + AlmTest.TS_UT_METHOD_NAME, + AlmCommonProperties.PARENT_ID, + AlmTest.TEST_RESPONSIBLE + }; + } + + private AlmTest importTest(AlmTest test , int testFolderId, String testingTool, String testdesigner) throws ExternalEntityUploadException{ + + String className = (String) test.getFieldValue(AlmTest.TS_UT_CLASS_NAME); + String methodName = (String) test.getFieldValue(AlmTest.TS_UT_METHOD_NAME); + String packageName = (String) test.getFieldValue(AlmTest.TS_UT_PACKAGE_NAME); + String testingFramework = (String) test.getFieldValue(AlmTest.TS_TESTING_FRAMEWORK); + + String queryString = String.format("query={parent-id[%s];subtype-id[EXTERNAL-TEST];ut-class-name[%s];ut-method-name[%s]}&fields=id,name,ut-package-name,ut-class-name,ut-method-name,testing-framework&page-size=2000", + String.valueOf(testFolderId), + AlmRestTool.getEncodedString(className), + AlmRestTool.getEncodedString(methodName)); + List existingTests = restTool.getAlmEntity(new AlmTestImpl(), queryString); + + AlmTestImpl importedTest = null;//restTool.getEntityUnderParentFolder(AlmTestImpl.class, testFolderId, test.getName()); + + if(existingTests != null && existingTests.size() >0) { + boolean exists = false; + Map existingTestMap = new HashMap (); + + for(AlmTestImpl existingTest : existingTests) { + if(existingTest.getKey().endsWith(test.getKey())) { + exists = true; + importedTest = existingTest; + break; + } + existingTestMap.put(existingTest.getName(), existingTest); + } + + if(!exists) { + String tempName = className + "_" + methodName; + if(!existingTestMap.containsKey(tempName)) { + test.setFieldValue(AlmTest.TEST_NAME, tempName); + } else { + tempName = packageName + "_" +tempName; + if(!existingTestMap.containsKey(tempName)) { + test.setFieldValue(AlmTest.TEST_NAME, tempName); + } else { + tempName = tempName +"_" +testingFramework; + if(!existingTestMap.containsKey(tempName)) { + test.setFieldValue(AlmTest.TEST_NAME, tempName); + } + } + } + + } + } + + if(importedTest == null) { + test.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(testFolderId)); + test.setFieldValue(AlmTest.TS_TESTING_TOOL, testingTool); + test.setFieldValue(AlmTest.TEST_RESPONSIBLE, testdesigner); + return restTool.createAlmEntity(test, getTestCreationFields()); + } + + + return importedTest; + } + + private String [] getTestSetCreationFields() { + return new String [] { AlmCommonProperties.PARENT_ID, + AlmTestSet.TESTSET_NAME, + AlmTestSet.TESTSET_SUB_TYPE_ID}; + } + + private AlmTestSet importTestSet(AlmTestSet testset, int testsetFolderId) throws ExternalEntityUploadException{ + + + AlmTestSetImpl + importedTestset = restTool.getEntityUnderParentFolder(AlmTestSetImpl.class, testsetFolderId, testset.getName()); + + if(importedTestset == null) { + + testset.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(testsetFolderId)); + return restTool.createAlmEntity(testset, getTestSetCreationFields()); + + } + + + return importedTestset; + } + + private AlmTestConfig getMainTestConfig(AlmTest test){ + + AlmTestConfigImpl testConfigImpl = new AlmTestConfigImpl(); + String queryString = String.format("query={parent-id[%s]}&fields=id,name", String.valueOf(test.getId()) ); + List testconfigs = restTool.getAlmEntity(testConfigImpl, queryString); + if(testconfigs != null && testconfigs.size() >0) { + return testconfigs.get(0); + } else { + return null; + } + + } + + private String [] getTestInstanceCreationFields (){ + return new String [] { AlmTestInstance.TEST_INSTANCE_TESTSET_ID, + AlmTestInstance.TEST_INSTANCE_CONFIG_ID, + AlmTestInstance.TEST_INSTANCE_TEST_ID, + AlmTestInstance.TEST_INSTANCE_TESTER_NAME, + AlmTestInstance.TEST_INSTANCE_SUBTYPE_ID + }; + + } + + private AlmTestInstance importTestInstance(AlmTestInstance testinstance, String testsetId, String testId, String testconfigId, String tester) throws ExternalEntityUploadException{ + + String queryString = String.format("query={cycle-id[%s];test-config-id[%s];test-id[%s]}&fields=id,name", + String.valueOf(testsetId), String.valueOf(testconfigId), String.valueOf(testId) ); + + List testInstances = restTool.getAlmEntity(new AlmTestInstanceImpl(), queryString); + + if(testInstances!=null && testInstances.size() > 0){ + return testInstances.get(0); + } else { + + testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TESTSET_ID, String.valueOf(testsetId)); + testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_CONFIG_ID, String.valueOf(testconfigId)); + testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TEST_ID, String.valueOf(testId)); + testinstance.setFieldValue(AlmTestInstance.TEST_INSTANCE_TESTER_NAME, tester); + + return restTool.createAlmEntity(testinstance, getTestInstanceCreationFields()); + } + } + + private String generateImportRunName() { + Calendar cal = new GregorianCalendar(); + cal.setTime(new java.sql.Date(System.currentTimeMillis())); + return String.format( + IAlmConsts.IMPORT_RUN_NAME_TEMPLATE, + cal.get(Calendar.MONTH) + 1, // java.util.Calendar represents months from 0 to 11 instead of from 1 to 12. That's why it should be incremented. + cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + cal.get(Calendar.SECOND)); + } + + + private String[] getRunCreationFields() { + return new String[]{ + AlmRun.RUN_CONFIG_ID, + AlmRun.RUN_CYCLE_ID, + AlmRun.RUN_TEST_ID, + AlmRun.RUN_TESTCYCL_UNIQUE_ID, + AlmRun.RUN_BUILD_REVISION, + AlmCommonProperties.NAME, + AlmCommonProperties.OWNER, + AlmRun.RUN_STATUS, + AlmRun.RUN_SUBTYPE_ID, + AlmRun.RUN_DETAIL, + AlmRun.RUN_DURATION, + AlmRun.RUN_JENKINS_JOB_NAME, + AlmRun.RUN_JENKINS_URL, + AlmRun.RUN_EXECUTION_DATE, + AlmRun.RUN_EXECUTION_TIME, + AlmRun.RUN_STATUS + }; + } + + private AlmRun generateRun(String tester, + AlmRun run, + String testsetId, + String testId, + String testInstanceId, + String testconfigId, + String subversion, + String jobName, + String buildUrl) throws ExternalEntityUploadException{ + + run.setFieldValue(AlmRun.RUN_CONFIG_ID, String.valueOf(testconfigId)); + run.setFieldValue(AlmRun.RUN_CYCLE_ID, String.valueOf(testsetId)); + run.setFieldValue(AlmRun.RUN_TEST_ID, String.valueOf(testId)); + run.setFieldValue(AlmRun.RUN_TESTCYCL_UNIQUE_ID, String.valueOf(testInstanceId)); + run.setFieldValue(AlmRun.RUN_JENKINS_JOB_NAME, jobName); + run.setFieldValue(AlmRun.RUN_JENKINS_URL, buildUrl); + + + if(subversion != null && subversion.length() >0 ) { + run.setFieldValue(AlmRun.RUN_BUILD_REVISION, subversion); + } else { + run.setFieldValue(AlmRun.RUN_BUILD_REVISION, ""); + } + + run.setFieldValue(AlmCommonProperties.NAME, generateImportRunName()); + run.setFieldValue(AlmCommonProperties.OWNER, tester); + + return restTool.createAlmEntity(run, getRunCreationFields()); + + + } + + private String[] getCreationFieldsForTestFolder() { + return new String[] {AlmCommonProperties.NAME, AlmCommonProperties.PARENT_ID}; + } + + private AlmTestFolder createTestFolder(int parentId, String folderName) throws ExternalEntityUploadException { + + AlmTestFolderImpl testFolder = restTool.getEntityUnderParentFolder(AlmTestFolderImpl.class, parentId, folderName); + String encodedFolderName = folderName; + + if(testFolder == null) { + testFolder = new AlmTestFolderImpl(); + testFolder.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(parentId)); + testFolder.setFieldValue(AlmCommonProperties.NAME, encodedFolderName); + return restTool.createAlmEntity(testFolder, getCreationFieldsForTestFolder()); + } else { + return testFolder; + } + } + String FOLDER_SEPERATOR = "\\"; + + + private AlmTestFolder createTestFolderPath(int parentId, String path) throws ExternalEntityUploadException { + List folders = new ArrayList(); + + StringTokenizer tokenizer = new StringTokenizer(path, FOLDER_SEPERATOR); + + while (tokenizer.hasMoreTokens()) { + String itemString = tokenizer.nextToken(); + AlmTestFolder testFolder = createTestFolder(parentId, itemString); + if(testFolder != null) { + folders.add(testFolder); + parentId = Integer.valueOf(testFolder.getId()); + } + } + + if(folders.size() >0 ){ + return folders.get(folders.size()-1); + } else { + return null; + } + } + + private String[] getCreationFieldsForTestSetFolder() { + return new String[] {AlmCommonProperties.NAME, AlmCommonProperties.PARENT_ID}; + } + + private AlmTestSetFolder createTestSetFolder(int parentId, String folderName) throws ExternalEntityUploadException { + + AlmTestSetFolderImpl + testsetFolder = restTool.getEntityUnderParentFolder(AlmTestSetFolderImpl.class, parentId, folderName); + + String encodedFolderName = folderName; + + if(testsetFolder == null) { + testsetFolder = new AlmTestSetFolderImpl(); + testsetFolder.setFieldValue(AlmCommonProperties.PARENT_ID, String.valueOf(parentId)); + testsetFolder.setFieldValue(AlmCommonProperties.NAME, encodedFolderName); + return restTool.createAlmEntity(testsetFolder, getCreationFieldsForTestSetFolder()); + } else { + return testsetFolder; + } + } + + private AlmTestSetFolder createTestSetFolderPath(int parentId, String path) throws ExternalEntityUploadException { + + List folders = new ArrayList(); + + StringTokenizer tokenizer = new StringTokenizer(path, FOLDER_SEPERATOR); + + while (tokenizer.hasMoreTokens()) { + String itemString = tokenizer.nextToken(); + AlmTestSetFolder testsetFolder = createTestSetFolder(parentId, itemString); + if(testsetFolder != null) { + folders.add(testsetFolder); + parentId = Integer.valueOf(testsetFolder.getId()); + } + } + if(folders.size() >0 ){ + return folders.get(folders.size()-1); + } else { + return null; + } + } + + @Override + public List uploadExternalTestSet(AlmRestInfo loginInfo, + String reportFilePath, + String testsetFolderPath, + String testFolderPath, + String testingFramework, + String testingTool, + String subversion, + String jobName, + String buildUrl) throws ExternalEntityUploadException { + + logger.log("INFO: Start to parse file: " + reportFilePath); + + List importedTestsetIds = new ArrayList<>(); + ReportParserManager reportParserManager = ReportParserManager.getInstance(workspace, logger); + + List testsets = reportParserManager.parseTestSets(reportFilePath, testingFramework, testingTool); + + if(testsets == null) { + throw new ExternalEntityUploadException("Failed to parse file: " + reportFilePath); + } else { + logger.log("INFO: parse resut file succeed."); + } + + if (testsets.size() <= 0) { + logger.log("INFO: No testset to upload."); + return importedTestsetIds; + } + + logger.log("INFO: Start to login to ALM Server."); + try { + if(!restTool.login()) { + throw new ExternalEntityUploadException("Failed to login to ALM Server."); + } + + // Get the username again if logged in with API key. + String actualUser = restTool.getActualUsername(); + if (actualUser == null || actualUser.length() == 0) { + throw new ExternalEntityUploadException("Failed to get actual login user."); + } + + logger.log("INFO: Checking test folder..."); + AlmTestFolder testFolder = createTestFolderPath(2, testFolderPath); + + logger.log("INFO: Checking testset folder..."); + AlmTestSetFolder testsetFolder = createTestSetFolderPath (0, testsetFolderPath); + + if(testFolder != null && testsetFolder != null) { + logger.log("INFO: Uploading ALM Entities..."); + importedTestsetIds = importExternalTestSet( + testsets, + actualUser, + Integer.valueOf(testsetFolder.getId()), + Integer.valueOf(testFolder.getId()), + testingTool, + subversion, + jobName, + buildUrl); + } + } catch (Exception e) { + throw new ExternalEntityUploadException(e); + } + return importedTestsetIds; + } + + + private List importExternalTestSet(List testsets, String tester, int testsetFolderId, int testFolderId, String testingTool, String subversion, String jobName, String buildUrl ) throws ExternalEntityUploadException{ + + List importedTestsetIds = new ArrayList(); + + for (AlmTestSet testset : testsets){ + AlmTestSet importedTestSet = importTestSet(testset, testsetFolderId); + if(importedTestSet == null ) { + continue; + } + + importedTestsetIds.add(importedTestSet.getId()); + + List testinstances = testset.getRelatedEntities().get(EntityRelation.TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION); + if(testinstances == null || testinstances.size() <=0) { + continue; + } + + for(AlmEntity testinstanceEntity: testinstances){ + AlmTestInstance testInstance = (AlmTestInstance) testinstanceEntity; + List tests = testInstance.getRelatedEntities().get(EntityRelation.TEST_TO_TESTINSTANCE_REALIZATION_RELATION); + if(tests == null || tests.size() <= 0) { + continue; + } + + AlmTest test = (AlmTest) tests.get(0); + AlmTest importedTest = importTest(test, testFolderId, testingTool, tester); + if(importedTest == null) { + continue; + } + + AlmTestConfig mainTestConfig = getMainTestConfig(importedTest); + if(mainTestConfig == null) { + continue; + } + + AlmTestInstance importedTestInstance = importTestInstance(testInstance, importedTestSet.getId(), importedTest.getId(), mainTestConfig.getId(), tester); + List runs = testInstance.getRelatedEntities().get(EntityRelation.TESTINSTANCE_TO_RUN_REALIZATION_RELATION); + if(runs == null || runs.size() <= 0) { + continue; + } + + AlmRun run = (AlmRun) runs.get(0); + generateRun(tester, + run, + importedTestSet.getId(), + importedTest.getId(), + importedTestInstance.getId(), + mainTestConfig.getId(), + subversion, + jobName, + buildUrl + ); + } + } + + return importedTestsetIds; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadException.java b/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadException.java new file mode 100644 index 0000000000..b5c3044831 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadException.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +public class ExternalEntityUploadException extends Exception{ + + private static final long serialVersionUID = -5386355008323770238L; + + public ExternalEntityUploadException(Throwable cause) { + + super(cause); + } + + public ExternalEntityUploadException(String message) { + + super(message); + } + + public ExternalEntityUploadException(String message, Throwable cause) { + + super(message, cause); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadLogger.java b/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadLogger.java new file mode 100644 index 0000000000..4d4cc7bdd8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/ExternalEntityUploadLogger.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import java.io.PrintStream; + +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +public class ExternalEntityUploadLogger implements Logger { + + private PrintStream printStream; + + public ExternalEntityUploadLogger(PrintStream printStream) { + this.printStream = printStream; + } + + @Override + public void log(String message) { + if(printStream != null) { + printStream.println(message); + } + } + + @Override + public void error(String message) { + log(message); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/IExternalEntityUploadService.java b/src/main/java/com/microfocus/application/automation/tools/results/service/IExternalEntityUploadService.java new file mode 100644 index 0000000000..45873761ba --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/IExternalEntityUploadService.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import java.util.List; + +public interface IExternalEntityUploadService { + + public List uploadExternalTestSet( + AlmRestInfo loginInfo, String reportFilePath, + String testsetFolderPath, String testFolderPath, + String testingFramework, String testingTool, + String subversion, String jobName, String buildUrl) throws ExternalEntityUploadException; + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/SystemOutLogger.java b/src/main/java/com/microfocus/application/automation/tools/results/service/SystemOutLogger.java new file mode 100644 index 0000000000..7da39296fa --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/SystemOutLogger.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +public class SystemOutLogger implements Logger { + + @Override + public void log(String message) { + System.out.println(message); + + } + + @Override + public void error(String message) { + log(message); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmCommonProperties.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmCommonProperties.java new file mode 100644 index 0000000000..26a367a499 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmCommonProperties.java @@ -0,0 +1,41 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmCommonProperties { + + public final String PARENT_ID = "parent-id"; + public final String NAME = "name"; + public final String ID = "id"; + public final String OWNER = "owner"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntity.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntity.java new file mode 100644 index 0000000000..49f60285b6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntity.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +import java.util.List; +import java.util.Map; + +public interface AlmEntity { + + public void setFieldValue(String fieldName, String fieldValue); + public Object getFieldValue(String fieldName); + public void addRelatedEntity(String relationName, AlmEntity entity); + public Map> getRelatedEntities() ; + + public String getName(); + + public String getId(); + + public void setId(String id); + + public String getRestPrefix(); + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntityImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntityImpl.java new file mode 100644 index 0000000000..befea905ee --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmEntityImpl.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class AlmEntityImpl implements AlmEntity { + + private final Map fields = new HashMap(); + private final Map> relatedEntities = + new HashMap>(); + + + public String getName() { + return (String) getFieldValue(AlmCommonProperties.NAME); + } + + public String getId() { + return getFieldValue(AlmCommonProperties.ID); + + } + + public void setId(String id) { + setFieldValue(AlmCommonProperties.ID, id); + } + + @Override + public void setFieldValue(String fieldName, String fieldValue) { + fields.put(fieldName, fieldValue); + + } + + @Override + public String getFieldValue(String fieldName) { + return fields.get(fieldName); + } + + @Override + public void addRelatedEntity(String relationName, AlmEntity entity) { + List entities = relatedEntities.get(relationName); + if (entities == null){ + relatedEntities.put(relationName, new ArrayList()); + entities = relatedEntities.get(relationName); + } + + entities.add(entity); + } + + @Override + public Map> getRelatedEntities() { + return relatedEntities; + } + + public String toString(){ + String s = this.getRestPrefix() +":"; + + for(Map.Entry field : fields.entrySet()) { + s += field.getKey(); + s += "="; + s += field.getValue(); + } + return s; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRun.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRun.java new file mode 100644 index 0000000000..cdc746b051 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRun.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmRun extends AlmEntity{ + public final String RUN_SUBTYPE_ID = "subtype-id"; + public final String RUN_STATUS = "status"; + public final String RUN_DETAIL = "detail"; + public final String RUN_EXECUTION_DATE = "execution-date"; + public final String RUN_EXECUTION_TIME = "execution-time"; + public final String RUN_DURATION = "duration"; + public final String RUN_CONFIG_ID ="test-config-id"; + public final String RUN_CYCLE_ID = "cycle-id"; + public final String RUN_TEST_ID = "test-id"; + public final String RUN_TESTCYCL_UNIQUE_ID = "testcycl-id"; + public final String RUN_BUILD_REVISION= "build-revision"; + public final String RUN_JENKINS_JOB_NAME="jenkins-job-name"; + public final String RUN_JENKINS_URL="jenkins-url"; + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRunImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRunImpl.java new file mode 100644 index 0000000000..77f6c27e17 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmRunImpl.java @@ -0,0 +1,41 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmRunImpl extends AlmEntityImpl implements AlmRun { + + private static String restPrefix = "runs"; + public String getRestPrefix() { + return restPrefix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTest.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTest.java new file mode 100644 index 0000000000..2278e9bbc3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTest.java @@ -0,0 +1,46 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTest extends AlmEntity{ + public final String TEST_NAME = "name"; + public final String TEST_TYPE = "subtype-id"; + public final String TS_TESTING_FRAMEWORK = "testing-framework"; + public final String TS_TESTING_TOOL = "testing-tool"; + public final String TS_UT_CLASS_NAME = "ut-class-name"; + public final String TS_UT_METHOD_NAME = "ut-method-name"; + public final String TEST_RESPONSIBLE = "owner"; + public final String TS_UT_PACKAGE_NAME = "ut-package-name"; + + public String getKey(); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfig.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfig.java new file mode 100644 index 0000000000..a0caebfb21 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfig.java @@ -0,0 +1,37 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTestConfig extends AlmEntity { + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java new file mode 100644 index 0000000000..c620e63095 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestConfigImpl.java @@ -0,0 +1,41 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestConfigImpl extends AlmEntityImpl implements AlmTestConfig { + + private static String restPrefix = "test-configs"; + public String getRestPrefix() { + return restPrefix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolder.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolder.java new file mode 100644 index 0000000000..e2d7315b72 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolder.java @@ -0,0 +1,37 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTestFolder extends AlmEntity { + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java new file mode 100644 index 0000000000..a88bfe3f0f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestFolderImpl.java @@ -0,0 +1,41 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestFolderImpl extends AlmEntityImpl implements AlmTestFolder { + + private static String restPrefix = "test-folders"; + public String getRestPrefix() { + return restPrefix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestImpl.java new file mode 100644 index 0000000000..2321b6ec12 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestImpl.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestImpl extends AlmEntityImpl implements AlmTest { + private static String restPrefix = "tests"; + private String trimTrailingSpace(String s){ + return s.replaceFirst("\\s++$", ""); + } + public String getRestPrefix() { + return restPrefix; + } + + public String getKey(){ + String className = (String)getFieldValue(TS_UT_CLASS_NAME); + + String methodName = trimTrailingSpace((String)getFieldValue(TS_UT_METHOD_NAME)); + String packageName = (String)getFieldValue(TS_UT_PACKAGE_NAME); + if(packageName == null) { + packageName = ""; + } + String testingFramework = (String) getFieldValue(TS_TESTING_FRAMEWORK); + String key = packageName +"_" +className +"_"+ methodName+"_"+testingFramework; + return key; + } + + public boolean equals(Object o){ + + if( !(o instanceof AlmTestImpl)){ + return false; + } + + if(this == o) { + return true; + } + + AlmTestImpl oT = (AlmTestImpl) o; + + String className = (String)getFieldValue(TS_UT_CLASS_NAME); + + String methodName = (String)getFieldValue(TS_UT_METHOD_NAME); + String packageName = (String)getFieldValue(TS_UT_PACKAGE_NAME); + if(packageName == null) { + packageName = ""; + } + + String testingFramework = (String) getFieldValue(TS_TESTING_FRAMEWORK); + + return className.equals((String)oT.getFieldValue(TS_UT_CLASS_NAME)) + && packageName.equals((String)oT.getFieldValue(TS_UT_PACKAGE_NAME)) + && methodName.equals((String)oT.getFieldValue(TS_UT_METHOD_NAME)) + && testingFramework.equals((String)oT.getFieldValue(TS_TESTING_FRAMEWORK)); + + } + + public int hashCode(){ + + return getKey().hashCode(); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstance.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstance.java new file mode 100644 index 0000000000..bac854138b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstance.java @@ -0,0 +1,46 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTestInstance extends AlmEntity{ + + public final String TEST_INSTANCE_SUBTYPE_ID = "subtype-id"; + public final String TEST_INSTANCE_EXEC_DATE = "exec-date"; + public final String TEST_INSTANCE_EXEC_TIME = "exec-time"; + public final String TEST_INSTANCE_TESTSET_ID = "cycle-id"; + public final String TEST_INSTANCE_CONFIG_ID= "test-config-id"; + public final String TEST_INSTANCE_TEST_ID = "test-id"; + public final String TEST_INSTANCE_TESTER_NAME = "owner"; + + public String getKey(); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java new file mode 100644 index 0000000000..44f27cf22f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestInstanceImpl.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestInstanceImpl extends AlmEntityImpl implements + AlmTestInstance { + private static String restPrefix = "test-instances"; + public String getRestPrefix() { + return restPrefix; + } + + public String getKey() { + + return getFieldValue(AlmTestInstance.TEST_INSTANCE_TESTSET_ID) + "_" + + getFieldValue(AlmTestInstance.TEST_INSTANCE_CONFIG_ID) + "_" + + getFieldValue(AlmTestInstance.TEST_INSTANCE_TEST_ID); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSet.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSet.java new file mode 100644 index 0000000000..51cdefbfb0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSet.java @@ -0,0 +1,40 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTestSet extends AlmEntity{ + + public final String TESTSET_NAME = "name"; + public final String TESTSET_SUB_TYPE_ID = "subtype-id"; + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolder.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolder.java new file mode 100644 index 0000000000..eccb12b7f5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolder.java @@ -0,0 +1,37 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface AlmTestSetFolder extends AlmEntity { + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java new file mode 100644 index 0000000000..b0e623660f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetFolderImpl.java @@ -0,0 +1,41 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestSetFolderImpl extends AlmEntityImpl implements + AlmTestSetFolder { + private static String restPrefix = "test-set-folders"; + public String getRestPrefix() { + return restPrefix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetImpl.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetImpl.java new file mode 100644 index 0000000000..1e469504e7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/AlmTestSetImpl.java @@ -0,0 +1,40 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public class AlmTestSetImpl extends AlmEntityImpl implements AlmTestSet { + private static String restPrefix = "test-sets"; + public String getRestPrefix() { + return restPrefix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/EntityRelation.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/EntityRelation.java new file mode 100644 index 0000000000..4aa1e17aa9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/EntityRelation.java @@ -0,0 +1,40 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface EntityRelation { + public final String TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION = "TESTSET_TO_TESTINSTANCE_CONTAINMENT_RELATION"; + public final String TEST_TO_TESTINSTANCE_REALIZATION_RELATION = "TEST_TO_TESTINSTANCE_REALIZATION_RELATION"; + public final String TESTINSTANCE_TO_RUN_REALIZATION_RELATION = "TESTINSTANCE_TO_RUN_REALIZATION_RELATION"; + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/IAlmConsts.java b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/IAlmConsts.java new file mode 100644 index 0000000000..ac36a08d0f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/almentities/IAlmConsts.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.almentities; + +public interface IAlmConsts { + + public enum IStatuses { + NO_RUN("No Run"), + PASSED("Passed"), + FAILED("Failed"), + BLOCKED("Blocked"), + NOT_COMPLETED("Not Completed"); + + private String value; + + IStatuses(String value) { + this.value = value; + } + + public String value() { + return value; + } + } + + public final String IMPORT_RUN_NAME_TEMPLATE = "Import_Run_%d-%d_%d-%d-%d"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java new file mode 100644 index 0000000000..90dd51b716 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAlmEntityRequest.java @@ -0,0 +1,77 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.rest; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.results.service.almentities.AlmEntity; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.PostRequest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CreateAlmEntityRequest extends PostRequest { + + List> attrForCreation; + AlmEntity almEntity; + private static final String IGNORE_REQUIRED_FIELDS_VALIDATION = "X-QC-Ignore-Customizable-Required-Fields-Validation"; + public CreateAlmEntityRequest(Client client, AlmEntity almEntity, List> attrForCreation){ + super(client, ""); + this.attrForCreation = attrForCreation; + this.almEntity = almEntity; + } + + @Override + protected Map getHeaders() { + + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + ret.put(IGNORE_REQUIRED_FIELDS_VALIDATION, "Y"); + ret.put("X-XSRF-TOKEN", _client.getXsrfTokenValue()); + return ret; + } + + @Override + protected String getSuffix() { + // TODO Auto-generated method stub + return almEntity.getRestPrefix(); + } + + protected List> getDataFields() { + + return attrForCreation; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAttachment.java b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAttachment.java new file mode 100644 index 0000000000..522df8e6be --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/CreateAttachment.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.rest; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.PostRequest; +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; + +import java.util.HashMap; +import java.util.Map; + +public class CreateAttachment extends PostRequest { + + private Client client; + private String testsetId; + private String fileName; + private byte[] filecontent; + private String entityCollectionName; + + private static final String CONTENT_TYPE = "application/octet-stream"; + + public CreateAttachment(String entityCollectionName, Client client, String id, String fileName, byte[] filecontent) { + super(client, ""); + this.entityCollectionName = entityCollectionName; + this.client = client; + this.testsetId = id; + this.fileName = fileName; + this.filecontent = filecontent; + } + + @Override + protected Map getHeaders() { + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, CONTENT_TYPE + ";"); + ret.put("Slug", fileName); + ret.put("X-XSRF-TOKEN", client.getXsrfTokenValue()); + return ret; + } + + @Override + protected String getSuffix() { + StringBuilder builder = new StringBuilder(); + builder.append(entityCollectionName).append("/").append(testsetId).append("/attachments"); + return builder.toString(); + } + + @Override + public Response perform() { + return client.httpPost( + getUrl(), + getDataBytes(), + getHeaders(), + ResourceAccessLevel.PROTECTED); + } + + private byte[] getDataBytes() { + return filecontent; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/rest/GetAlmEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/GetAlmEntityRequest.java new file mode 100644 index 0000000000..efe78ec0ec --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/GetAlmEntityRequest.java @@ -0,0 +1,70 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.rest; + +import com.microfocus.application.automation.tools.results.service.almentities.AlmEntity; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GetRequest; + +public class GetAlmEntityRequest extends GetRequest { + + private AlmEntity almEntity; + private String queryString ; + + public GetAlmEntityRequest(AlmEntity almEntity, Client client) { + super(client, ""); + this.almEntity = almEntity; + + } + + public GetAlmEntityRequest(AlmEntity almEntity, Client client, String queryString) { + super(client, ""); + this.almEntity = almEntity; + this.queryString = queryString; + + } + + protected String getQueryString() { + + return queryString; + } + + protected String getSuffix() { + if(queryString != null && queryString.length() >0 ) { + return almEntity.getRestPrefix(); + + } else { + return String.format("%s/%s", almEntity.getRestPrefix(), almEntity.getId()); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java new file mode 100644 index 0000000000..4c55af6974 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/results/service/rest/UpdateAlmEntityRequest.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service.rest; + +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.results.service.almentities.AlmEntity; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralPutBulkRequest; + +public class UpdateAlmEntityRequest extends GeneralPutBulkRequest { + + List> attrForUpdate; + AlmEntity almEntity; + + public UpdateAlmEntityRequest(Client client, AlmEntity almEntity, List> attrForUpdate){ + super(client); + this.attrForUpdate = attrForUpdate; + this.almEntity = almEntity; + } + + @Override + protected String getSuffix() { + // TODO Auto-generated method stub + return String.format("%s/%s", almEntity.getRestPrefix(), almEntity.getId()); + } + + protected List> getFields() { + + return attrForUpdate; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/AdditionalParametersAction.java b/src/main/java/com/microfocus/application/automation/tools/run/AdditionalParametersAction.java new file mode 100644 index 0000000000..ef795beead --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/AdditionalParametersAction.java @@ -0,0 +1,95 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.EnvironmentContributor; +import hudson.model.ParameterValue; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.model.ParametersAction; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +/** + * Fix for supporting SECURITY-170 changes + * https://jenkins.io/blog/2016/05/11/security-update/ + * https://issues.jenkins-ci.org/browse/JENKINS-39654 + * + */ +public class AdditionalParametersAction extends ParametersAction{ + + private List parameters; + + public AdditionalParametersAction(List cparameters){ + this.parameters = Collections.unmodifiableList(cparameters); + } + + @Override + public List getParameters() { + return Collections.unmodifiableList(parameters); + } + + @Override + public List getAllParameters() { + return Collections.unmodifiableList(parameters); + } + + @Override + public ParameterValue getParameter(String name){ + for (ParameterValue p : parameters) { + if (p == null) + continue; + if (p.getName().equals(name)) + return p; + } + return null; + } + + @Extension + public static final class AdditionalParametersActionEnvironmentContributor extends EnvironmentContributor { + @Override + public void buildEnvironmentFor(Run r, EnvVars envs, TaskListener listener) + throws IOException, InterruptedException { + AdditionalParametersAction action = r.getAction(AdditionalParametersAction.class); + if (action != null) { + for (ParameterValue p : action.getParameters()) { + envs.putIfNotNull(p.getName(), String.valueOf(p.getValue())); + } + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/AlmRunTypes.java b/src/main/java/com/microfocus/application/automation/tools/run/AlmRunTypes.java new file mode 100644 index 0000000000..8ca73f2389 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/AlmRunTypes.java @@ -0,0 +1,40 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; +public class AlmRunTypes { + + public enum RunType { + Alm, FileSystem, LoadRunner + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder.java new file mode 100644 index 0000000000..7e576afaa5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder.java @@ -0,0 +1,220 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.microfocus.application.automation.tools.model.AUTEnvironmentResolvedModel; +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.model.AutEnvironmentModel; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.autenvironment.AUTEnvironmentBuilderPerformer; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import org.kohsuke.stapler.DataBoundConstructor; + +import com.microfocus.application.automation.tools.model.AUTEnvironmentModelResolver; + +import hudson.EnvVars; +import hudson.Extension; +import hudson.Launcher; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.VariableResolver; + +import static com.microfocus.application.automation.tools.Messages.AutEnvironmentBuilderStepName; +import static com.microfocus.application.automation.tools.Messages.CompanyName; + +/** + * Created by barush on 21/10/2014. + */ +public class AutEnvironmentBuilder extends Builder { + + private final AutEnvironmentModel autEnvironmentModel; + + @DataBoundConstructor + public AutEnvironmentBuilder(AutEnvironmentModel autEnvironmentModel) { + + this.autEnvironmentModel = autEnvironmentModel; + + } + + public AutEnvironmentModel getAutEnvironmentModel() { + return autEnvironmentModel; + } + + @Override + public DescriptorImpl getDescriptor() { + + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) + throws InterruptedException, IOException { + + autEnvironmentModel.setAlmServerUrl(getServerUrl(autEnvironmentModel.getAlmServerName())); + PrintStream logger = listener.getLogger(); + EnvVars envVars = build.getEnvironment(listener); + execute(build, envVars, autEnvironmentModel, logger); + + return true; + } + + public String getServerUrl(String almServerName) { + + String ret = ""; + AlmServerSettingsModel[] almServers = getDescriptor().getAlmServers(); + if (almServers != null && almServers.length > 0) { + for (AlmServerSettingsModel almServer : almServers) { + if (almServerName.equals(almServer.getAlmServerName())) { + ret = almServer.getAlmServerUrl(); + break; + } + } + } + + return ret; + } + + private void execute( + AbstractBuild build, + EnvVars envVars, + AutEnvironmentModel autEnvironmentModel, + final PrintStream printStreamLogger) { + + AUTEnvironmentBuilderPerformer performer; + + Logger logger = new Logger() { + @Override + public void log(String message) { + printStreamLogger.println(message); + } + @Override + public void error(String message) { + log(message); + } + }; + + try { + VariableResolver.ByMap variableResolver = + new VariableResolver.ByMap(envVars); + + AUTEnvironmentResolvedModel autEnvModel = + AUTEnvironmentModelResolver.resolveModel(autEnvironmentModel, variableResolver); + performer = new AUTEnvironmentBuilderPerformer(autEnvModel, variableResolver, logger); + performer.start(envVars); + assignOutputValue(build, performer, autEnvModel.getOutputParameter(), logger); + + } catch (Exception e) { + logger.log(String.format("Build failed: %s", e.getMessage())); + build.setResult(Result.FAILURE); + } + } + + private void assignOutputValue( + AbstractBuild build, + AUTEnvironmentBuilderPerformer performer, + String outputParameterName, + Logger logger) { + + if (StringUtils.isNullOrEmpty(outputParameterName)) { + logger.log("No environment variable was specified for getting the AUT Environment Configuration ID"); + return; + } + + ParametersAction oldParametersAction = build.getAction(ParametersAction.class); + if (oldParametersAction != null + && oldParametersAction.getParameter(outputParameterName) != null) { + + List parametersList = + new ArrayList(oldParametersAction.getParameters()); + Iterator iterator = parametersList.iterator(); + while (iterator.hasNext()) { + ParameterValue nextValue = iterator.next(); + if (nextValue.getName().equals(outputParameterName)) { + if (!(nextValue instanceof StringParameterValue)) { + logger.log(String.format( + "Can't assign value to %s because it's type is not 'String Parameter'", + outputParameterName)); + return; + } + parametersList.remove(nextValue); + parametersList.add(new StringParameterValue( + nextValue.getName(), + performer.getAutEnvironmentConfigurationIdToReturn(), + nextValue.getDescription())); + break; + } + } + + build.getActions().remove(oldParametersAction); + build.addAction(new ParametersAction(parametersList)); + + } else { + logger.log(String.format( + "Can't assign created AUT Environment Configuration ID to: [%s] because there's no such parameter for this build", + outputParameterName)); + } + + } + + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + + load(); + } + + @Override + public boolean isApplicable(Class aClass) { + return true; + } + + @Override + public String getDisplayName() { + return AutEnvironmentBuilderStepName(CompanyName()); + } + + public AlmServerSettingsModel[] getAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/JobConfigRebrander.java b/src/main/java/com/microfocus/application/automation/tools/run/JobConfigRebrander.java new file mode 100644 index 0000000000..6f1d071d64 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/JobConfigRebrander.java @@ -0,0 +1,204 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.XmlFile; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.io.FileUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * Created in order to fix previous builds that we're build with HP/HPE convention plugin and move them to Micro Focus + */ +public class JobConfigRebrander extends Builder implements SimpleBuildStep { + private static final String MICROFOCUS = ".microfocus."; + private static final String HPE_HP_REGEX = "\\.hp\\.|\\.hpe\\."; + + private Run build; + + @DataBoundConstructor + public JobConfigRebrander() { + // A class which extends Builder should supply an empty constructor. + } + + /** + * Run this step. + * + * @param run a build this is running as a part of + * @param workspace a workspace to use for any file operations + * @param launcher a way to start processes + * @param listener a place to send output + * @throws InterruptedException if the step is interrupted + */ + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException{ + build = run; + File root = Jenkins.getInstance().getRootDir(); + convertXmlFilesAtRootDir(listener, root); + File projectsDir = new File(root,"jobs"); + File[] subdirs = projectsDir.listFiles(); + + for (final File subdir : subdirs) { + convertSpecifiedXmlFile(listener, subdir, "config.xml"); + final File buildsFolder = new File(subdir, "builds"); + File[] builds = buildsFolder.listFiles(); + + if(builds != null) { + for (final File buildDir : builds) { + convertSpecifiedXmlFile(listener, buildDir, "build.xml"); + } + } + } + } + + /** + * Creates XML file of the file we want to convert. + * And calls {@link JobConfigRebrander#convertOldNameToNewName(TaskListener, XmlFile)} + * to convert from all the old package names. + * @param listener A place to send log output + * @param dir The directory which we create the file + * @param xmlFileName The XML file name + */ + private void convertSpecifiedXmlFile(@Nonnull TaskListener listener, File dir, String xmlFileName) { + XmlFile xmlFile = new XmlFile(new File(dir, xmlFileName)); + if (xmlFile.exists()) { + convertOldNameToNewName(listener, xmlFile); + } + } + + /** + * Converts xml files which is located in the root directory + * That is responsible for the configuration files located at the "Manage Jenkins -> Configure System". + * @param listener a place to send log output + * @param root the root directory + */ + private void convertXmlFilesAtRootDir(@Nonnull TaskListener listener, File root) { + try { + File[] files = root.listFiles(pathname -> { + String name = pathname.getName().toLowerCase(); + return (name.startsWith("com.hpe") || name.startsWith("com.hp")) && name.endsWith(".xml") && pathname.isFile(); + }); + + for (File file: files) { + String newFileName = file.toString().replaceAll(HPE_HP_REGEX, MICROFOCUS); + File replacedFile = new File(newFileName); + + removeXmlFileIfExists(listener, newFileName, replacedFile); + convertXmlFileIfNotExists(listener, file, replacedFile); + } + } catch (SecurityException | NullPointerException e) { + listener.error("Failed to convert Global Settings configurations to microfocus: %s", e.getMessage()); + build.setResult(Result.FAILURE); + } + } + + private void convertXmlFileIfNotExists(@Nonnull TaskListener listener, File file, File replacedFile) { + if (!replacedFile.exists() && file.renameTo(replacedFile)) { + XmlFile xmlFile = new XmlFile(replacedFile); + convertOldNameToNewName(listener, xmlFile); + } + } + + /** + * There are files which can be auto-generated as empty after the package name change. + * We need to remove them in order to let the + * {@link JobConfigRebrander#convertXmlFileIfNotExists(TaskListener, File, File)} do the convert. + * @param listener a place to send log output + * @param newFileName the new file absolute path + * @param replacedFile the new file name which we need to remove + */ + private void removeXmlFileIfExists(@Nonnull TaskListener listener, String newFileName, File replacedFile) { + if (replacedFile.exists()) { + try { + Files.delete(Paths.get(replacedFile.getAbsolutePath())); + } catch (IOException | SecurityException e) { + listener.error("Failed to delete %s when doing Global Settings configurations convert: %s", + newFileName, e.getMessage()); + build.setResult(Result.UNSTABLE); + } + } + } + + /** + * Replace all occurrences of {@code oldName} of a given XML file. + * @param listener A place to send log output + * @param confXmlFile The XML file which we convert + * @see XmlFile + */ + private void convertOldNameToNewName(@Nonnull TaskListener listener, XmlFile confXmlFile) { + try { + String configuration = FileUtils.readFileToString(confXmlFile.getFile()); + String newConfiguration = configuration.replaceAll(HPE_HP_REGEX, MICROFOCUS); + FileUtils.writeStringToFile(confXmlFile.getFile(), newConfiguration); + } catch (IOException e) { + listener.error("Failed to convert job configuration format to microfocus: %s", e.getMessage()); + build.setResult(Result.FAILURE); + } + } + + + @Extension + public static class Descriptor extends BuildStepDescriptor { + + public Descriptor() { + load(); + } + + @Override + public String getDisplayName() { + return "Fix old OpenText Jenkins builds"; + } + + @Override + public boolean isApplicable(Class aClass) { + return false; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/LrScriptResultsParser.java b/src/main/java/com/microfocus/application/automation/tools/run/LrScriptResultsParser.java new file mode 100644 index 0000000000..67c3d6985e --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/LrScriptResultsParser.java @@ -0,0 +1,281 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import hudson.FilePath; +import hudson.model.TaskListener; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * Created by YafimK on 22/03/2017. + */ + +/** + * LR Script result xml paser - convers the results XML to JUNIT + */ +public class LrScriptResultsParser { + + + /** + * The constant LR_SCRIPT_RESULT_FILENAME. + */ + public static final String LR_SCRIPT_RESULT_FILENAME = "Results.xml"; + public static final String LR_SCRIPT_PASSED_STATUS = "Passed"; + public static final String LR_SCRIPT_REPORT_PASSED_STATUS = "passed"; + public static final String LR_SCRIPT_REPORT_FAILED_STATUS = "failed"; + private TaskListener _logger; + private String _scriptName; + + public LrScriptResultsParser(TaskListener listener) { + this._logger = listener; + } + + /** + * Parse script result. + * + * @param scriptName the script name + * @param workspace the workspace + * @throws InterruptedException the interrupted exception + */ + public void parseScriptResult(String scriptName, + FilePath workspace) + throws InterruptedException { + this._scriptName = scriptName; + invoke(workspace); + } + + /** + * Invoke void. + * + * @param ws_filePath the ws file path + * @return the void + * @throws IOException the io exception + * @throws InterruptedException the interrupted exception + */ + public void invoke(FilePath ws_filePath) throws InterruptedException { + FilePath sourceFile = ws_filePath.child(this._scriptName).child(LR_SCRIPT_RESULT_FILENAME); + FilePath targetFile = ws_filePath.child(this._scriptName).child("JunitResult.xml"); + parse(sourceFile, targetFile); + } + + /** + * Parse. + * + * @param scriptName the script name + * @param outputFile the output file + */ + public void parse(FilePath scriptName, FilePath outputFile) throws InterruptedException { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = null; + Document doc; + Document newDoc; + try { + dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(scriptName.read()); + + newDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + + doc.getDocumentElement().normalize(); + NodeList actionNodes = doc.getElementsByTagName("Action"); + + Element testSuits = newDoc.createElement("testsuites"); + parseScriptAction(newDoc, actionNodes, testSuits, scriptName.getParent().getBaseName()); + Element reportSummaryNode = (Element) doc.getElementsByTagName("Summary").item(actionNodes.getLength()); + testSuits.setAttribute( + LR_SCRIPT_REPORT_PASSED_STATUS, reportSummaryNode.getAttribute(LR_SCRIPT_REPORT_PASSED_STATUS)); + testSuits.setAttribute("failures", reportSummaryNode.getAttribute(LR_SCRIPT_REPORT_FAILED_STATUS)); + testSuits.setAttribute("name", scriptName.getParent().getBaseName()); + testSuits.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); + testSuits.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); + int tests = + Integer.parseInt(reportSummaryNode.getAttribute(LR_SCRIPT_REPORT_FAILED_STATUS)) + + Integer.parseInt(reportSummaryNode + .getAttribute(LR_SCRIPT_REPORT_PASSED_STATUS)); + testSuits.setAttribute("tests", String.valueOf(tests)); + newDoc.appendChild(testSuits); + newDoc.setXmlVersion("1.0"); + + TransformerFactory tFactory = + TransformerFactory.newInstance(); + Transformer transformer = + tFactory.newTransformer(); + + DOMSource source = new DOMSource(newDoc); + StreamResult result = new StreamResult(outputFile.write()); + + transformer.transform(source, result); + } catch (SAXException e) { + log("XML reader error"); + log(e); + } catch (ParserConfigurationException e) { + log("XML parser error"); + log(e); + } catch (IOException e) { + log("IO error"); + log(e); + } catch (TransformerConfigurationException tce) { + log("* Transformer Factory error"); + log(" " + tce.getMessage()); + + Throwable x = tce; + if (tce.getException() != null) { + x = tce.getException(); + } + log(x); + } catch (TransformerException te) { + log("* Transformation error"); + log(" " + te.getMessage()); + + Throwable x = te; + if (te.getException() != null) { + x = te.getException(); + } + log(x); + } + } + + private void log(Object msg) { + _logger.error(msg.toString()); + } + + private static void parseScriptAction(Document newDoc, NodeList actionNodes, Element rootnode, String scriptName) { + for (int i = 0; i < actionNodes.getLength(); i++) { + + Element action = (Element) actionNodes.item(i); + + + NodeList actionProps = action.getElementsByTagName("AName"); + Element actionName = (Element) actionProps.item(0); + + Element testSuite = newDoc.createElement("testsuite"); + final String suiteName = getCharacterDataFromElement(actionName); + testSuite.setAttribute("name", suiteName); + + NodeList stepNodes = action.getElementsByTagName("Step"); + parseScriptActionStep(newDoc, testSuite, stepNodes, scriptName + "." + suiteName); + + Element suiteSummaryNode = (Element) action.getElementsByTagName("Summary").item(0); + testSuite.setAttribute( + LR_SCRIPT_REPORT_PASSED_STATUS, suiteSummaryNode.getAttribute(LR_SCRIPT_REPORT_PASSED_STATUS)); + testSuite.setAttribute("failures", suiteSummaryNode.getAttribute(LR_SCRIPT_REPORT_FAILED_STATUS)); + int tests = + Integer.parseInt(suiteSummaryNode.getAttribute(LR_SCRIPT_REPORT_FAILED_STATUS)) + + Integer.parseInt(suiteSummaryNode.getAttribute(LR_SCRIPT_REPORT_PASSED_STATUS)); + testSuite.setAttribute("package", scriptName); + + testSuite.setAttribute("tests", String.valueOf(tests)); + if (tests > 0) { + rootnode.appendChild(testSuite); + } + } + } + + private static void parseScriptActionStep(Document newDoc, Element testSuite, NodeList stepNodes, + String className) { + for (int j = 0; j < stepNodes.getLength(); j++) { + Element step = (Element) stepNodes.item(j); + Element objNode = (Element) step.getElementsByTagName("Obj").item(0); + Element testCase = newDoc.createElement("testcase"); + testCase.setAttribute("name", getStepDataFromElement(objNode)); + Element nodeArgs = (Element) step.getElementsByTagName("NodeArgs").item(0); + String stepStatus = nodeArgs.getAttribute("status"); + if (stepStatus.equals(LR_SCRIPT_PASSED_STATUS)) { + stepStatus = "pass"; + } else { + stepStatus = "fail"; + Element failureMessage = newDoc.createElement("failure"); + failureMessage.setAttribute("message", ""); + + testCase.appendChild(failureMessage); + } + testCase.setAttribute("status", stepStatus); + testCase.setAttribute("classname", className); + + testSuite.appendChild(testCase); + } + } + + private static String getStepDataFromElement(Element e) { + String stepName = getCharacterDataFromElement(e); + stepName = stepName.replace("Url: ", ""); + + return stepName; + } + + private static String getCharacterDataFromElement(Element e) { + Node child = e.getFirstChild(); + if (child instanceof CharacterData) { + CharacterData cd = (CharacterData) child; + return cd.getData(); + } + return ""; + } + + /** + * Parse. + * + * @param scriptName the script name + * @param outputFile the output file + * @throws FileNotFoundException the file not found exception + */ + public void parse(File scriptName, File outputFile) throws InterruptedException { + parse(new FilePath(scriptName.getAbsoluteFile()), new FilePath(outputFile.getAbsoluteFile())); + } + + /** + * Sets script name. + * + * @param _scriptName the script name + */ + public void setScriptName(String _scriptName) { + this._scriptName = _scriptName; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/MigrateAlmCredentialsBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/MigrateAlmCredentialsBuilder.java new file mode 100644 index 0000000000..f69a07efad --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/MigrateAlmCredentialsBuilder.java @@ -0,0 +1,166 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.microfocus.application.automation.tools.model.*; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; + +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; + +public class MigrateAlmCredentialsBuilder extends Recorder implements Serializable, SimpleBuildStep { + + + + @DataBoundConstructor + public MigrateAlmCredentialsBuilder() {} + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener taskListener) throws InterruptedException, IOException { + if(!isMigrationDone()) { + scanJobs(taskListener); + } else { + taskListener.getLogger().println("ALM credentials have been already migrated to Jenkins Configure page."); + } + } + + public static void scanJobs(TaskListener listener) { + List jobs = Jenkins.getInstanceOrNull().getAllItems(Project.class); + + List models = Arrays.asList(AlmServerSettingsGlobalConfiguration.getInstance().getInstallations()); + + Multimap serverUsernames = ArrayListMultimap.create(); + Multimap serverClientIds = ArrayListMultimap.create(); + + for (Project job : jobs) { + List builders = job.getBuilders(); + if (builders != null) { + for (Builder builder : builders) { + if (builder instanceof RunFromAlmBuilder) { + RunFromAlmBuilder almBuilder = (RunFromAlmBuilder) builder; + String almUsername = almBuilder.runFromAlmModel.getAlmUserName(); + String almClientID = almBuilder.runFromAlmModel.getAlmClientID(); + if(!StringUtils.isNullOrEmpty(almUsername) || !StringUtils.isNullOrEmpty(almClientID)) { + listener.getLogger().println("Migrating credentials from task " + job.getDisplayName()); + + for (AlmServerSettingsModel model : models) { + if (model.getAlmServerName().equals(almBuilder.getAlmServerName())) { + if (!StringUtils.isNullOrEmpty(almUsername) && !serverUsernames.get(model.getAlmServerName()).contains(almUsername) && + !almUsername.equals(UftConstants.NO_USERNAME_DEFINED) && almBuilder.runFromAlmModel.getAlmPassword() != null) { + String almPassword = almBuilder.runFromAlmModel.getAlmPassword().getPlainText(); + serverUsernames.put(model.getAlmServerName(), almUsername); + model.set_almCredentials(Arrays.asList(new CredentialsModel(almUsername, almPassword))); + listener.getLogger().println("Migrating username '" + almUsername + "' 'for server: " + model.getAlmServerName() + ", " + model.getAlmServerUrl()); + } + + if (!StringUtils.isNullOrEmpty(almClientID) && !serverClientIds.get(model.getAlmServerName()).contains(almClientID) && + !almClientID.equals(UftConstants.NO_CLIENT_ID_DEFINED) && almBuilder.runFromAlmModel.getAlmApiKey() != null) { + String almApiKeySecret = almBuilder.runFromAlmModel.getAlmApiKey().getPlainText(); + serverClientIds.put(model.getAlmServerName(), almClientID); + model.set_almSSOCredentials(Arrays.asList(new SSOCredentialsModel(almClientID, almApiKeySecret))); + listener.getLogger().println("Migrating client ID '" + almClientID + "' for server: " + model.getAlmServerName() + ", " + model.getAlmServerUrl()); + } + + + try { + job.save(); + } catch (IOException e) { + listener.getLogger().println("Job not saved."); + } + + listener.getLogger().println("------------------------------"); + } + } + } + } + } + } + } + } + + public Boolean isMigrationDone(){ + List models = Arrays.asList(AlmServerSettingsGlobalConfiguration.getInstance().getInstallations()); + for(AlmServerSettingsModel model : models){ + if (model != null && (!model.getAlmCredentials().isEmpty() || !model.getAlmSSOCredentials().isEmpty())) { + return true; + } + } + + return false; + } + + + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { + + load(); + } + + @Override + public String getDisplayName() { + + return "Migrate ALM Credentials"; + } + + @Override + public boolean isApplicable(@SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/PcBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/PcBuilder.java new file mode 100644 index 0000000000..87c8bc8335 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/PcBuilder.java @@ -0,0 +1,1301 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +/* + * Create the PCModel and the PCClient and allows the connection between the job and PC + * */ +package com.microfocus.application.automation.tools.run; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.cloudbees.plugins.credentials.matchers.IdMatcher; +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; +import com.microfocus.application.automation.tools.pc.PcClient; +import com.microfocus.application.automation.tools.pc.PcModel; +import com.microfocus.application.automation.tools.pc.helper.DateFormatter; +import com.microfocus.application.automation.tools.sse.result.model.junit.Error; +import com.microfocus.application.automation.tools.sse.result.model.junit.Failure; +import com.microfocus.application.automation.tools.sse.result.model.junit.*; +import com.thoughtworks.xstream.XStream; +import hudson.*; +import hudson.console.HyperlinkNote; +import hudson.model.Queue; +import hudson.model.*; +import hudson.model.queue.Tasks; +import hudson.security.ACL; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.LogTaskListener; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; +import org.apache.http.client.ClientProtocolException; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.beans.IntrospectionException; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.logging.Level; + +import static com.microfocus.adm.performancecenter.plugins.common.pcentities.RunState.FINISHED; +import static com.microfocus.adm.performancecenter.plugins.common.pcentities.RunState.RUN_FAILURE; + +public class PcBuilder extends Builder implements SimpleBuildStep { + + public static final String artifactsResourceName = "artifact"; + public static final String runReportStructure = "%s/%s/performanceTestsReports/pcRun"; + public static final String trendReportStructure = "%s/%s/performanceTestsReports/TrendReports"; + public static final String pcReportArchiveName = "Reports.zip"; + public static final String pcReportFileName = "Report.html"; + public static final String TRENDED = "Trended"; + public static final String PENDING = "Pending"; + public static final String PUBLISHING = "Publishing"; + public static final String ERROR = "Error"; + private static final String artifactsDirectoryName = "archive"; + private static final String RUNID_BUILD_VARIABLE = "PC_RUN_ID"; + public static UsernamePasswordCredentials usernamePCPasswordCredentials; + public static UsernamePasswordCredentials usernamePCPasswordCredentialsForProxy; + private transient static Run _run; + private static PrintStream logger; + private final String timeslotDurationHours; + private final String timeslotDurationMinutes; + private final boolean statusBySLA; + private PcModel pcModel; + private String serverAndPort; + private String pcServerName; + private String credentialsId; + private String almDomain; + private String almProject; + private String testId; + private String testInstanceId; + private String autoTestInstanceID; + private PostRunAction postRunAction; + private boolean vudsMode; + private String description; + private String addRunToTrendReport; + private String trendReportId; + private boolean HTTPSProtocol; + private String proxyOutURL; + private String credentialsProxyId; + private String retry; + private String retryDelay; + private String retryOccurrences; + private boolean authenticateWithToken; + private int runId; + private String testName; + private FilePath pcReportFile; + private String junitResultsFileName; + private File WorkspacePath; + private FilePath Workspace; + private DateFormatter dateFormatter = new DateFormatter(""); + + @DataBoundConstructor + public PcBuilder( + String serverAndPort, + String pcServerName, + String credentialsId, + String almDomain, + String almProject, + String testId, + String testInstanceId, + String autoTestInstanceID, + String timeslotDurationHours, + String timeslotDurationMinutes, + PostRunAction postRunAction, + boolean vudsMode, + boolean statusBySLA, + String description, + String addRunToTrendReport, + String trendReportId, + boolean HTTPSProtocol, + String proxyOutURL, + String credentialsProxyId, + String retry, + String retryDelay, + String retryOccurrences, + boolean authenticateWithToken) { + + this.serverAndPort = serverAndPort; + this.pcServerName = pcServerName; + this.credentialsId = credentialsId; + this.almDomain = almDomain; + this.almProject = almProject; + this.testId = testId; + this.testInstanceId = testInstanceId; + this.autoTestInstanceID = autoTestInstanceID; + this.timeslotDurationHours = timeslotDurationHours; + this.timeslotDurationMinutes = timeslotDurationMinutes; + this.postRunAction = postRunAction; + this.vudsMode = vudsMode; + this.statusBySLA = statusBySLA; + this.description = description; + this.addRunToTrendReport = addRunToTrendReport; + this.trendReportId = trendReportId; + this.HTTPSProtocol = HTTPSProtocol; + this.proxyOutURL = proxyOutURL; + this.credentialsProxyId = credentialsProxyId; + this.retry = (retry == null || retry.isEmpty()) ? "NO_RETRY" : retry; + this.retryDelay = ("NO_RETRY".equals(this.retry)) ? "0" : (retryDelay == null || retryDelay.isEmpty()) ? "5" : retryDelay; + this.retryOccurrences = ("NO_RETRY".equals(this.retry)) ? "0" : (retryOccurrences == null || retryOccurrences.isEmpty()) ? "3" : retryOccurrences; + this.authenticateWithToken = authenticateWithToken; + } + + public static UsernamePasswordCredentials getCredentialsId(String credentialsId) { + if (credentialsId != null && _run != null) + return getCredentialsById(credentialsId, _run, logger); + return null; + } + + public static UsernamePasswordCredentials getCredentialsProxyId(String credentialsProxyId) { + if (credentialsProxyId != null && _run != null) + return getCredentialsById(credentialsProxyId, _run, logger); + return null; + } + + private static UsernamePasswordCredentials getCredentialsById(String credentialsId, Run run, PrintStream logger) { + if (StringUtils.isBlank(credentialsId)) + return null; + + UsernamePasswordCredentials usernamePCPasswordCredentials = CredentialsProvider.findCredentialById(credentialsId, + StandardUsernamePasswordCredentials.class, + run, + URIRequirementBuilder.create().build()); + + if (usernamePCPasswordCredentials == null) { + logger.println(String.format("%s : %s", + Messages.CannotFindCredentials(), + credentialsId)); + } + + return usernamePCPasswordCredentials; + } + + public static String getArtifactsDirectoryName() { + + return artifactsDirectoryName; + } + + public static String getArtifactsResourceName() { + + return artifactsResourceName; + } + + public static String getRunReportStructure() { + + return runReportStructure; + } + + public static String getPcReportArchiveName() { + + return pcReportArchiveName; + } + + public static String getPcreportFileName() { + + return pcReportFileName; + } + + public static String getPluginVersion() { + Plugin plugin = getJenkinsInstance().getPlugin(Messages.ArtifactId()); + return plugin.getWrapper().getVersion(); + } + + private static Jenkins getJenkinsInstance() { + Jenkins result = Jenkins.getInstance(); + if (result == null) { + throw new IllegalStateException(Messages.FailedToObtainInstance()); + } + return result; + } + + @Override + public DescriptorImpl getDescriptor() { + + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) + throws InterruptedException, IOException { + if (build.getWorkspace() != null) + WorkspacePath = new File(build.getWorkspace().toURI()); + else + WorkspacePath = null; + if ((getPcModel() != null) && (build != null) && (build instanceof AbstractBuild)) + setPcModelBuildParameters(build, listener); + if (build.getWorkspace() != null) + perform(build, build.getWorkspace(), launcher, listener); + else + return false; + return true; + } + + private void setPcModelBuildParameters(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { + Map mapParamsAndEnvars = new HashMap(); + Map buildParameters = build.getBuildVariables(); + mapParamsAndEnvars.putAll(buildParameters); + if (listener != null) { + Map buildEnvars = build.getEnvironment(listener); + mapParamsAndEnvars.putAll(buildEnvars); + } else { + Map buildEnvars = build.getEnvironment(new LogTaskListener(null, Level.INFO)); + mapParamsAndEnvars.putAll(buildEnvars); + } + String buildParametersAndEnvars = mapParamsAndEnvars.toString(); + if (!buildParameters.isEmpty()) + getPcModel().setBuildParameters(buildParametersAndEnvars); + } + + public File getWorkspacePath() { + return WorkspacePath; + } + + public String getCredentialsId() { + return credentialsId; + } + + public void setCredentialsId(String newCredentialsId) { + credentialsId = newCredentialsId; + pcModel = null; + getPcModel(); + } + + public String getCredentialsProxyId() { + return credentialsProxyId; + } + + public void setCredentialsProxyId(String newCredentialsProxyId) { + credentialsProxyId = newCredentialsProxyId; + pcModel = null; + getPcModel(); + } + + //pcModel is intialized here. + public PcModel getPcModel() { + if (pcModel == null) { + pcModel = + new PcModel( + serverAndPort.trim(), + pcServerName.trim(), + credentialsId, + almDomain.trim(), + almProject.trim(), + testId.trim(), + autoTestInstanceID, + testInstanceId.trim(), + timeslotDurationHours.trim(), + timeslotDurationMinutes.trim(), + postRunAction, + vudsMode, + description, + addRunToTrendReport, + trendReportId, + HTTPSProtocol, + proxyOutURL, + credentialsProxyId, + retry, + retryDelay, + retryOccurrences, + authenticateWithToken); + } + return pcModel; + } + + public String getRunResultsFileName() { + + return junitResultsFileName; + } + + private void setBuildParameters(AbstractBuild build) { + try { + if (build != null && build.getBuildVariables() != null) + getPcModel().setBuildParameters(build.getBuildVariables().toString()); + } catch (Exception ex) { + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.BuildParameterNotConsidered(), + ex.getMessage())); + } + } + + private String getVersion() { + String completeVersion = getPluginVersion(); + if (completeVersion != null) { + String[] partsOfCompleteVersion = completeVersion.split(" [(]"); + return partsOfCompleteVersion[0]; + } + return "unknown"; + } + + private Testsuites execute(PcClient pcClient, Run build) + throws InterruptedException, NullPointerException { + _run = build; + try { + String version = getVersion(); + if (!(version == null || version.equals("unknown"))) + logger.println(String.format("%s - %s '%s'", + dateFormatter.getDate(), + Messages.PluginVersionIs(), + version)); + if ((getPcModel() != null) && (build != null) && (build instanceof AbstractBuild)) + setPcModelBuildParameters((AbstractBuild) build, null); + if (!StringUtils.isBlank(getPcModel().getDescription())) + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.TestDescription(), + getPcModel().getDescription())); + if (!beforeRun(pcClient)) + return null; + + return run(pcClient, build); + + } catch (InterruptedException e) { + build.setResult(Result.ABORTED); + pcClient.stopRun(runId); + throw e; + } catch (NullPointerException e) { + logger.println(String.format("%s - %s: %s", + dateFormatter.getDate(), + Messages.Error(), + e.getMessage())); + } catch (Exception e) { + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + e.getMessage())); + } finally { + pcClient.logout(); + } + return null; + } + + private Testsuites run(PcClient pcClient, Run build) + throws InterruptedException, ClientProtocolException, + IOException, PcException { + if ((getPcModel() != null) && (build != null) && (build instanceof AbstractBuild)) + setPcModelBuildParameters((AbstractBuild) build, null); + PcRunResponse response = null; + String errorMessage = ""; + String eventLogString = ""; + boolean trendReportReady = false; + try { + runId = pcClient.startRun(); + if (runId == 0) + return null; + } catch (NumberFormatException | ClientProtocolException | PcException ex) { + logger.println(String.format("%s - %s. %s: %s", + dateFormatter.getDate(), + Messages.StartRunFailed(), + Messages.Error(), + ex.getMessage())); + throw ex; + } catch (IOException ex) { + logger.println(String.format("%s - %s. %s: %s", + dateFormatter.getDate(), + Messages.StartRunFailed(), + Messages.Error(), + ex.getMessage())); + throw ex; + } + + //getTestName failure should not fail test execution. + try { + testName = pcClient.getTestName(); + if (testName == null) { + testName = String.format("TestId_%s", getPcModel().getTestId()); + logger.println(String.format("%s - getTestName failed. Using '%s' as testname.", + dateFormatter.getDate(), + testName)); + } else + logger.println(String.format("%s - %s %s", + dateFormatter.getDate(), + Messages.TestNameIs(), + testName)); + } catch (PcException | IOException ex) { + testName = String.format("TestId_%s", getPcModel().getTestId()); + logger.println(String.format("%s - getTestName failed. Using '%s' as testname. Error: %s \n", + dateFormatter.getDate(), + testName, + ex.getMessage())); + } + + try { + List parameters = new ArrayList<>(); + parameters.add(new StringParameterValue(RUNID_BUILD_VARIABLE, "" + runId)); + // This allows a user to access the runId from within Jenkins using a build variable. + build.addAction(new AdditionalParametersAction(parameters)); + logger.print(String.format("%s - %s: %s = %s \n", + dateFormatter.getDate(), + Messages.SetEnvironmentVariable(), + RUNID_BUILD_VARIABLE, + runId)); + response = pcClient.waitForRunCompletion(runId); + + if (response != null && RunState.get(response.getRunState()) == FINISHED && getPcModel().getPostRunAction() != PostRunAction.DO_NOTHING) { + pcReportFile = pcClient.publishRunReport(runId, getReportDirectory(build)); + + // Adding the trend report section if ID has been set or if the Associated Trend report is selected. + if (((("USE_ID").equals(getPcModel().getAddRunToTrendReport()) && getPcModel().getTrendReportId(true) != null) || ("ASSOCIATED").equals(getPcModel().getAddRunToTrendReport())) && RunState.get(response.getRunState()) != RUN_FAILURE) { + Thread.sleep(5000); + pcClient.addRunToTrendReport(this.runId, getPcModel().getTrendReportId(true)); + pcClient.waitForRunToPublishOnTrendReport(this.runId, getPcModel().getTrendReportId(true)); + pcClient.downloadTrendReportAsPdf(getPcModel().getTrendReportId(true), getTrendReportsDirectory(build)); + trendReportReady = true; + } + + } else if (response != null && RunState.get(response.getRunState()).ordinal() > FINISHED.ordinal()) { + PcRunEventLog eventLog = pcClient.getRunEventLog(runId); + eventLogString = buildEventLogString(eventLog); + } + + } catch (PcException e) { + logger.println(String.format("%s - Error: %s", + dateFormatter.getDate(), + e.getMessage())); + } + + Testsuites ret = new Testsuites(); + parsePcRunResponse(ret, response, build, errorMessage, eventLogString); + try { + parsePcTrendResponse(ret, build, pcClient, trendReportReady, getPcModel().getTrendReportId(true), runId); + } catch (IntrospectionException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + return ret; + } + + private String buildEventLogString(PcRunEventLog eventLog) { + + String logFormat = "%-5s | %-7s | %-19s | %s\n"; + StringBuilder eventLogStr = new StringBuilder("Event Log:\n\n" + String.format(logFormat, "ID", "TYPE", "TIME", "DESCRIPTION")); + for (PcRunEventLogRecord record : eventLog.getRecordsList()) { + eventLogStr.append(String.format(logFormat, record.getID(), record.getType(), record.getTime(), record.getDescription())); + } + return eventLogStr.toString(); + } + + private boolean beforeRun(PcClient pcClient) { + return validatePcForm() && pcClient.login(); + } + + private String getReportDirectory(Run build) { + return String.format( + runReportStructure, + build.getRootDir().getPath(), + artifactsDirectoryName); + } + + private String getTrendReportsDirectory(Run build) { + return String.format( + trendReportStructure, + build.getRootDir().getPath(), + artifactsDirectoryName); + } + + + @Override + @Deprecated + public boolean perform(Build build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + return super.perform(build, launcher, listener); + } + + private boolean validatePcForm() { + + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + Messages.ValidatingParametersBeforeRun())); + String prefix = "doCheck"; + boolean ret = true; + Method[] methods = getDescriptor().getClass().getMethods(); + Method[] modelMethods = getPcModel().getClass().getMethods(); + for (Method method : methods) { + String name = method.getName(); + if (name.startsWith(prefix)) { + name = name.replace(prefix, "").toLowerCase(); + for (Method modelMethod : modelMethods) { + String modelMethodName = modelMethod.getName(); + if (modelMethodName.toLowerCase().equals("get" + name) && modelMethod.getParameterTypes().length == 0) { + try { + Object obj = FormValidation.ok(); + if (!("testinstanceid".equals(name) && "AUTO".equals(getPcModel().getAutoTestInstanceID())) + && !(("retrydelay".equals(name) && "NO_RETRY".equals(getPcModel().getRetry())) || getPcModel().getRetry().isEmpty()) + && !(("retryoccurrences".equals(name) && "NO_RETRY".equals(getPcModel().getRetry())) || getPcModel().getRetry().isEmpty()) + ) { + if ("doCheckCredentialsId".equals(method.getName()) && "credentialsid".equals(name) && "getCredentialsId".equals(modelMethodName) + || "doCheckCredentialsProxyId".equals(method.getName()) && "credentialsproxyid".equals(name) && "getCredentialsProxyId".equals(modelMethodName) + ) + obj = method.invoke(getDescriptor(), null, null, modelMethod.invoke(getPcModel())); + else + obj = method.invoke(getDescriptor(), modelMethod.invoke(getPcModel())); + } + if (!obj.equals(FormValidation.ok())) { + logger.println(obj); + ret = false; + } + break; + } catch (Exception e) { + logger.println(String.format("%s - Validation error: method.getName() = '%s', name = '%s', modelMethodName = '%s', exception = '%s'.", + dateFormatter.getDate(), + method.getName(), + name, + modelMethodName, + e.getMessage())); + } + } + } + } + } + + boolean isTrendReportIdValid = validateTrendReportIdIsNumeric(getPcModel().getTrendReportId(true), ("USE_ID").equals(getPcModel().getAddRunToTrendReport())); + + ret &= isTrendReportIdValid; + return ret; + + } + + + private boolean validateTrendReportIdIsNumeric(String trendReportId, boolean addRunToTrendReport) { + + FormValidation res = FormValidation.ok(); + if (addRunToTrendReport) { + if (trendReportId.isEmpty()) { + res = FormValidation.error(String.format("%s: %s.", + Messages.ParameterIsMissing(), + Messages.TrendReportIDIsMissing())); + } else { + + try { + + Integer.parseInt(trendReportId); + } catch (NumberFormatException e) { + + res = FormValidation.error(Messages.IllegalParameter()); + } + + } + } + + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + res.toString().replace(":

", ""))); + + return res.equals(FormValidation.ok()); + } + + private Testsuites parsePcRunResponse(Testsuites ret, + PcRunResponse runResponse, + Run build, + String errorMessage, String eventLogString) throws IOException, InterruptedException { + + RunState runState = RunState.get(runResponse.getRunState()); + + + List testSuites = ret.getTestsuite(); + Testsuite testSuite = new Testsuite(); + Testcase testCase = new Testcase(); + //testCase.setClassname("Performance Tests.Test ID: " + runResponse.getTestID()); + testCase.setClassname("Performance Test.Load Test"); + testCase.setName(testName + "(ID:" + runResponse.getTestID() + ")"); + testCase.setTime(String.valueOf(runResponse.getDuration() * 60)); + if (pcReportFile != null && pcReportFile.exists() && runState == FINISHED) { + testCase.getSystemOut().add(getOutputForReportLinks(build)); + } + updateTestStatus(testCase, runResponse, errorMessage, eventLogString); + testSuite.getTestcase().add(testCase); + testSuite.setName("Performance Test ID: " + runResponse.getTestID() + ", Run ID: " + runResponse.getID()); + testSuites.add(testSuite); + return ret; + } + + private Testsuites parsePcTrendResponse(Testsuites ret, Run build, PcClient pcClient, boolean trendReportReady, String TrendReportID, int runID) throws PcException, IntrospectionException, IOException, InterruptedException, NoSuchMethodException { + + + if (trendReportReady) { + String reportUrlTemp = trendReportStructure.replaceFirst("%s/", "") + "/trendReport%s.pdf"; + String reportUrl = String.format(reportUrlTemp, artifactsResourceName, getPcModel().getTrendReportId(true)); + pcClient.publishTrendReport(reportUrl, getPcModel().getTrendReportId(true)); + + // Updating all CSV files for plot plugin + // this helps to show the transaction of each result + if (isPluginActive("Plot plugin")) { + logger.println(String.format("%s %s.", + dateFormatter.getDate(), + Messages.UpdatingCsvFilesForTrendingCharts())); + updateCSVFilesForPlot(pcClient, runID); + String plotUrlPath = "/job/" + build.getParent().getName() + "/plot"; + logger.println(String.format("%s - %s", + dateFormatter.getDate(), + HyperlinkNote.encodeTo(plotUrlPath, Messages.TrendingCharts()))); + } else { + logger.println(String.format("%s - %s %s (%s).", + dateFormatter.getDate(), + Messages.YouCanViewTrendCharts(), + HyperlinkNote.encodeTo("https://admhelp.microfocus.com/lre/en/2023-2023-r1/online_help/Content/PC/Continuous-Integration-Jenkins.htm#mt-item-4", Messages.Documentation()), + Messages.PerformanceCenter1255AndLater())); + } + } + return ret; + } + + private boolean isPluginActive(String pluginDisplayName) { + List allPlugin = Jenkins.get().pluginManager.getPlugins(); + for (PluginWrapper pw : + allPlugin) { + + if (pw.getDisplayName().toLowerCase().equals(pluginDisplayName.toLowerCase())) { + return pw.isActive(); + } + } + return false; + } + + private void updateCSVFilesForPlot(PcClient pcClient, int runId) throws IOException, PcException, IntrospectionException, NoSuchMethodException { + + TriTrendReportTypes triTrendReportTypes[] = { + // Transaction - TRT + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_MINIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_MAXIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_AVERAGE), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_MEDIAN), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_STDDEVIATION), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_COUNT1), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_PERCENTILE_90), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRT, TrendReportTypes.Measurement.PCT_PERCENTILE_95), + // Transaction - TPS + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TPS, TrendReportTypes.Measurement.PCT_MINIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TPS, TrendReportTypes.Measurement.PCT_MAXIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TPS, TrendReportTypes.Measurement.PCT_AVERAGE), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TPS, TrendReportTypes.Measurement.PCT_MEDIAN), + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TPS, TrendReportTypes.Measurement.PCT_SUM1), + // Transaction - TRS + new TriTrendReportTypes(TrendReportTypes.DataType.Transaction, TrendReportTypes.PctType.TRS, TrendReportTypes.Measurement.PCT_COUNT1), + // Monitors - UDP + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_MINIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_MAXIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_AVERAGE), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_MEDIAN), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_STDDEVIATION), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_COUNT1), + new TriTrendReportTypes(TrendReportTypes.DataType.Monitors, TrendReportTypes.PctType.UDP, TrendReportTypes.Measurement.PCT_SUM1), + // Regular - VU + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.VU, TrendReportTypes.Measurement.PCT_MAXIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.VU, TrendReportTypes.Measurement.PCT_AVERAGE), + // Regular - WEB + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.WEB, TrendReportTypes.Measurement.PCT_MINIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.WEB, TrendReportTypes.Measurement.PCT_MAXIMUM), + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.WEB, TrendReportTypes.Measurement.PCT_AVERAGE), + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.WEB, TrendReportTypes.Measurement.PCT_MEDIAN), + new TriTrendReportTypes(TrendReportTypes.DataType.Regular, TrendReportTypes.PctType.WEB, TrendReportTypes.Measurement.PCT_SUM1) + }; + + for (TriTrendReportTypes triTrendReportType : triTrendReportTypes + ) { + saveFileToWorkspacePath(pcClient, getPcModel().getTrendReportId(true), runId, triTrendReportType.getDataType(), triTrendReportType.getPctType(), triTrendReportType.getMeasurement()); + } + + } + + private boolean saveFileToWorkspacePath(PcClient pcClient, String trendReportID, int runId, TrendReportTypes.DataType dataType, TrendReportTypes.PctType pctType, TrendReportTypes.Measurement measurement) throws IOException, PcException, IntrospectionException, NoSuchMethodException { + String fileName = measurement.toString().toLowerCase() + "_" + pctType.toString().toLowerCase() + ".csv"; + Map measurementMap = pcClient.getTrendReportByXML(trendReportID, runId, dataType, pctType, measurement); + try { + FilePath filePath = new FilePath(Workspace.getChannel(), getWorkspacePath().getPath() + "/" + fileName); + String filepathContent = ""; + for (String key : measurementMap.keySet()) { + filepathContent += key + ","; + } + filepathContent += "\r\n"; + for (String value : measurementMap.values()) { + filepathContent += value + ","; + } + filePath.write(filepathContent, null); + return true; + } catch (InterruptedException e) { + if (getWorkspacePath().getPath() != null) + logger.println(String.format("%s - %s: %s %s: %s. %s: %s", + dateFormatter.getDate(), + Messages.ErrorSavingFile(), + fileName, + Messages.ToWorkspacePath(), + getWorkspacePath().getPath(), + Messages.Error(), + e.getMessage())); + else + logger.println(String.format("%s - %s: %s. %s. %s: %s", + dateFormatter.getDate(), + Messages.ErrorSavingFile(), + fileName, + Messages.WorkspacePathIsUnavailable(), + Messages.Error(), + e.getMessage())); + return false; + } + } + + private void updateTestStatus(Testcase testCase, PcRunResponse response, String errorMessage, String eventLog) { + RunState runState = RunState.get(response.getRunState()); + if (runState == RUN_FAILURE) { + setError(testCase, + String.format("%s. %s", + runState, + errorMessage), + eventLog); + } else if (statusBySLA && runState == FINISHED && !(response.getRunSLAStatus().equalsIgnoreCase("passed"))) { + setFailure(testCase, Messages.RunMeasurementsNotReachSLACriteria() + ": " + + response.getRunSLAStatus(), eventLog); + } else if (runState.hasFailure()) { + setFailure(testCase, + String.format("%s. %s", + runState, + errorMessage), + eventLog); + } else if (errorMessage != null && !errorMessage.isEmpty()) { + setFailure(testCase, + String.format("%s. %s", + runState, + errorMessage), + eventLog); + } else { + testCase.setStatus(JUnitTestCaseStatus.PASS); + } + } + + private void setError(Testcase testCase, String message, String eventLog) { + Error error = new Error(); + error.setMessage(message); + if (!(eventLog == null || eventLog.isEmpty())) + testCase.getSystemErr().add(eventLog); + testCase.getError().add(error); + testCase.setStatus(JUnitTestCaseStatus.ERROR); + logger.println(String.format("%s - %s %s", + dateFormatter.getDate(), + message, + eventLog)); + } + + private void setFailure(Testcase testCase, String message, String eventLog) { + Failure failure = new Failure(); + failure.setMessage(message); + if (!(eventLog == null || eventLog.isEmpty())) + testCase.getSystemErr().add(eventLog); + testCase.getFailure().add(failure); + testCase.setStatus(JUnitTestCaseStatus.FAILURE); + logger.println(String.format("%s - %s: %s %s", + dateFormatter.getDate(), + Messages.Failure(), + message, + eventLog)); + } + + private String getOutputForReportLinks(Run build) { + String urlPattern = getArtifactsUrlPattern(build); + String viewUrl = String.format(urlPattern + "/%s", pcReportFileName); + String downloadUrl = String.format(urlPattern + "/%s", "*zip*/pcRun"); + logger.println(String.format("%s - %s", dateFormatter.getDate(), HyperlinkNote.encodeTo(viewUrl, Messages.ViewAnalysisReportOfRun() + " " + runId))); + + return String.format("%s: %s" + + "\n\n%s:\n%s" + + "\n\n%s:\n%s", + Messages.LoadTestRunID(), runId, + Messages.ViewAnalysisReport(), getPcModel().getserverAndPort() + "/" + build.getUrl() + viewUrl, + Messages.DownloadReport(), getPcModel().getserverAndPort() + "/" + build.getUrl() + downloadUrl); + } + + private String getArtifactsUrlPattern(Run build) { + + String runReportUrlTemp = runReportStructure.replaceFirst("%s/", ""); + return String.format( + runReportUrlTemp, + artifactsResourceName); + } + + private void provideStepResultStatus(Result resultStatus, Run build) { + String runIdStr = + (runId > 0) ? String.format(" (LRE RunID: %s)", String.valueOf(runId)) : ""; + logger.println(String.format("%s - %s%s: %s\n- - -", + dateFormatter.getDate(), + Messages.ResultStatus(), + runIdStr, + resultStatus.toString())); + build.setResult(resultStatus); + + } + + private Result createRunResults(FilePath filePath, Testsuites testsuites) { + Result ret = Result.SUCCESS; + try { + if (testsuites != null) { + StringWriter writer = new StringWriter(); + XStream xstream = new XStream(); + xstream.autodetectAnnotations(true); + xstream.toXML(testsuites, writer); + filePath.write(writer.toString(), null); + if (containsErrorsOrFailures(testsuites.getTestsuite())) { + ret = Result.FAILURE; + } + } else { + logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.EmptyResults())); + ret = Result.FAILURE; + } + + } catch (Exception cause) { + logger.print(String.format( + "%s - %s. %s: %s", + dateFormatter.getDate(), + Messages.FailedToCreateRunResults(), + Messages.Exception(), + cause.getMessage())); + ret = Result.FAILURE; + } + return ret; + } + + private boolean containsErrorsOrFailures(List testsuites) { + boolean ret = false; + for (Testsuite testsuite : testsuites) { + for (Testcase testcase : testsuite.getTestcase()) { + String status = testcase.getStatus(); + if (status.equals(JUnitTestCaseStatus.ERROR) + || status.equals(JUnitTestCaseStatus.FAILURE)) { + ret = true; + break; + } + } + } + return ret; + } + + private String getJunitResultsFileName() { + Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); + String time = formatter.format(new Date()); + junitResultsFileName = String.format("Results%s.xml", time); + return junitResultsFileName; + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException { + Workspace = workspace; + WorkspacePath = new File(workspace.toURI()); + Result resultStatus = Result.FAILURE; + //trendReportReady = false; + logger = listener.getLogger(); + if (credentialsId != null) + usernamePCPasswordCredentials = getCredentialsById(credentialsId, build, logger); + if (credentialsProxyId != null && !credentialsProxyId.isEmpty()) + usernamePCPasswordCredentialsForProxy = getCredentialsById(credentialsProxyId, build, logger); + PcClient pcClient = new PcClient(getPcModel(), logger); + Testsuites testsuites = execute(pcClient, build); + +// // Create Trend Report +// if(trendReportReady){ +// String reportUrlTemp = trendReportStructure.replaceFirst("%s/", "") + "/trendReport%s.pdf"; +// String reportUrl = String.format(reportUrlTemp, artifactsResourceName, getPcModel().getTrendReportId(true)); +// pcClient.publishTrendReport(reportUrl, getPcModel().getTrendReportId(true)); +// } +// // End Create Trend Report + + FilePath resultsFilePath = workspace.child(getJunitResultsFileName()); + resultStatus = createRunResults(resultsFilePath, testsuites); + provideStepResultStatus(resultStatus, build); + + + //add info for execution in pipeline mode + ParametersAction parameterAction = build.getAction(ParametersAction.class); + List newParams = (parameterAction != null) ? new ArrayList<>(parameterAction.getAllParameters()) : new ArrayList<>(); + newParams.add(new StringParameterValue("buildStepName", "PcBuilder")); + newParams.add(new StringParameterValue("resultsFilename", this.getRunResultsFileName())); + + if (parameterAction instanceof AdditionalParametersAction) { + build.addOrReplaceAction(new AdditionalParametersAction(newParams)); + } else { + build.addOrReplaceAction(new ParametersAction(newParams)); + } + + + if (!Result.SUCCESS.equals(resultStatus) && !Result.FAILURE.equals(resultStatus)) { + return; + } +// //Only do this if build worked (Not unstable or aborted - which might mean there is no report +// JUnitResultArchiver jUnitResultArchiver = new JUnitResultArchiver(this.getRunResultsFileName()); +// jUnitResultArchiver.setKeepLongStdio(true); +// jUnitResultArchiver.perform(build, workspace, launcher, listener); + + } + + public String getServerAndPort() { + return getPcModel().getserverAndPort(); + } + + public String getPcServerName() { + return getPcModel().getPcServerName(); + } + + public String getAlmProject() { + return getPcModel().getAlmProject(); + } + + public String getTestId() { + return getPcModel().getTestId(); + } + + public String getAlmDomain() { + return getPcModel().getAlmDomain(); + } + + public String getTimeslotDurationHours() { + return getPcModel().getTimeslotDurationHours(); + } + + public String getTimeslotDurationMinutes() { + return getPcModel().getTimeslotDurationMinutes(); + } + + public PostRunAction getPostRunAction() { + return getPcModel().getPostRunAction(); + } + + public String getTrendReportId() { + return getPcModel().getTrendReportId(true); + } + + public String getAutoTestInstanceID() { + return getPcModel().getAutoTestInstanceID(); + } + + public String getTestInstanceId() { + return getPcModel().getTestInstanceId(); + } + + public String getAddRunToTrendReport() { + return getPcModel().getAddRunToTrendReport(); + } + + public boolean isVudsMode() { + return getPcModel().isVudsMode(); + } + + public boolean isAuthenticateWithToken() { + return getPcModel().isAuthenticateWithToken(); + } + + public String getRetry() { + return getPcModel().getRetry(); + } + + public String getRetryOccurrences() { + return getPcModel().getRetryOccurrences(); + } + + public String getRetryDelay() { + return getPcModel().getRetryDelay(); + } + + public String getDescription() { + return getPcModel().getDescription(); + } + + public boolean isHTTPSProtocol() { + return getPcModel().httpsProtocol(); + } + + public boolean isStatusBySLA() { + return statusBySLA; + } + + public String getProxyOutURL() { + return getPcModel().getProxyOutURL(); + } + + // This indicates to Jenkins that this is an implementation of an extension + // point + @Extension + @Symbol("pcBuild") + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + + load(); + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + @Override + public String getDisplayName() { + + return Messages.DisplayName(); + } + + public FormValidation doCheckPcServerName(@QueryParameter String value) { + + return validateString(value, "LRE Server"); + } + + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + + return validateString(value, "Domain"); + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + + return validateString(value, "Project"); + } + + public FormValidation doCheckTestId(@QueryParameter String value) { + + return validateHigherThanInt(value, "Test ID", 0, true); + } + + public FormValidation doCheckRetryDelay(@QueryParameter String value) { + + return validateHigherThanInt(value, "Delay between attempts (in minutes)", 0, true); + } + + public FormValidation doCheckRetryOccurrences(@QueryParameter String value) { + + return validateHigherThanInt(value, "Number of attempts", 0, true); + } + + // if autoTestInstanceID is selected we don't need to check the validation of the test instance +// public static FormValidation CheckOnlyAutoTestInstanceId(String autoTestInstanceID){ +// if(autoTestInstanceID.equals("AUTO")) +// return FormValidation.ok(); +// else +// return FormValidation.error("Error "); +// } + + + public FormValidation doCheckTestInstanceId(@QueryParameter String value) { + return validateHigherThanInt(value, "Test Instance ID", 0, true); + } + + + public FormValidation doCheckTimeslotDuration(@QueryParameter TimeslotDuration value) { + + return validateHigherThanInt( + String.valueOf(value.toMinutes()), + "Timeslot Duration (in minutes)", + 30, + false); + } + + public FormValidation doCheckTimeslotId(@QueryParameter String value) { + + return validateHigherThanInt(value, "Timeslot ID", 0, true); + } + + public FormValidation doCheckCredentialsId(@AncestorInPath Item project, + @QueryParameter String pcUrl, + @QueryParameter String value) { + return checkCredentialsId(project, pcUrl, value); + } + + public FormValidation doCheckCredentialsProxyId(@AncestorInPath Item project, + @QueryParameter String pcUrl, + @QueryParameter String value) { + return checkCredentialsId(project, pcUrl, value); + } + + public FormValidation checkCredentialsId(@AncestorInPath Item project, + @QueryParameter String pcUrl, + @QueryParameter String credentialIdValue) { + if (project == null || !project.hasPermission(Item.EXTENDED_READ)) { + return FormValidation.ok(); + } + + String credentialIdValueStr = Util.fixEmptyAndTrim(credentialIdValue); + if (credentialIdValueStr == null) { + return FormValidation.ok(); + } + + String pcUrlStr = Util.fixEmptyAndTrim(pcUrl); + if (pcUrlStr == null) + // not set, can't check + { + return FormValidation.ok(); + } + + if (pcUrlStr.indexOf('$') >= 0) + // set by variable, can't check + { + return FormValidation.ok(); + } + + for (ListBoxModel.Option o : CredentialsProvider.listCredentials( + StandardUsernamePasswordCredentials.class, + project, + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + URIRequirementBuilder.create().build(), + new IdMatcher(credentialIdValueStr))) { + + if (StringUtils.equals(credentialIdValueStr, o.value)) { + return FormValidation.ok(); + } + } + // no credentials available, can't check + return FormValidation.warning(String.format("%s s", + Messages.CannotFindAnyCredentials(), + credentialIdValueStr)); + } + + + /** + * @param limitIncluded if true, value must be higher than limit. if false, value must be equal to or + * higher than limit. + */ + private FormValidation validateHigherThanInt( + String value, + String field, + int limit, + boolean limitIncluded) { + FormValidation ret = FormValidation.ok(); + value = value.trim(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error(" " + Messages.MustBeSet()); + } else { + try { + //regular expression: parameter (with brackets or not) + if (value.matches("^\\$\\{[\\w-. ]*}$|^\\$[\\w-.]*$")) + return ret; + //regular expression: number + else if (value.matches("[0-9]*$|")) { + if (limitIncluded && Integer.parseInt(value) <= limit) + ret = FormValidation.error(" " + Messages.MustBeHigherThan() + " " + limit); + else if (Integer.parseInt(value) < limit) + ret = FormValidation.error(" " + Messages.MustBeAtLeast() + " " + limit); + } else + ret = FormValidation.error(" " + Messages.MustBeAWholeNumberOrAParameter() + ", " + Messages.ForExample() + ": 23, $TESTID or ${TEST_ID}."); + } catch (Exception e) { + ret = FormValidation.error(" " + Messages.MustBeAWholeNumberOrAParameter() + " (" + Messages.ForExample() + ": $TESTID or ${TestID})"); + } + } + + return ret; + + } + + private FormValidation validateString(String value, String field) { + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value.trim())) { + ret = FormValidation.error(field + " " + Messages.MustBeSet()); + } + + return ret; + } + + + public List getPostRunActions() { + + return PcModel.getPostRunActions(); + } + + + /** + * To fill in the credentials drop down list which's field is 'credentialsId'. + * This method's name works with tag . + */ + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + + if (project == null || !project.hasPermission(Item.CONFIGURE)) { + return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); + } + return new StandardUsernameListBoxModel() + .includeEmptyValue() + .includeAs( + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + project, + StandardUsernamePasswordCredentials.class, + URIRequirementBuilder.create().build()) + .includeCurrentValue(credentialsId); + } + + /** + * To fill in the credentials drop down list which's field is 'credentialsProxyId'. + * This method's name works with tag . + */ + public ListBoxModel doFillCredentialsProxyIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + + return doFillCredentialsIdItems(project, credentialsId); + } + + } + + private class TriTrendReportTypes { + + private TrendReportTypes.DataType dataType; + private TrendReportTypes.PctType pctType; + private TrendReportTypes.Measurement measurement; + + TriTrendReportTypes(TrendReportTypes.DataType dataType, TrendReportTypes.PctType pctType, TrendReportTypes.Measurement measurement) { + this.dataType = dataType; + this.pctType = pctType; + this.measurement = measurement; + } + + public TrendReportTypes.DataType getDataType() { + return dataType; + } + + public TrendReportTypes.PctType getPctType() { + return pctType; + } + + public TrendReportTypes.Measurement getMeasurement() { + return measurement; + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/RunFromAlmBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/RunFromAlmBuilder.java new file mode 100644 index 0000000000..9a2be064d4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/RunFromAlmBuilder.java @@ -0,0 +1,589 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.microfocus.application.automation.tools.JenkinsUtils; +import com.microfocus.application.automation.tools.model.*; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.uft.model.FilterTestsModel; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.uft.model.SpecifyParametersModel; +import hudson.*; + +import hudson.model.*; + +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; + +import java.io.IOException; +import java.net.URL; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Stream; + +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.VariableResolver; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import com.microfocus.application.automation.tools.AlmToolsUtils; +import com.microfocus.application.automation.tools.EncryptionUtils; +import com.microfocus.application.automation.tools.run.AlmRunTypes.RunType; + +import static com.microfocus.application.automation.tools.Messages.CompanyName; +import static com.microfocus.application.automation.tools.Messages.RunFromAlmBuilderStepName; + +public class RunFromAlmBuilder extends Builder implements SimpleBuildStep { + + public RunFromAlmModel runFromAlmModel; + private boolean isFilterTestsEnabled; + private boolean areParametersEnabled; + private FilterTestsModel filterTestsModel; + private SpecifyParametersModel specifyParametersModel; + private final static String HP_TOOLS_LAUNCHER_EXE = "HpToolsLauncher.exe"; + private final static String HP_TOOLS_LAUNCHER_EXE_CFG = "HpToolsLauncher.exe.config"; + private String resultsFileName = "ApiResults.xml"; + private AlmServerSettingsModel almServerSettingsModel; + + @DataBoundConstructor + public RunFromAlmBuilder( + String almServerName, + String almCredentialsScope, + String almUserName, + String almPassword, + String almDomain, + String almProject, + String almTestSets, + String almRunResultsMode, + String almTimeout, + String almRunMode, + String almRunHost, + String almClientID, + String almApiKey, + boolean isSSOEnabled, + boolean isFilterTestsEnabled, + boolean areParametersEnabled, + FilterTestsModel filterTestsModel, + SpecifyParametersModel specifyParametersModel, + AlmServerSettingsModel almServerSettingsModel) { + + this.isFilterTestsEnabled = isFilterTestsEnabled; + this.areParametersEnabled = areParametersEnabled; + this.filterTestsModel = filterTestsModel; + this.specifyParametersModel = specifyParametersModel; + this.almServerSettingsModel = almServerSettingsModel; + CredentialsScope almCredScope = StringUtils.isBlank(almCredentialsScope) ? + findMostSuitableCredentialsScope(almServerName, almUserName, almClientID, isSSOEnabled) : + CredentialsScope.valueOf(almCredentialsScope.toUpperCase()); + + runFromAlmModel = + new RunFromAlmModel( + almServerName, + almUserName, + almPassword, + almDomain, + almProject, + almTestSets, + almRunResultsMode, + almTimeout, + almRunMode, + almRunHost, + isSSOEnabled, + almClientID, + almApiKey, + almCredScope); + } + + public CredentialsScope getCredentialsScopeOrDefault() { + CredentialsScope scope = runFromAlmModel.getCredentialsScope(); + return scope == null ? + findMostSuitableCredentialsScope(getAlmServerName(), getAlmUserName(), getAlmClientID(), getIsSSOEnabled()) : + scope; + } + + private AlmServerSettingsModel findAlmServerSettingsModel(String serverName) { + Stream models = Arrays.stream(AlmServerSettingsGlobalConfiguration.getInstance().getInstallations()); + return models.filter(m -> m.getAlmServerName().equals(serverName)).findFirst().orElse(null); + } + + private boolean isUserNameDefinedAtSystemLevel(String serverName, String userName) { + AlmServerSettingsModel model = findAlmServerSettingsModel(serverName); + if (model != null) { + return model.getAlmCredentials().stream().anyMatch(c -> c.getAlmUsername().equals(userName)); + } + return false; + } + + private boolean isClientIdDefinedAtSystemLevel(String serverName, String clientId) { + AlmServerSettingsModel model = findAlmServerSettingsModel(serverName); + if (model != null) { + return model.getAlmSSOCredentials().stream().anyMatch(c -> c.getAlmClientID().equals(clientId)); + } + return false; + } + + private CredentialsScope findMostSuitableCredentialsScope(String serverName, String userName, String clientId, boolean isSSOEnabled) { + if (isSSOEnabled) { + return isClientIdDefinedAtSystemLevel(serverName, clientId) ? CredentialsScope.SYSTEM : CredentialsScope.JOB; + } else { + return isUserNameDefinedAtSystemLevel(serverName, userName) ? CredentialsScope.SYSTEM : CredentialsScope.JOB; + } + } + + public String getAlmServerName() { + return runFromAlmModel.getAlmServerName(); + } + + public boolean getIsSSOEnabled() { + return runFromAlmModel.isSSOEnabled(); + } + + public void setIsSSOEnabled(Boolean isSSOEnabled) { + runFromAlmModel.setIsSSOEnabled(isSSOEnabled); + } + + /* This setter seems to be useless, it only seems to generate an unnecessary object in pipeline script, of type RunFromAlmModel + Also, it is already set in the constructor above + @DataBoundSetter + public void setRunFromAlmModel(RunFromAlmModel runFromAlmModel){ + this.runFromAlmModel = runFromAlmModel; + }*/ + + @DataBoundSetter + public void setAlmServerSettingsModel(AlmServerSettingsModel almServerSettingsModel) { + this.almServerSettingsModel = almServerSettingsModel; + } + + //IMPORTANT: most properties are used by config.jelly and / or by pipeline-syntax generator + public String getAlmCredentialsScope() { + return runFromAlmModel.getCredentialsScopeValue(); + } + + public String getAlmUserName() { + return runFromAlmModel.getAlmUserName(); + } + + public String getAlmPassword() { + return runFromAlmModel.getPasswordEncryptedValue(); + } + + public String getAlmClientID() { + return runFromAlmModel.getAlmClientID(); + } + + public String getAlmApiKey() { + return runFromAlmModel.getApiKeyEncryptedValue(); + } + + public String getAlmDomain() { + return runFromAlmModel.getAlmDomain(); + } + + public String getAlmProject() { + return runFromAlmModel.getAlmProject(); + } + + public String getAlmTestSets() { + return runFromAlmModel.getAlmTestSets(); + } + + public String getAlmRunResultsMode() { + return runFromAlmModel.getAlmRunResultsMode(); + } + + public String getAlmTimeout() { + return runFromAlmModel.getAlmTimeout(); + } + + public String getAlmRunMode() { + return runFromAlmModel.getAlmRunMode(); + } + + public String getAlmRunHost() { + return runFromAlmModel.getAlmRunHost(); + } + + public boolean getIsFilterTestsEnabled() { + return isFilterTestsEnabled; + } + + @DataBoundSetter + public void setIsFilterTestsEnabled(boolean isFilterTestsEnabled) { + this.isFilterTestsEnabled = isFilterTestsEnabled; + } + + public FilterTestsModel getFilterTestsModel() { + return filterTestsModel; + } + + @DataBoundSetter + public void setFilterTestsModel(FilterTestsModel filterTestsModel) { + this.filterTestsModel = filterTestsModel; + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public void perform(Run build, FilePath workspace, Launcher launcher, TaskListener listener) + throws InterruptedException, IOException { + // get the alm server settings + AlmServerSettingsModel almServerSettingsModel = getAlmServerSettingsModel(); + + if (almServerSettingsModel == null) { + listener.fatalError("An ALM server is not defined. Go to Manage Jenkins->Configure System and define your ALM server under Application Lifecycle Management"); + + // set pipeline stage as failure in case if ALM server was not configured + build.setResult(Result.FAILURE); + + return; + } + + Node currNode = JenkinsUtils.getCurrentNode(workspace); + if (currNode == null) { + listener.error("Failed to get current executor node."); + return; + } + + EnvVars env; + try { + env = build.getEnvironment(listener); + } catch (IOException e2) { + throw new IOException("Env Null - something went wrong with fetching jenkins build environment"); + } + VariableResolver varResolver = new VariableResolver.ByMap(build.getEnvironment(listener)); + + // now merge them into one list + Properties mergedProps = new Properties(); + + mergedProps.putAll(almServerSettingsModel.getProperties()); + mergedProps.putAll(runFromAlmModel.getProperties(env, varResolver)); + + CredentialsScope scope = getCredentialsScopeOrDefault(); + String encAlmPass; + try { + String almPassword = runFromAlmModel.getPasswordPlainText(); + if (scope == CredentialsScope.SYSTEM) { + Optional cred = almServerSettingsModel.getAlmCredentials().stream().filter(c -> c.getAlmUsername().equals(runFromAlmModel.getAlmUserName())).findFirst(); + if (cred.isPresent()) { + almPassword = cred.get().getAlmPasswordPlainText(); + } + } + + encAlmPass = EncryptionUtils.encrypt(almPassword, currNode); + + mergedProps.remove(RunFromAlmModel.ALM_PASSWORD_KEY); + mergedProps.put(RunFromAlmModel.ALM_PASSWORD_KEY, encAlmPass); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.fatalError("Issue with ALM Password encryption: " + e.getMessage() + "."); + return; + } + + String encAlmApiKey; + try { + String almApiKeySecret = runFromAlmModel.getApiKeyPlainText(); + if (scope == CredentialsScope.SYSTEM) { + Optional cred = almServerSettingsModel.getAlmSSOCredentials().stream().filter(c -> c.getAlmClientID().equals(runFromAlmModel.getAlmClientID())).findFirst(); + if (cred.isPresent()) { + almApiKeySecret = cred.get().getAlmApiKeySecretPlainText(); + } + } + + encAlmApiKey = EncryptionUtils.encrypt(almApiKeySecret, currNode); + mergedProps.remove(RunFromAlmModel.ALM_API_KEY_SECRET); + mergedProps.put(RunFromAlmModel.ALM_API_KEY_SECRET, encAlmApiKey); + mergedProps.put("almClientID", getAlmClientID()); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.fatalError("Issue with apiKey encryption: " + e.getMessage() + "."); + return; + } + + if (isFilterTestsEnabled) { + filterTestsModel.addProperties(mergedProps); + } else { + mergedProps.put("FilterTests", "false"); + } + + Date now = new Date(); + Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); + String time = formatter.format(now); + + // get a unique filename for the params file + String propsFileName = String.format("props%s.txt", time); + resultsFileName = String.format("Results%s_%d.xml", time, build.getNumber()); + //KillFileName = "stop" + time + ".txt"; + + //params used when run with Pipeline + ParametersAction parameterAction = build.getAction(ParametersAction.class); + List newParams = (parameterAction != null) ? new ArrayList<>(parameterAction.getAllParameters()) : new ArrayList<>(); + newParams.add(new StringParameterValue("buildStepName", "RunFromAlmBuilder")); + newParams.add(new StringParameterValue("resultsFilename", resultsFileName)); + build.addOrReplaceAction(new ParametersAction(newParams)); + + mergedProps.put("runType", RunType.Alm.toString()); + mergedProps.put("resultsFilename", resultsFileName); + + if (areParametersEnabled) { + try { + specifyParametersModel.addProperties(mergedProps, "TestSet", currNode); + } catch (Exception e) { + listener.error("Error occurred while parsing parameter input, reverting back to empty array."); + } + } + + // get properties serialized into a stream + String strProps; + try { + strProps = AlmToolsUtils.getPropsAsString(mergedProps); + } catch (IOException e) { + build.setResult(Result.FAILURE); + listener.error("Failed to store properties on agent machine: " + e); + return; + } + + // Get the URL to the Script used to run the test, which is bundled + // in the plugin + + URL cmdExeUrl = Hudson.getInstance().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE); + if (cmdExeUrl == null) { + build.setResult(Result.FAILURE); + listener.fatalError(HP_TOOLS_LAUNCHER_EXE + " not found in resources"); + return; + } + URL cmdExeCfgUrl = Hudson.getInstance().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE_CFG); + if (cmdExeCfgUrl == null) { + build.setResult(Result.FAILURE); + listener.fatalError(HP_TOOLS_LAUNCHER_EXE_CFG + " not found in resources"); + return; + } + + FilePath fileProps = workspace.child(propsFileName); + FilePath cmdLineExe = workspace.child(HP_TOOLS_LAUNCHER_EXE); + FilePath cmdLineExeCfg = workspace.child(HP_TOOLS_LAUNCHER_EXE_CFG); + + try { + // create a file for the properties file, and save the properties + if (!AlmToolsUtils.tryCreatePropsFile(listener, strProps, fileProps)) { + build.setResult(Result.FAILURE); + return; + } + // Copy the script to the project workspace + cmdLineExe.copyFrom(cmdExeUrl); + cmdLineExeCfg.copyFrom(cmdExeCfgUrl); + } catch (IOException | InterruptedException e) { + build.setResult(Result.FAILURE); + listener.error("Failed to copy props file or UFT tools to agent machine. " + e); + return; + } + try { + // Run the HpToolsLauncher.exe + AlmToolsUtils.runOnBuildEnv(build, launcher, listener, cmdLineExe, propsFileName, currNode); + } catch (IOException ioe) { + Util.displayIOException(ioe, listener); + build.setResult(Result.FAILURE); + } catch (InterruptedException e) { + build.setResult(Result.ABORTED); + try { + AlmToolsUtils.runHpToolsAborterOnBuildEnv(build, launcher, listener, propsFileName, workspace); + } catch (IOException e1) { + Util.displayIOException(e1, listener); + build.setResult(Result.FAILURE); + } catch (InterruptedException e1) { + listener.error("Failed running HpToolsAborter " + e1.getMessage()); + } + } + } + + public AlmServerSettingsModel getAlmServerSettingsModel() { + if (runFromAlmModel != null) { + return findAlmServerSettingsModel(getAlmServerName()); + } + return null; + } + + public RunFromAlmModel getRunFromAlmModel() { + return runFromAlmModel; + } + + public boolean isAreParametersEnabled() { + return areParametersEnabled; + } + + public void setAreParametersEnabled(boolean areParametersEnabled) { + this.areParametersEnabled = areParametersEnabled; + } + + public SpecifyParametersModel getSpecifyParametersModel() { + return specifyParametersModel; + } + + // This indicates to Jenkins that this is an implementation of an extension + // point. + @Extension + // To expose this builder in the Snippet Generator. + @Symbol("runFromAlmBuilder") + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + load(); + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + return true; + } + + @Override + public String getDisplayName() { + return RunFromAlmBuilderStepName(CompanyName()); + } + + public boolean hasAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().hasAlmServers(); + } + + public Stream getAlmServers() { + return Arrays.stream(AlmServerSettingsGlobalConfiguration.getInstance().getInstallations()).sorted(); + } + + private AlmServerSettingsModel findAlmServer(String almServerName) { + return StringUtils.isBlank(almServerName) ? + getAlmServers().findFirst().orElse(null) : + getAlmServers().filter(s -> s.getAlmServerName().equals(almServerName)).findFirst().orElse(null); + } + + public ListBoxModel doFillAlmServerNameItems() { + ListBoxModel m = new ListBoxModel(); + getAlmServers().forEachOrdered(s -> m.add(s.getAlmServerName())); + return m; + } + + public ListBoxModel doFillAlmUserNameItems(@QueryParameter String almServerName) { + ListBoxModel m = new ListBoxModel(); + if (hasAlmServers()) { + AlmServerSettingsModel model = findAlmServer(almServerName); + if (model != null && !model.getAlmCredentials().isEmpty()) { + model.getAlmCredentials().forEach(cm -> m.add(cm.getAlmUsername())); + } else if (StringUtils.isNotBlank(almServerName)) { + m.add(UftConstants.NO_USERNAME_DEFINED); + } + } + + return m; + } + + public ListBoxModel doFillAlmClientIDItems(@QueryParameter String almServerName) { + ListBoxModel m = new ListBoxModel(); + if (hasAlmServers()) { + AlmServerSettingsModel model = findAlmServer(almServerName); + if (model != null && !model.getAlmSSOCredentials().isEmpty()) { + model.getAlmSSOCredentials().forEach(cm -> m.add(cm.getAlmClientID())); + } else { + m.add(UftConstants.NO_CLIENT_ID_DEFINED); + } + } + return m; + } + + public FormValidation doCheckAlmTimeout(@QueryParameter String value) { + + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + String val1 = value.trim(); + + if (val1.length() > 0 && val1.charAt(0) == '-') + val1 = val1.substring(1); + + if (!StringUtils.isNumeric(val1) && !val1.equals("")) { + return FormValidation.error("Timeout value must be a number"); + } + return FormValidation.ok(); + } + + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Domain must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Project must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmTestSets(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Test sets are missing"); + } + + String[] testSetsArr = value.replaceAll("\r", "").split("\n"); + + for (int i = 0; i < testSetsArr.length; i++) { + if (StringUtils.isBlank(testSetsArr[i])) { + return FormValidation.error("Test sets should not contains empty lines"); + } + } + return FormValidation.ok(); + } + + public List getAlmRunModes() { + return RunFromAlmModel.runModes; + } + + public List getAlmCredentialScopes() { + return Arrays.asList(CredentialsScope.values()); + } + } + + public String getRunResultsFileName() { + return resultsFileName; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder.java new file mode 100644 index 0000000000..73a331468b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder.java @@ -0,0 +1,181 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.microfocus.application.automation.tools.Messages; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Util; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.ArgumentListBuilder; +import jenkins.tasks.SimpleBuildStep; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.IOException; +import java.io.PrintStream; + +import static com.microfocus.application.automation.tools.octane.executor.UftConstants.CODELESS_FOLDER_TEMPLATE; + +/** + * @author Itay Karo on 11/11/2021 + */ +public class RunFromCodelessBuilder extends Builder implements SimpleBuildStep { + + private static final String RUN_MSG_TEMPLATE = "Running codeless for test: %s, path: %s%n"; + + private static final String RESULT_MSG_TEMPLATE = "Codeless returned code: %d%n"; + + private static final String CODELESS_BATCH_FILE = "CodelessExecuter.bat"; + + @DataBoundConstructor + public RunFromCodelessBuilder() { + //for codeclimate + } + + @Override + public void perform(@NonNull Run build, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener taskListener) throws InterruptedException, IOException { + FilePath parentFolder = workspace.child(String.format(CODELESS_FOLDER_TEMPLATE, build.getNumber())); + if (!parentFolder.exists()) { // no codeless tests to run + taskListener.getLogger().println(RunFromCodelessBuilder.class.getSimpleName() + " : No codeless tests were found"); + return; + } + + FilePath[] list = parentFolder.list("mbt.json"); + if (list.length == 0) { + taskListener.getLogger().println(RunFromCodelessBuilder.class.getSimpleName() + " : mbt.json file was not found"); + return; + } + FilePath mbtJsonFile = list[0]; + JSONArray mbtJsonArr = (JSONArray) JSONValue.parse(mbtJsonFile.read()); + PrintStream out = taskListener.getLogger(); + Result currentResult = Result.NOT_BUILT; + + for (Object o : mbtJsonArr) { + JSONObject jsonObject = (JSONObject) o; + String testName = jsonObject.getAsString("testName"); + String filePath = jsonObject.getAsString("path"); + + ArgumentListBuilder args = new ArgumentListBuilder(); + args.add(CODELESS_BATCH_FILE); + args.add(filePath); + + // Run the script on node + // Execution result should be 0 + try { + out.printf(RUN_MSG_TEMPLATE, testName, filePath); + int returnCode = launcher.launch().cmds(args).stdout(out).pwd(parentFolder).join(); + out.printf(RESULT_MSG_TEMPLATE, returnCode); + currentResult = getResultFromCodeless(returnCode, currentResult); + } catch (IOException e) { + Util.displayIOException(e, taskListener); + build.setResult(Result.FAILURE); + taskListener.error("Failed running {} with exception {}", CODELESS_BATCH_FILE, e); + } catch (InterruptedException e) { + build.setResult(Result.ABORTED); + taskListener.error("Failed running {} - build aborted {}", CODELESS_BATCH_FILE, e); + Thread.currentThread().interrupt();//for codeclimate + } + } + + build.setResult(currentResult); + } + + @Override + public RunFromCodelessBuilder.DescriptorImpl getDescriptor() { + return (RunFromCodelessBuilder.DescriptorImpl) super.getDescriptor(); + } + + private Result getResultFromCodeless(int reportCode, Result currentResult) { + Result codelessResult = convertReportCode(reportCode); + + if (currentResult.equals(Result.NOT_BUILT)) { // initial status + return codelessResult; + } else if ((currentResult.equals(Result.SUCCESS) && codelessResult.equals(Result.FAILURE)) || (currentResult.equals(Result.FAILURE) && codelessResult.equals(Result.SUCCESS))) { + return Result.UNSTABLE; + } else { + return codelessResult; + } + } + + private Result convertReportCode(int reportCode) { + switch (reportCode) { + case 0: + return Result.SUCCESS; + case 1: + return Result.FAILURE; + case -1: + return Result.ABORTED; + default: + return Result.SUCCESS; + } + } + + /** + * The type Descriptor. + */ + @Symbol("runFromCodelessBuilder") + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { + load(); + } + + @Override + public boolean isApplicable(@SuppressWarnings("rawtypes") Class jobType) { + return true; + } + + @Override + public String getDisplayName() { + return com.microfocus.application.automation.tools.Messages.RunFromCodelessBuilderStepName(Messages.CompanyName()); + } + + } + + ; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/RunFromFileBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/RunFromFileBuilder.java new file mode 100644 index 0000000000..1543756a0c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/RunFromFileBuilder.java @@ -0,0 +1,1235 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.hp.octane.integrations.executor.TestsToRunConverter; +import com.microfocus.application.automation.tools.JenkinsUtils; +import com.microfocus.application.automation.tools.AlmToolsUtils; +import com.microfocus.application.automation.tools.EncryptionUtils; +import com.microfocus.application.automation.tools.Messages; +import com.microfocus.application.automation.tools.lr.model.ScriptRTSSetModel; +import com.microfocus.application.automation.tools.lr.model.SummaryDataLogModel; +import com.microfocus.application.automation.tools.mc.JobConfigurationProxy; +import com.microfocus.application.automation.tools.model.*; +import com.microfocus.application.automation.tools.settings.MCServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.uft.model.SpecifyParametersModel; +import com.microfocus.application.automation.tools.uft.model.UftRunAsUser; +import com.microfocus.application.automation.tools.uft.model.UftSettingsModel; +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import hudson.*; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.FormValidation; +import hudson.util.Secret; +import hudson.util.VariableResolver; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import net.minidev.json.JSONObject; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.bind.JavaScriptMethod; + +import javax.annotation.Nonnull; +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Describes a regular jenkins build step from UFT or LR + */ +public class RunFromFileBuilder extends Builder implements SimpleBuildStep { + + private static final String LRANALYSIS_LAUNCHER_EXE = "LRAnalysisLauncher.exe"; + + public static final String HP_TOOLS_LAUNCHER_EXE = "HpToolsLauncher.exe"; + public static final String HP_TOOLS_LAUNCHER_EXE_CFG = "HpToolsLauncher.exe.config"; + + private RunFromFileSystemModel runFromFileModel; + + private FileSystemTestSetModel fileSystemTestSetModel; + private SpecifyParametersModel specifyParametersModel; + private boolean isParallelRunnerEnabled; + private boolean areParametersEnabled; + private SummaryDataLogModel summaryDataLogModel; + + private ScriptRTSSetModel scriptRTSSetModel; + + private UftSettingsModel uftSettingsModel; + + private Map resultFileNames; + + /** + * Instantiates a new Run from file builder. + * + * @param fsTests the fs tests + */ + @DataBoundConstructor + public RunFromFileBuilder(String fsTests, + boolean isParallelRunnerEnabled, + boolean areParametersEnabled, + SpecifyParametersModel specifyParametersModel, + FileSystemTestSetModel fileSystemTestSetModel, + SummaryDataLogModel summaryDataLogModel, + ScriptRTSSetModel scriptRTSSetModel, + UftSettingsModel uftSettingsModel) { + this.runFromFileModel = new RunFromFileSystemModel(fsTests); + this.specifyParametersModel = specifyParametersModel; + this.fileSystemTestSetModel = fileSystemTestSetModel; + this.isParallelRunnerEnabled = isParallelRunnerEnabled; + this.areParametersEnabled = areParametersEnabled; + this.summaryDataLogModel = summaryDataLogModel; + this.scriptRTSSetModel = scriptRTSSetModel; + this.uftSettingsModel = uftSettingsModel; + if (uftSettingsModel != null) { + uftSettingsModel.setFsTestPath(getFsTests()); + } + resultFileNames = new HashMap(); + } + + /** + * Instantiates a new Run from file builder. + * + * @param fsTests the fs tests + */ + public RunFromFileBuilder(String fsTests) { + runFromFileModel = new RunFromFileSystemModel(fsTests); + } + + /** + * Instantiates a new Run from file builder. + * + * @param runFromFileModel the run from file model + */ + public RunFromFileBuilder(RunFromFileSystemModel runFromFileModel) { + this.runFromFileModel = runFromFileModel; + } + + /** + * @param fsTests the fs tests + * @param fsTimeout the fs timeout + * @param controllerPollingInterval the controller polling interval + * @param perScenarioTimeOut the per scenario time out + * @param ignoreErrorStrings the ignore error strings + * @param analysisTemplate the analysis template + * @param displayController the display controller + * @param mcServerName the mc server name + * @param fsDeviceId the fs device id + * @param fsTargetLab the fs target lab + * @param fsManufacturerAndModel the fs manufacturer and model + * @param fsOs the fs os + * @param fsAutActions the fs aut actions + * @param fsLaunchAppName the fs launch app name + * @param fsDevicesMetrics the fs devices metrics + * @param fsInstrumented the fs instrumented + * @param fsExtraApps the fs extra apps + * @param fsJobId the fs job id + * @param proxySettings the proxy settings + * @param useSSL the use ssl + * @deprecated Instantiates a new Run from file builder. + */ + @SuppressWarnings("squid:S00107") + @Deprecated + public RunFromFileBuilder(String fsTests, String fsTimeout, String fsUftRunMode, String controllerPollingInterval, + String perScenarioTimeOut, String ignoreErrorStrings, String displayController, + String analysisTemplate, String mcServerName, AuthModel authModel, String fsDeviceId, String fsTargetLab, String fsManufacturerAndModel, + String fsOs, String fsAutActions, String fsLaunchAppName, String fsDevicesMetrics, + String fsInstrumented, String fsExtraApps, String fsJobId, ProxySettings proxySettings, + boolean useSSL, boolean isParallelRunnerEnabled, String fsReportPath, CloudBrowserModel cloudBrowserModel) { + this.isParallelRunnerEnabled = isParallelRunnerEnabled; + runFromFileModel = new RunFromFileSystemModel(fsTests, fsTimeout, fsUftRunMode, controllerPollingInterval, + perScenarioTimeOut, ignoreErrorStrings, displayController, analysisTemplate, mcServerName, + authModel, fsDeviceId, fsTargetLab, fsManufacturerAndModel, fsOs, + fsAutActions, fsLaunchAppName, fsDevicesMetrics, fsInstrumented, fsExtraApps, fsJobId, + proxySettings, useSSL, fsReportPath, cloudBrowserModel); + } + + /** + * Replace the fsTests given as mtbx with the actual mtbx file. + * + * @param workspace the current workspace + * @param props the properties + * @param content the mtbx content + * @param key the test key + * @param time current time string + * @param index the index for the prefix + * @throws Exception + */ + private static void replaceTestWithMtbxFile(FilePath workspace, Properties props, String content, String key, + String time, int index) throws Exception { + if (UftToolUtils.isMtbxContent(content)) { + try { + String prefx = index > 0 ? index + "_" : ""; + String mtbxFilePath = prefx + createMtbxFileInWs(workspace, content, time); + props.setProperty(key, mtbxFilePath); + } catch (IOException | InterruptedException e) { + throw new Exception(e); + } + } + } + + /** + * Replace the fsTests given as mtbx with the actual mtbx file. + * + * @param workspace the current workspace + * @param props the properties + * @param content the mtbx content + * @param key the test key + * @param time current time string + * @throws Exception + */ + private static void replaceTestWithMtbxFile(FilePath workspace, Properties props, String content, String key, + String time) throws Exception { + replaceTestWithMtbxFile(workspace, props, content, key, time, 0); + } + + /** + * Creates an .mtbx file with the provided mtbx content. + * + * @param workspace jenkins workspace + * @param mtbxContent the motbx content + * @param timeString current time represented as a String + * @return the remote file path + * @throws IOException + * @throws InterruptedException + */ + private static String createMtbxFileInWs(FilePath workspace, String mtbxContent, String timeString) + throws IOException, InterruptedException { + String fileName = "test_suite_" + timeString + ".mtbx"; + + FilePath remoteFile = workspace.child(fileName); + + String mtbxContentUpdated = mtbxContent.replace("${WORKSPACE}", workspace.getRemote()); + if (mtbxContent.contains("${workspace}")) { + mtbxContentUpdated = mtbxContent.replace("${workspace}", workspace.getRemote()); + } + try (InputStream in = IOUtils.toInputStream(mtbxContentUpdated, StandardCharsets.UTF_8)) { + remoteFile.copyFrom(in); + } + return remoteFile.getRemote(); + } + + public FileSystemTestSetModel getFileSystemTestSetModel() { + return fileSystemTestSetModel; + } + + /** + * Gets the parallel runner flag. + * + * @return the current parallel runner flag state(enabled/disabled) + */ + public boolean getIsParallelRunnerEnabled() { + return isParallelRunnerEnabled; + } + + /** + * Sets the parallel runner flag + * + * @param isParallelRunnerEnabled the parallel runner flag + */ + @DataBoundSetter + private void setIsParallelRunnerEnabled(boolean isParallelRunnerEnabled) { + this.isParallelRunnerEnabled = isParallelRunnerEnabled; + } + + public String getAnalysisTemplate() { + return runFromFileModel.getAnalysisTemplate(); + } + + /** + * Sets analysis template. + * + * @param analysisTemplate the analysis template + */ + @DataBoundSetter + public void setAnalysisTemplate(String analysisTemplate) { + runFromFileModel.setAnalysisTemplate(analysisTemplate); + } + + public SummaryDataLogModel getSummaryDataLogModel() { + return summaryDataLogModel; + } + + public void setSummaryDataLogModel(SummaryDataLogModel summaryDataLogModel) { + this.summaryDataLogModel = summaryDataLogModel; + } + + public ScriptRTSSetModel getScriptRTSSetModel() { + return scriptRTSSetModel; + } + + public void setScriptRTSSetModel(ScriptRTSSetModel scriptRTSSetModel) { + this.scriptRTSSetModel = scriptRTSSetModel; + } + + public UftSettingsModel getUftSettingsModel() { + return uftSettingsModel; + } + + @DataBoundSetter + public void setUftSettingsModel(UftSettingsModel uftSettingsModel) { + this.uftSettingsModel = uftSettingsModel; + } + + public String getFsTimeout() { + return runFromFileModel.getFsTimeout(); + } + + /** + * Sets fs timeout. + * + * @param fsTimeout the fs timeout + */ + @DataBoundSetter + public void setFsTimeout(String fsTimeout) { + runFromFileModel.setFsTimeout(fsTimeout); + } + + public String getFsTests() { + return runFromFileModel.getFsTests(); + } + + public void setFsTests(String fsTests) { + runFromFileModel.setFsTests(fsTests); + } + + public String getControllerPollingInterval() { + return runFromFileModel.getControllerPollingInterval(); + } + + /** + * Sets controller polling interval. + * + * @param controllerPollingInterval the controller polling interval + */ + @DataBoundSetter + public void setControllerPollingInterval(String controllerPollingInterval) { + runFromFileModel.setControllerPollingInterval(controllerPollingInterval); + } + + public String getPerScenarioTimeOut() { + return runFromFileModel.getPerScenarioTimeOut(); + } + + /** + * Sets per scenario time out. + * + * @param perScenarioTimeOut the per scenario time out + */ + @DataBoundSetter + public void setPerScenarioTimeOut(String perScenarioTimeOut) { + runFromFileModel.setPerScenarioTimeOut(perScenarioTimeOut); + } + + public String getDisplayController() { + return runFromFileModel.getDisplayController(); + } + + /** + * Sets display controller. + * + * @param displayController the display controller + */ + @DataBoundSetter + public void setDisplayController(String displayController) { + runFromFileModel.setDisplayController(displayController); + } + + public String getFsAutActions() { + return runFromFileModel.getFsAutActions(); + } + + /** + * Sets fs aut actions. + * + * @param fsAutActions the fs aut actions + */ + @DataBoundSetter + public void setFsAutActions(String fsAutActions) { + runFromFileModel.setFsAutActions(fsAutActions); + } + + public String getFsDeviceId() { + return runFromFileModel.getFsDeviceId(); + } + + /** + * Sets fs device id. + * + * @param fsDeviceId the fs device id + */ + @DataBoundSetter + public void setFsDeviceId(String fsDeviceId) { + runFromFileModel.setFsDeviceId(fsDeviceId); + } + + public String getFsDevicesMetrics() { + return runFromFileModel.getFsDevicesMetrics(); + } + + /** + * Sets fs devices metrics. + * + * @param fsDevicesMetrics the fs devices metrics + */ + @DataBoundSetter + public void setFsDevicesMetrics(String fsDevicesMetrics) { + runFromFileModel.setFsDevicesMetrics(fsDevicesMetrics); + } + + public String getFsExtraApps() { + return runFromFileModel.getFsExtraApps(); + } + + /** + * Sets fs extra apps. + * + * @param fsExtraApps the fs extra apps + */ + @DataBoundSetter + public void setFsExtraApps(String fsExtraApps) { + runFromFileModel.setFsExtraApps(fsExtraApps); + } + + public String getFsOs() { + return runFromFileModel.getFsOs(); + } + + /** + * Sets fs os. + * + * @param fsOs the fs os + */ + @DataBoundSetter + public void setFsOs(String fsOs) { + runFromFileModel.setFsOs(fsOs); + } + + public String getFsInstrumented() { + return runFromFileModel.getFsInstrumented(); + } + + /** + * Sets fs instrumented. + * + * @param fsInstrumented the fs instrumented + */ + @DataBoundSetter + public void setFsInstrumented(String fsInstrumented) { + runFromFileModel.setFsInstrumented(fsInstrumented); + } + + public String getFsJobId() { + return runFromFileModel.getFsJobId(); + } + + /** + * Sets fs job id. + * + * @param fsJobId the fs job id + */ + @DataBoundSetter + public void setFsJobId(String fsJobId) { + runFromFileModel.setFsJobId(fsJobId); + } + + public String getFsUftRunMode() { + return runFromFileModel.getFsUftRunMode(); + } + + /** + * Sets fs runMode. + * + * @param fsUftRunMode the fs runMode + */ + @DataBoundSetter + public void setFsUftRunMode(String fsUftRunMode) { + runFromFileModel.setFsUftRunMode(fsUftRunMode); + } + + public String getIgnoreErrorStrings() { + return runFromFileModel.getIgnoreErrorStrings(); + } + + /** + * Sets ignore error strings. + * + * @param ignoreErrorStrings the ignore error strings + */ + @DataBoundSetter + public void setIgnoreErrorStrings(String ignoreErrorStrings) { + runFromFileModel.setIgnoreErrorStrings(ignoreErrorStrings); + } + + public String getMcServerName() { + return runFromFileModel.getMcServerName(); + } + + /** + * Sets mc server name. + * + * @param mcServerName the mc server name + */ + @DataBoundSetter + public void setMcServerName(String mcServerName) { + runFromFileModel.setMcServerName(mcServerName); + } + + public String getFsManufacturerAndModel() { + return runFromFileModel.getFsManufacturerAndModel(); + } + + /** + * Sets fs manufacturer and model. + * + * @param fsManufacturerAndModel the fs manufacturer and model + */ + @DataBoundSetter + public void setFsManufacturerAndModel(String fsManufacturerAndModel) { + runFromFileModel.setFsManufacturerAndModel(fsManufacturerAndModel); + } + + public String getFsLaunchAppName() { + return runFromFileModel.getFsLaunchAppName(); + } + + /** + * Sets fs launch app name. + * + * @param fsLaunchAppName the fs launch app name + */ + @DataBoundSetter + public void setFsLaunchAppName(String fsLaunchAppName) { + runFromFileModel.setFsLaunchAppName(fsLaunchAppName); + } + + public ProxySettings getProxySettings() { + return runFromFileModel.getProxySettings(); + } + + /** + * Sets proxy settings. + * + * @param proxySettings the proxy settings + */ + @DataBoundSetter + public void setProxySettings(ProxySettings proxySettings) { + runFromFileModel.setProxySettings(proxySettings); + } + + public String getFsTargetLab() { + return runFromFileModel.getFsTargetLab(); + } + + public AuthModel getAuthModel() { + return runFromFileModel.getAuthModel(); + } + + @DataBoundSetter + public void setAuthModel(AuthModel authModel) { + runFromFileModel.setAuthModel(authModel); + } + + /** + * Sets fs target lab. + * + * @param fsTargetLab the fs target lab + */ + @DataBoundSetter + public void setFsTargetLab(String fsTargetLab) { + runFromFileModel.setFsTargetLab(fsTargetLab); + } + + public boolean getUseSSL() { + return runFromFileModel.isUseSSL(); + } + + /** + * Get the fs report path. + * + * @return the filesystem report path + */ + public String getFsReportPath() { + return runFromFileModel.getFsReportPath(); + } + + /** + * Sets the report path + * + * @param fsReportPath the report path + */ + @DataBoundSetter + public void setFsReportPath(String fsReportPath) { + runFromFileModel.setFsReportPath(fsReportPath); + } + + public CloudBrowserModel getCloudBrowserModel() { + return runFromFileModel.getCloudBrowserModel(); + } + @DataBoundSetter + public void setCloudBrowserModel(CloudBrowserModel cloudBrowserModel) { + runFromFileModel.setCloudBrowserModel(cloudBrowserModel); + } + public String getOutEncoding() { return runFromFileModel.getOutEncoding(); } + + @DataBoundSetter + public void setOutEncoding(String encoding) { runFromFileModel.setOutEncoding(encoding); } + + /** + * Sets mc server name. + * + * @param useSSL the mc server name + */ + @DataBoundSetter + public void setUseSSL(boolean useSSL) { + runFromFileModel.setUseSSL(useSSL); + } + + public Map getResultFileNames() { + return resultFileNames; + } + + @DataBoundSetter + public void setResultFileNames(Map results) { + resultFileNames = results; + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) + throws IOException { + PrintStream out = listener.getLogger(); + + UftOctaneUtils.setUFTRunnerTypeAsParameter(build, listener); + // get the mc server settings + MCServerSettingsModel mcServerSettingsModel = getMCServerSettingsModel(); + + EnvVars env = null; + try { + env = build.getEnvironment(listener); + } catch (IOException | InterruptedException e) { + listener.error("Failed loading build environment: " + e.getMessage()); + } + + Node currNode = JenkinsUtils.getCurrentNode(workspace); + if (currNode == null) { + listener.error("Failed to get current executor node."); + return; + } + + // in case of mbt, since mbt can support uft and codeless at the same time, run only if there are uft tests + ParametersAction parameterAction = build.getAction(ParametersAction.class); + ParameterValue octaneFrameworkParam = parameterAction != null ? parameterAction.getParameter("octaneTestRunnerFramework") : null; + if (octaneFrameworkParam != null && octaneFrameworkParam.getValue().equals("MBT")) { + String testsToRunConverted = env == null ? null : env.get(TestsToRunConverter.DEFAULT_TESTS_TO_RUN_CONVERTED_PARAMETER); + if (StringUtils.isEmpty(testsToRunConverted)) { + out.println(RunFromFileBuilder.class.getSimpleName() + " : No UFT tests were found"); + return; + } + } + + // this is an unproper replacement to the build.getVariableResolver since workflow run won't support the + // getBuildEnvironment() as written here: + // https://github.com/jenkinsci/pipeline-plugin/blob/893e3484a25289c59567c6724f7ce19e3d23c6ee/DEVGUIDE + // .md#variable-substitutions + + JSONObject jobDetails; + String mcServerUrl; + // now merge them into one list + Properties mergedProps = new Properties(); + if (mcServerSettingsModel != null) { + mcServerUrl = mcServerSettingsModel.getProperties().getProperty("MobileHostAddress"); + jobDetails = runFromFileModel.getJobDetails(mcServerUrl); + + mergedProps.setProperty("mobileinfo", jobDetails != null ? jobDetails.toJSONString() : ""); + mergedProps.setProperty("MobileHostAddress", mcServerUrl); + + CloudBrowserModel cbm = getCloudBrowserModel(); + if (cbm != null) { + String cb = String.format("\"url=%s;os=%s;type=%s;version=%s;region=%s\"", cbm.getUrl(), cbm.getOs(), cbm.getType(), cbm.getVersion(), cbm.getRegion()); + mergedProps.setProperty("cloudBrowser", cb); + } + } + + // check whether Mobile authentication info is given or not + String plainTextPwd = runFromFileModel.getMcPassword() == null ? null : Secret.fromString(runFromFileModel.getMcPassword()).getPlainText(); + String plainTextToken = runFromFileModel.getMcExecToken() == null ? null : Secret.fromString(runFromFileModel.getMcExecToken()).getPlainText(); + if (StringUtils.isNotBlank(plainTextPwd)) { + try { + String encPassword = EncryptionUtils.encrypt(plainTextPwd, currNode); + mergedProps.put("MobilePassword", encPassword); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.fatalError("Problem in Digital Lab password encryption: " + e.getMessage() + "."); + return; + } + } else if (StringUtils.isNotBlank(plainTextToken)) { + try { + String encToken = EncryptionUtils.encrypt(plainTextToken, currNode); + mergedProps.put("MobileExecToken", encToken); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.fatalError("Problem in Digital Lab execution token encryption: " + e.getMessage() + "."); + return; + } + } + + if (env == null) { + listener.fatalError("Environment not set"); + throw new IOException("Env Null - something went wrong with fetching jenkins build environment"); + } + + if (build instanceof AbstractBuild) { + VariableResolver varResolver = ((AbstractBuild) build).getBuildVariableResolver(); + } + + mergedProps.putAll(Objects.requireNonNull(runFromFileModel).getProperties(env, currNode)); + + if (areParametersEnabled) { + try { + specifyParametersModel.addProperties(mergedProps, "Test", currNode); + } catch (Exception e) { + listener.error("Error occurred while parsing parameter input, reverting back to empty array."); + } + } + boolean isPrintTestParams = UftToolUtils.isPrintTestParams(build, listener); + mergedProps.put("printTestParams", isPrintTestParams ? "1" : "0"); + + UftRunAsUser uftRunAsUser; + try { + uftRunAsUser = UftToolUtils.getRunAsUser(build, listener); + if (uftRunAsUser != null) { + mergedProps.put("uftRunAsUserName", uftRunAsUser.getUsername()); + if (StringUtils.isNotBlank(uftRunAsUser.getEncodedPassword())) { + mergedProps.put("uftRunAsUserEncodedPassword", uftRunAsUser.getEncodedPasswordAsEncrypted(currNode)); + } else if (uftRunAsUser.getPassword() != null) { + mergedProps.put("uftRunAsUserPassword", uftRunAsUser.getPasswordAsEncrypted(currNode)); + } + } + } catch(IllegalArgumentException | EncryptionUtils.EncryptionException e) { + build.setResult(Result.FAILURE); + listener.fatalError(String.format("Build parameters check failed: %s.", e.getMessage())); + return; + } + int idx = 0; + for (Iterator iterator = env.keySet().iterator(); iterator.hasNext(); ) { + String key = iterator.next(); + idx++; + mergedProps.put("JenkinsEnv" + idx, key + ";" + env.get(key)); + } + + Date now = new Date(); + Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); + String time = formatter.format(now); + + // get a unique filename for the params file + String propsFileName = String.format("props%s.txt", time); + String resFileName = String.format("Results%s_%d.xml", time, build.getNumber()); + + long threadId = Thread.currentThread().getId(); + if (resultFileNames == null) { + resultFileNames = new HashMap(); + } + resultFileNames.put(threadId, resFileName); + + mergedProps.put("runType", AlmRunTypes.RunType.FileSystem.toString()); + + if (summaryDataLogModel != null) { + summaryDataLogModel.addToProps(mergedProps); + } + + if (scriptRTSSetModel != null) { + scriptRTSSetModel.addScriptsToProps(mergedProps, env); + } + + mergedProps.put("resultsFilename", resFileName); + + // parallel runner is enabled + if (isParallelRunnerEnabled) { + // add the parallel runner properties + fileSystemTestSetModel.addTestSetProperties(mergedProps, env); + + // we need to replace each mtbx test with mtbx file path + for (int index = 1; index < this.fileSystemTestSetModel.getFileSystemTestSet().size(); index++) { + String key = "Test" + index; + String content = mergedProps.getProperty(key + index, ""); + try { + replaceTestWithMtbxFile(workspace, mergedProps, content, key, time, index); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.error("Failed to save MTBX file : " + e.getMessage()); + } + } + } else { + // handling mtbx file content : + // If we have mtbx content - it is located in Test1 property and there is no other test properties (like + // Test2 etc) + // We save mtbx content in workspace and replace content of Test1 by reference to saved file + // this only applies to the normal file system flow + String firstTestKey = "Test1"; + String firstTestContent = mergedProps.getProperty(firstTestKey, ""); + try { + replaceTestWithMtbxFile(workspace, mergedProps, firstTestContent, firstTestKey, time); + } catch (Exception e) { + build.setResult(Result.FAILURE); + listener.error("Failed to save MTBX file : " + e.getMessage()); + } + } + + if (uftSettingsModel != null) { + uftSettingsModel.addToProperties(mergedProps); + } + + // cleanup report folders before running the build + String selectedNode = env.get("NODE_NAME"); + if (selectedNode == null) {//if slave is given in the pipeline and not as part of build step + try { + selectedNode = launcher.getComputer().getName(); + } catch (Exception e) { + listener.error("Failed to get selected node for UFT execution : " + e.getMessage()); + } + } + + // clean cleanuptests' report folders + int index = 1; + while (mergedProps.getProperty("CleanupTest" + index) != null) { + String testPath = mergedProps.getProperty("CleanupTest" + index); + List cleanupTests = UftToolUtils.getBuildTests(selectedNode, testPath); + for (String test : cleanupTests) { + UftToolUtils.deleteReportFoldersFromNode(selectedNode, test, listener); + } + + index++; + } + + // clean actual tests' report folders + index = 1; + while (mergedProps.getProperty("Test" + index) != null) { + String testPath = mergedProps.getProperty(("Test" + index)); + List buildTests = UftToolUtils.getBuildTests(selectedNode, testPath); + for (String test : buildTests) { + UftToolUtils.deleteReportFoldersFromNode(selectedNode, test, listener); + } + index++; + } + + mergedProps.setProperty("numOfTests", String.valueOf(index - 1)); + + // get properties serialized into a stream + String strProps; + try { + strProps = AlmToolsUtils.getPropsAsString(mergedProps); + } catch (IOException e) { + build.setResult(Result.FAILURE); + listener.error("Failed to store properties on agent machine: " + e); + return; + } + + // Get the URL to the Script used to run the test, which is bundled + // in the plugin + @SuppressWarnings("squid:S2259") + URL cmdExeUrl = Jenkins.get().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE); + if (cmdExeUrl == null) { + listener.fatalError(HP_TOOLS_LAUNCHER_EXE + " not found in resources"); + return; + } + + @SuppressWarnings("squid:S2259") + URL cmdExeCfgUrl = Jenkins.get().pluginManager.uberClassLoader.getResource(HP_TOOLS_LAUNCHER_EXE_CFG); + if (cmdExeCfgUrl == null) { + listener.fatalError(HP_TOOLS_LAUNCHER_EXE_CFG + " not found in resources"); + return; + } + + @SuppressWarnings("squid:S2259") + URL cmdExe2Url = Jenkins.get().pluginManager.uberClassLoader.getResource(LRANALYSIS_LAUNCHER_EXE); + if (cmdExe2Url == null) { + listener.fatalError(LRANALYSIS_LAUNCHER_EXE + "not found in resources"); + return; + } + + FilePath fileProps = workspace.child(propsFileName); + FilePath cmdLineExe = workspace.child(HP_TOOLS_LAUNCHER_EXE); + FilePath cmdLineExeCfg = workspace.child(HP_TOOLS_LAUNCHER_EXE_CFG); + FilePath cmdLineExe2 = workspace.child(LRANALYSIS_LAUNCHER_EXE); + + try { + // create a file for the properties file, and save the properties + if (!AlmToolsUtils.tryCreatePropsFile(listener, strProps, fileProps)) { + build.setResult(Result.FAILURE); + return; + } + // Copy the script to the project workspace + cmdLineExe.copyFrom(cmdExeUrl); + cmdLineExeCfg.copyFrom(cmdExeCfgUrl); + cmdLineExe2.copyFrom(cmdExe2Url); + } catch (IOException | InterruptedException e) { + build.setResult(Result.FAILURE); + listener.error("Failed to copy props file or UFT tools to agent machine. " + e); + } + + try { + // Run the HpToolsLauncher.exe + AlmToolsUtils.runOnBuildEnv(build, launcher, listener, cmdLineExe, propsFileName, currNode, runFromFileModel.getOutEncoding()); + // Has the report been successfully generated? + } catch (IOException ioe) { + Util.displayIOException(ioe, listener); + build.setResult(Result.FAILURE); + listener.error("Failed running HpToolsLauncher " + ioe.getMessage()); + } catch (InterruptedException e) { + build.setResult(Result.ABORTED); + listener.error("Failed running HpToolsLauncher - build aborted " + StringUtils.defaultString(e.getMessage())); + try { + AlmToolsUtils.runHpToolsAborterOnBuildEnv(build, launcher, listener, propsFileName, workspace); + } catch (IOException e1) { + Util.displayIOException(e1, listener); + build.setResult(Result.FAILURE); + } catch (InterruptedException e1) { + listener.error("Failed running HpToolsAborter " + e1.getMessage()); + } + } + } + + /** + * Gets mc server settings model. + * + * @return the mc server settings model + */ + public MCServerSettingsModel getMCServerSettingsModel() { + for (MCServerSettingsModel mcServer : getDescriptor().getMcServers()) { + if (this.runFromFileModel != null + && runFromFileModel.getMcServerName() != null + && mcServer.getMcServerName() != null + && runFromFileModel.getMcServerName().equals(mcServer.getMcServerName())) { + return mcServer; + } + } + return null; + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + /** + * Gets run from file model. + * + * @return the run from file model + */ + public RunFromFileSystemModel getRunFromFileModel() { + return runFromFileModel; + } + + /** + * Gets run results file name. + * + * @return the run results file name + */ + public String getRunResultsFileName() { + synchronized (this) { + long threadId = Thread.currentThread().getId(); + String fileName = resultFileNames.get(threadId); + return fileName; + } + } + + public boolean isAreParametersEnabled() { + return areParametersEnabled; + } + + public void setAreParametersEnabled(boolean areParametersEnabled) { + this.areParametersEnabled = areParametersEnabled; + } + + public SpecifyParametersModel getSpecifyParametersModel() { + return specifyParametersModel; + } + + /** + * The type Descriptor. + */ + @Symbol("runFromFSBuilder") + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + /** + * The Instance. + */ + JobConfigurationProxy instance = JobConfigurationProxy.getInstance(); + + /** + * Instantiates a new Descriptor. + */ + public DescriptorImpl() { + load(); + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + return true; + } + + /** + * Gets job id. + * If there is already a job created by jenkins plugin, and exists then return this job id, + * otherwise, create a new temp job and return the new job id. + * + * @param mcUrl the mc url + * @param mcUserName the mc user name + * @param mcPassword the mc password + * @param proxyAddress the proxy address + * @param proxyUserName the proxy user name + * @param proxyPassword the proxy password + * @param previousJobId the previous job id + * @return the job id + */ + @JavaScriptMethod + public String getJobId(String mcUrl, String mcUserName, String mcPassword, String mcTenantId, String accessKey, String authType, + boolean useProxyAuth, String proxyAddress, String proxyUserName, String proxyPassword, String previousJobId) { + AuthModel authModel = new AuthModel(mcUserName, mcPassword, mcTenantId, accessKey, authType); + ProxySettings proxy = new ProxySettings(useProxyAuth, proxyAddress, proxyUserName, proxyPassword); + if (null != previousJobId && !previousJobId.isEmpty()) { + JSONObject jobJSON = instance.getJobById(mcUrl, authModel, proxy, previousJobId); + if (jobJSON != null && previousJobId.equals(jobJSON.getAsString("id"))) { + return previousJobId; + } else { + return instance.createTempJob(mcUrl, authModel, proxy); + } + } + return instance.createTempJob(mcUrl, authModel, proxy); + } + + /** + * Populate app and device json object. + * + * @param mcUrl the mc url + * @param jobId the job id + * @return the json object + */ + @JavaScriptMethod + public JSONObject populateAppAndDevice(String mcUrl, String mcUserName, String mcPassword, String mcTenantId, String accessKey, String authType, + boolean useProxyAuth, String proxyAddress, String proxyUserName, String proxyPassword, + String jobId) { + AuthModel authModel = new AuthModel(mcUserName, mcPassword, mcTenantId, accessKey, authType); + ProxySettings proxy = new ProxySettings(useProxyAuth, proxyAddress, proxyUserName, proxyPassword); + return instance.getJobJSONData(mcUrl, authModel, proxy, jobId); + } + + /** + * Gets mc server url. + * + * @param serverName the server name + * @return the mc server url + */ + @SuppressWarnings("squid:S2259") + @JavaScriptMethod + public String getMcServerUrl(String serverName) { + String serverUrl = ""; + MCServerSettingsModel[] servers = MCServerSettingsGlobalConfiguration.getInstance().getInstallations(); + for (MCServerSettingsModel mcServer : servers) { + if (mcServer.getMcServerName().equals(serverName)) { + serverUrl = mcServer.getMcServerUrl().trim(); + break; + } + } + return serverUrl; + } + + @JavaScriptMethod + public JSONObject getBrowserLab(String serverName, String accessKey, boolean useProxyAuth, String proxyAddr, String proxyUserName, String proxyPassword) { + String serverUrl = getMcServerUrl(serverName); + if (StringUtils.isNotBlank(serverUrl)) { + serverUrl = StringUtils.stripEnd(serverUrl, "/"); + ProxySettings proxy = new ProxySettings(useProxyAuth, proxyAddr, proxyUserName, proxyPassword); + return instance.getBrowserLab(serverUrl, accessKey, proxy); + } + return null; + } + + @Override + public String getDisplayName() { + return Messages.RunFromFileBuilderStepName(Messages.CompanyName()); + } + + /** + * Do check fs tests form validation. + * + * @param value the value + * @return the form validation + */ + @SuppressWarnings("squid:S1172") + public FormValidation doCheckFsTests(@QueryParameter String value) { + return FormValidation.ok(); + } + + /** + * Do check ignore error strings form validation. + * + * @param value the value + * @return the form validation + */ + @SuppressWarnings("squid:S1172") + public FormValidation doCheckIgnoreErrorStrings(@QueryParameter String value) { + + return FormValidation.ok(); + } + + /** + * Do check fs timeout form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckFsTimeout(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + String sanitizedValue = value.trim(); + if (sanitizedValue.length() > 0 && sanitizedValue.charAt(0) == '-') { + sanitizedValue = sanitizedValue.substring(1); + } + + if (!isParameterizedValue(sanitizedValue) && !StringUtils.isNumeric(sanitizedValue)) { + return FormValidation.error("Timeout must be a parameter or a number, e.g.: 23, $Timeout or " + + "${Timeout}."); + } + + return FormValidation.ok(); + } + + /** + * Has mc servers boolean. + * + * @return the boolean + */ + @SuppressWarnings("squid:S2259") + public boolean hasMCServers() { + return MCServerSettingsGlobalConfiguration.getInstance().hasMCServers(); + } + + /** + * Get mc servers mc server settings model [ ]. + * + * @return the mc server settings model [ ] + */ + @SuppressWarnings("squid:S2259") + + public MCServerSettingsModel[] getMcServers() { + MCServerSettingsModel emptySrv = new MCServerSettingsModel("", ""); + MCServerSettingsModel[] servers = MCServerSettingsGlobalConfiguration.getInstance().getInstallations(); + if (servers == null) { + servers = new MCServerSettingsModel[0]; + } + int nbOfServers = servers.length; + MCServerSettingsModel[] all = new MCServerSettingsModel[nbOfServers + 1]; + all[0] = emptySrv; + for (int i = 0; i < servers.length; i++) { + all[i + 1] = servers[i]; + } + return all; + } + + /** + * Do check controller polling interval form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckControllerPollingInterval(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + if (!StringUtils.isNumeric(value)) { + return FormValidation.error("Controller Polling Interval must be a number"); + } + + return FormValidation.ok(); + } + + /** + * Do check per scenario time out form validation. + * + * @param value the value + * @return the form validation + */ + public FormValidation doCheckPerScenarioTimeOut(@QueryParameter String value) { + if (StringUtils.isEmpty(value)) { + return FormValidation.ok(); + } + + if (!isParameterizedValue(value) && !StringUtils.isNumeric(value)) { + return FormValidation.error("Per Scenario Timeout must be a parameter or a number, e.g.: 23, " + + "$ScenarioDuration or ${ScenarioDuration}."); + } + + return FormValidation.ok(); + } + + /** + * Check if the value is parameterized. + * + * @param value the value + * @return boolean + */ + public boolean isParameterizedValue(String value) { + //Parameter (with or without brackets) + return value.matches("^\\$\\{[\\w-. ]*}$|^\\$[\\w-.]*$"); + } + + public List getFsUftRunModes() { + return RunFromFileSystemModel.fsUftRunModes; + } + + public List getFsTestTypes() { + return UftSettingsModel.fsTestTypes; + } + + public List getNodes() { + return UftToolUtils.getNodesList(); + } + + public List getEncodings() { return RunFromFileSystemModel.encodings; } + } + +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/run/RunLoadRunnerScript.java b/src/main/java/com/microfocus/application/automation/tools/run/RunLoadRunnerScript.java new file mode 100644 index 0000000000..43520ca013 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/RunLoadRunnerScript.java @@ -0,0 +1,346 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.microfocus.application.automation.tools.results.lrscriptresultparser.LrScriptHtmlReportAction; +import com.microfocus.application.automation.tools.results.lrscriptresultparser.LrScriptResultsSanitizer; +import hudson.EnvVars; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Builder; +import hudson.tasks.junit.JUnitResultArchiver; +import hudson.util.ArgumentListBuilder; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import jenkins.util.VirtualFile; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.input.BOMInputStream; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.net.URL; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; + +/** + * Created by kazaky on 14/03/2017. + */ + +/** + * This step enables to run LoadRunner scripts directly and collecting their results by converting them to JUnit + */ +public class RunLoadRunnerScript extends Builder implements SimpleBuildStep { + public static final String LR_SCRIPT_HTML_REPORT_CSS = "PResults.css"; + private static final String LINUX_MDRV_PATH = "/bin/mdrv"; + private static final String WIN_MDRV_PATH = "\\bin\\mmdrv.exe"; + private static final String LR_SCRIPT_HTML_XSLT = "PDetails.xsl"; + private static final String LR_SCRIPT_HTML_CSS = "LR_SCRIPT_REPORT.css"; + private String scriptsPath; + private Jenkins jenkinsInstance; + private PrintStream logger; + private EnvVars slaveEnvVars; + + @DataBoundConstructor + public RunLoadRunnerScript(@Nonnull String scriptsPath) { + if (scriptsPath.equals(DescriptorImpl.DEFAULT_SCRIPTS_PATH)) { + this.scriptsPath = ""; + } else { + this.scriptsPath = scriptsPath; + } + } + + /** + * Returns {@link BuildStepMonitor#NONE} by default, as {@link Builder}s normally don't depend + * on its previous result. + */ + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + + public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener, @Nonnull EnvVars envVars) throws InterruptedException, + IOException { + this.slaveEnvVars = envVars; + this.perform(build, workspace, launcher, listener); + } + + @Override + public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException { + try { + jenkinsInstance = Jenkins.getInstance(); + if (jenkinsInstance == null) { + listener.error("Failed loading Jenkins instance "); + build.setResult(Result.FAILURE); + return; + } + logger = listener.getLogger(); + ArgumentListBuilder args = new ArgumentListBuilder(); + String scriptName = FilenameUtils.getBaseName(this.scriptsPath); + FilePath buildWorkDir = workspace.child(build.getId()); + buildWorkDir.mkdirs(); + buildWorkDir = buildWorkDir.absolutize(); + if(build instanceof AbstractBuild){ + slaveEnvVars = build.getEnvironment(listener); + } + FilePath scriptPath = workspace.child(slaveEnvVars.expand(this.scriptsPath)); + FilePath scriptWorkDir = buildWorkDir.child(scriptName); + scriptWorkDir.mkdirs(); + scriptWorkDir = scriptWorkDir.absolutize(); + + + if (runScriptMdrv(launcher, args, slaveEnvVars, scriptPath, scriptWorkDir)) { + build.setResult(Result.FAILURE); + return; + } + + final VirtualFile root = build.getArtifactManager().root(); + + File masterBuildWorkspace = new File(new File(root.toURI()), "LRReport"); + if (!masterBuildWorkspace.exists()) { + if (!root.exists()) { + (new File(root.toURI())).mkdirs(); + } + masterBuildWorkspace.mkdirs(); + } + + FilePath outputHTML = buildWorkDir.child(scriptName); + outputHTML.mkdirs(); + outputHTML = outputHTML.child("result.html"); + FilePath xsltOnNode = copyXsltToNode(workspace); + createHtmlReports(buildWorkDir, scriptName, outputHTML, xsltOnNode); + LrScriptResultsParser lrScriptResultsParser = new LrScriptResultsParser(listener); + lrScriptResultsParser.parseScriptResult(scriptName, buildWorkDir); + copyScriptsResultToMaster(build, listener, buildWorkDir, new FilePath(masterBuildWorkspace)); + parseJunitResult(build, launcher, listener, buildWorkDir, scriptName); + addLrScriptHtmlReportAcrion(build, scriptName); + + build.setResult(Result.SUCCESS); + + } catch (IllegalArgumentException e) { + build.setResult(Result.FAILURE); + logger.println(e); + } catch (IOException | InterruptedException e) { + listener.error("Failed loading build environment " + e); + build.setResult(Result.FAILURE); + } catch (XMLStreamException e) { + listener.error(e.getMessage(), e); + build.setResult(Result.FAILURE); + } + } + + private FilePath copyXsltToNode(@Nonnull FilePath workspace) throws IOException, InterruptedException { + final URL xsltPath = jenkinsInstance.pluginManager.uberClassLoader.getResource(LR_SCRIPT_HTML_XSLT); + logger.println("loading XSLT from " + xsltPath.getFile()); + FilePath xsltOnNode = workspace.child("resultsHtml.xslt"); + if (!xsltOnNode.exists()) { + xsltOnNode.copyFrom(xsltPath); + } + return xsltOnNode; + } + + private boolean runScriptMdrv(@Nonnull Launcher launcher, ArgumentListBuilder args, + EnvVars env, FilePath scriptPath, FilePath scriptWorkDir) + throws IOException, InterruptedException { + FilePath mdrv; + //base command line mmdrv.exe -usr "%1\%1.usr" -extra_ext NVReportExt -qt_result_dir + // "c:\%1_results" + //Do run the script on linux or windows? + mdrv = getMDRVPath(launcher, env); + args.add(mdrv); + args.add("-usr"); + args.add(scriptPath); + args.add("-extra_ext NVReportExt"); + args.add("-qt_result_dir"); + args.add(scriptWorkDir); + + int returnCode = launcher.launch().cmds(args).stdout(logger).pwd(scriptWorkDir).join(); + return returnCode != 0; + } + + private static FilePath getMDRVPath(@Nonnull Launcher launcher, EnvVars env) { + FilePath mdrv; + if (launcher.isUnix()) { + String lrPath = env.get("M_LROOT", ""); + if ("".equals(lrPath)) { + throw new LrScriptParserException( + "Please make sure environment variables are set correctly on the running node - M_LROOT for " + + "linux"); + } + lrPath += LINUX_MDRV_PATH; + mdrv = new FilePath(launcher.getChannel(), lrPath); + } else { + String lrPath = env.get("LR_PATH", ""); + if ("".equals(lrPath)) { + throw new LrScriptParserException("Please make sure environment variables are set correctly on the " + + "running node - LR_PATH for windows"); + } + lrPath += WIN_MDRV_PATH; + mdrv = new FilePath(launcher.getChannel(), lrPath); + } + return mdrv; + } + + private void addLrScriptHtmlReportAcrion(@Nonnull Run build, String scriptName) { + synchronized (build) { + LrScriptHtmlReportAction action = build.getAction(LrScriptHtmlReportAction.class); + if (action == null) { + action = new LrScriptHtmlReportAction(build); + action.mergeResult(build, scriptName); + build.addAction(action); + } else { + action.mergeResult(build, scriptName); + } + } + } + + private static void parseJunitResult(@Nonnull Run build, @Nonnull Launcher launcher, @Nonnull TaskListener + listener, + FilePath buildWorkDir, String scriptName) + throws InterruptedException, IOException { + JUnitResultArchiver jUnitResultArchiver = new JUnitResultArchiver("JunitResult.xml"); + jUnitResultArchiver.setKeepLongStdio(true); + jUnitResultArchiver.setAllowEmptyResults(true); + jUnitResultArchiver.perform(build, buildWorkDir.child(scriptName), launcher, listener); + } + + private void createHtmlReports(FilePath buildWorkDir, String scriptName, FilePath outputHTML, FilePath xsltOnNode) + throws IOException, InterruptedException, XMLStreamException { + if (!buildWorkDir.exists()) { + throw new IllegalArgumentException("Build worker doesn't exist"); + } + if ("".equals(scriptName)) { + throw new IllegalArgumentException("Script name is empty"); + } + if (!xsltOnNode.exists()) { + throw new IllegalArgumentException("LR Html report doesn't exist on the node"); + } + try { + TransformerFactory factory = TransformerFactory.newInstance(); + StreamSource xslStream = new StreamSource(xsltOnNode.read()); + Transformer transformer = factory.newTransformer(xslStream); + + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + decoder.onMalformedInput(CodingErrorAction.REPLACE).replacement(); + + final InputStreamReader inputStreamReader = new InputStreamReader(new BOMInputStream(buildWorkDir + .child(scriptName).child("Results.xml").read()), decoder); + + StreamSource in = new StreamSource(new LrScriptResultsSanitizer(inputStreamReader)); + StreamResult out = new StreamResult(outputHTML.write()); + transformer.transform(in, out); + final URL lrHtmlCSSPath = jenkinsInstance.pluginManager.uberClassLoader.getResource(LR_SCRIPT_HTML_CSS); + if (lrHtmlCSSPath == null) { + throw new LrScriptParserException( + "For some reason the jenkins instance is null - is it an improper set tests?"); + } + + FilePath lrScriptHtmlReportCss = buildWorkDir.child(scriptName).child(LR_SCRIPT_HTML_REPORT_CSS); + lrScriptHtmlReportCss.copyFrom(lrHtmlCSSPath); + + logger.println("The generated HTML file is:" + outputHTML); + } catch (TransformerConfigurationException e) { + logger.println("TransformerConfigurationException"); + logger.println(e); + } catch (TransformerException e) { + logger.println("TransformerException"); + logger.println(e); + } catch (LrScriptParserException e) { + logger.println("General exception"); + logger.println(e); + } + } + + private static void copyScriptsResultToMaster(@Nonnull Run build, @Nonnull TaskListener listener, + FilePath buildWorkDir, FilePath masterBuildWorkspace) + throws IOException, InterruptedException { + listener.getLogger().printf("Copying script results, from '%s' on node to '%s' on the master. %n" + , buildWorkDir.toURI(), build.getRootDir().toURI()); + + buildWorkDir.copyRecursiveTo(masterBuildWorkspace); + } + + public @Nonnull + String getScriptsPath() { + return scriptsPath == null ? DescriptorImpl.DEFAULT_SCRIPTS_PATH : this.scriptsPath; + } + + + @Extension + public static class DescriptorImpl extends BuildStepDescriptor { + public static final String DEFAULT_SCRIPTS_PATH = ""; + + @Override + public String getDisplayName() { + return "Run LoadRunner script"; + } + + @Override + public boolean isApplicable(@SuppressWarnings("rawtypes") Class aClass) { + return true; + } + + } + + + public static final class LrScriptParserException extends IllegalArgumentException { + + public LrScriptParserException(String s) { + super(s); + } + + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SonarOctaneListener.java b/src/main/java/com/microfocus/application/automation/tools/run/SonarOctaneListener.java new file mode 100644 index 0000000000..dd57c81c93 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SonarOctaneListener.java @@ -0,0 +1,244 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.exceptions.SonarIntegrationException; +import com.microfocus.application.automation.tools.octane.actions.WebhookAction; +import com.microfocus.application.automation.tools.octane.actions.Webhooks; +import com.microfocus.application.automation.tools.octane.model.SonarHelper; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.PrintStream; +import java.util.HashSet; +import java.util.Set; + +public class SonarOctaneListener extends Builder implements SimpleBuildStep { + + // these properties will be used for sonar communication + public String sonarToken; + public String sonarServerUrl; + boolean pushVulnerabilities; + boolean pushCoverage; + private boolean skipWebhookCreation; + + private Set dataTypeSet = new HashSet<>(); + + + @DataBoundConstructor + public SonarOctaneListener() { + } + + @DataBoundSetter + public void setSonarToken(String sonarToken) { + this.sonarToken = sonarToken; + } + + @DataBoundSetter + public void setSonarServerUrl(String sonarServerUrl) { + this.sonarServerUrl = sonarServerUrl; + } + + + @DataBoundSetter + public void setSkipWebhookCreation(boolean skipWebhookCreation) { + this.skipWebhookCreation = skipWebhookCreation; + + } + + @DataBoundSetter + public void setPushVulnerabilities(boolean pushVulnerabilities) { + this.pushVulnerabilities = pushVulnerabilities; + if (pushVulnerabilities) { + dataTypeSet.add(SonarHelper.DataType.VULNERABILITIES); + } else { + dataTypeSet.remove(SonarHelper.DataType.VULNERABILITIES); + } + + } + + @DataBoundSetter + public void setPushCoverage(boolean pushCoverage) { + this.pushCoverage = pushCoverage; + if (pushCoverage) { + dataTypeSet.add(SonarHelper.DataType.COVERAGE); + } else { + dataTypeSet.remove(SonarHelper.DataType.COVERAGE); + } + } + + /** + * get server token + * + * @return + */ + public String getSonarToken() { + return sonarToken; + } + + /** + * get server url + * + * @return + */ + public String getSonarServerUrl() { + return sonarServerUrl; + } + + /** + * is Push Vulnerabilities to octane + * + * @return + */ + public boolean isPushVulnerabilities() { + return pushVulnerabilities; + } + + /** + * is Push Coverage to octane + * + * @return + */ + public boolean isPushCoverage() { + return pushCoverage; + } + + /** + * this method is initializing sonar server details from listener configuration or + * sonar plugin data + * + * @param run current run + * @throws InterruptedException + */ + private void initializeSonarDetails(@Nonnull Run run, TaskListener listener) throws InterruptedException { + // if one of the properties is empty, need to query sonar plugin from jenkins to get the data + ExtensionList allConfigurations = GlobalConfiguration.all(); + if (allConfigurations != null) { + SonarHelper adapter = new SonarHelper(run, listener); + // get the most recent sonar server details from environments variables, and only if there is no details there take the details from the class properties. + setSonarServerUrl(StringUtils.isNullOrEmpty(adapter.getServerUrl()) ? sonarServerUrl : adapter.getServerUrl()); + setSonarToken(StringUtils.isNullOrEmpty(adapter.getServerToken()) ? sonarToken : adapter.getServerToken()); + } + } + + + private String getBuildNumber(Run run) { + if (run instanceof AbstractBuild) { + AbstractBuild abstractBuild = (AbstractBuild) run; + return String.valueOf(abstractBuild.getNumber()); + } + return ""; + } + + /** + * Run this step. + * + * @param run a build this is running as a part of + * @param workspace a workspace to use for any file operations + * @param launcher a way to start processes + * @param listener a place to send output + * @throws InterruptedException if the step is interrupted + */ + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException { + if( !OctaneSDK.hasClients()){ + return; + } + PrintStream logger = listener.getLogger(); + initializeSonarDetails(run, listener); + + String jenkinsRoot = Jenkins.get().getRootUrl(); + String callbackWebHooksURL = jenkinsRoot + Webhooks.WEBHOOK_PATH + Webhooks.NOTIFY_METHOD; + if (StringUtils.isNullOrEmpty(this.sonarServerUrl) || StringUtils.isNullOrEmpty(this.sonarToken)) { + logger.println("Webhook registration in sonarQube for build " + getBuildNumber(run) + " failed, missing sonarQube server url or sonarQube authentication token"); + } else if (!skipWebhookCreation) { + logger.println("callback URL for jenkins resource will be set to: " + callbackWebHooksURL + " in sonarQube server with URL: " + this.sonarServerUrl); + try { + OctaneSDK.getClients().get(0).getSonarService().ensureSonarWebhookExist(callbackWebHooksURL, getSonarServerUrl(), getSonarToken()); + } catch (SonarIntegrationException e) { + logger.println("Webhook registration in sonarQube for build " + getBuildNumber(run) + " failed: " + e.getMessage()); + } + } else { + logger.println("Webhook creation is skipped. Be sure that Sonar server " + this.sonarServerUrl + " has configured webhook to: " + callbackWebHooksURL); + } + run.addAction(new WebhookAction(true, getSonarServerUrl(), dataTypeSet)); + } + + @Override + public SonarDescriptor getDescriptor() { + return (SonarDescriptor) super.getDescriptor(); + } + + public boolean isSkipWebhookCreation() { + return skipWebhookCreation; + } + + @Symbol("addALMOctaneSonarQubeListener") + @Extension + public static class SonarDescriptor extends BuildStepDescriptor { + + public SonarDescriptor() { + load(); + } + + @Override + public String getDisplayName() { + return "ALM Octane SonarQube listener"; + } + + + @Override + public boolean isApplicable(Class aClass) { + return true; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SseBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/SseBuilder.java new file mode 100644 index 0000000000..e6ba8d7238 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SseBuilder.java @@ -0,0 +1,555 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.StringWriter; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.settings.AlmServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testcase; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuite; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.AncestorInPath; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.cloudbees.plugins.credentials.matchers.IdMatcher; +import com.microfocus.application.automation.tools.sse.SSEBuilderPerformer; + +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Util; +import hudson.model.*; +import hudson.model.queue.Tasks; +import hudson.security.ACL; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.VariableResolver; +import jenkins.tasks.SimpleBuildStep; + +import static com.microfocus.application.automation.tools.Messages.CompanyName; +import static com.microfocus.application.automation.tools.Messages.SseBuilderStepName; + +/*** + * This Jenkins plugin contains an unofficial implementation of some of the elements of the HPE ALM + * Lab Management SDK. Users are free to use this plugin as they wish, but HPE does not take + * responsibility for supporting or providing backwards compatibility for the functionality herein. + * + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class SseBuilder extends Builder implements SimpleBuildStep { + + private SseModel _sseModel; + private String _fileName; + + private String almServerName; + private String credentialsId; + private String clientType; + private String almDomain; + private String almProject; + private String description; + private String runType; + private String almEntityId; + private String timeslotDuration; + private String postRunAction; + private String environmentConfigurationId; + private CdaDetails cdaDetails; + + //Databound setters and getters. + public String getAlmServerName() { return almServerName; } + public String getCredentialsId() { return credentialsId; } + public String getClientType() { return clientType; } + public String getAlmDomain() { return almDomain; } + public String getAlmProject() { return almProject; } + public String getDescription() { return description; } + public String getRunType() { return runType; } + public String getAlmEntityId() { return almEntityId; } + public String getTimeslotDuration() { return timeslotDuration; } + public String getPostRunAction() { return postRunAction; } + public String getEnvironmentConfigurationId() { return environmentConfigurationId; } + public CdaDetails getCdaDetails() { return cdaDetails; } + + public boolean isCdaDetailsChecked() { + return cdaDetails != null; + } + + @DataBoundSetter + public void setDescription(String description) { this.description = description; } + + @DataBoundSetter + public void setPostRunAction(String postRunAction) { this.postRunAction = postRunAction; } + + @DataBoundSetter + public void setEnvironmentConfigurationId(String environmentConfigurationId) { + this.environmentConfigurationId = environmentConfigurationId; + } + + @DataBoundSetter + public void setCdaDetails(CdaDetails cdaDetails) { this.cdaDetails = cdaDetails; } + + /** + * Should only contains mandatory properties. + */ + @DataBoundConstructor + public SseBuilder(String almServerName, + String almProject, + String credentialsId, + String clientType, + String almDomain, + String runType, + String almEntityId, + String timeslotDuration) { + + this.almServerName = almServerName; + this.credentialsId = credentialsId; + this.almProject = almProject; + this.almDomain = almDomain; + this.timeslotDuration = timeslotDuration; + this.runType = runType; + this.almEntityId = almEntityId; + this.clientType = clientType; + } + + @Override + public void perform(Run build, FilePath workspace, Launcher launcher, TaskListener listener) + throws InterruptedException, IOException { + + PrintStream logger = listener.getLogger(); + + UsernamePasswordCredentials credentials = getCredentialsById(credentialsId, build, logger); + + _sseModel = new SseModel( + almServerName, + credentials.getUsername(), + credentials.getPassword().getPlainText(), + almDomain, + clientType, + almProject, + runType, + almEntityId, + timeslotDuration, + description, + postRunAction, + environmentConfigurationId, + cdaDetails); + + _sseModel.setAlmServerUrl(getServerUrl(_sseModel.getAlmServerName())); + + VariableResolver varResolver = new VariableResolver.ByMap(build.getEnvironment(listener)); + Testsuites testsuites = execute(build, logger, varResolver); + + String resultsFilename = generateResultsFilename(); + FilePath resultsFilePath = workspace.child(resultsFilename); + Result resultStatus = createRunResults(resultsFilePath, testsuites, logger); + provideStepResultStatus(resultStatus, build, logger); + + //params used when run with Pipeline + ParametersAction parameterAction = build.getAction(ParametersAction.class); + List newParams = (parameterAction != null) ? new ArrayList<>(parameterAction.getAllParameters()) : new ArrayList<>(); + newParams.add(new StringParameterValue("buildStepName", "RunFromAlmLabManagementBuilder")); + newParams.add(new StringParameterValue("resultsFilename", resultsFilename)); + build.addOrReplaceAction(new ParametersAction(newParams)); + } + + /** + * Get user name password credentials by id. + */ + private UsernamePasswordCredentials getCredentialsById(String credentialsId, Run run, PrintStream logger) { + if (StringUtils.isBlank(credentialsId)) { + throw new NullPointerException("credentials is not configured."); + } + + UsernamePasswordCredentials credentials = CredentialsProvider.findCredentialById(credentialsId, + StandardUsernamePasswordCredentials.class, + run, + URIRequirementBuilder.create().build()); + + if (credentials == null) { + logger.println("Can not find credentials with the credentialsId:" + credentialsId); + } + return credentials; + } + + public AlmServerSettingsModel getAlmServerSettingsModel() { + AlmServerSettingsModel ret = null; + for (AlmServerSettingsModel almServer : getDescriptor().getAlmServers()) { + if (this.almServerName.equals(almServer.getAlmServerName())) { + ret = almServer; + break; + } + } + return ret; + } + + private void provideStepResultStatus( + Result resultStatus, + Run build, + PrintStream logger) { + + logger.println(String.format("Result Status: %s", resultStatus.toString())); + build.setResult(resultStatus); + + } + + private Testsuites execute( + Run build, + PrintStream logger, + VariableResolver buildVariableResolver) throws InterruptedException { + + Testsuites ret = null; + SSEBuilderPerformer performer = null; + try { + performer = new SSEBuilderPerformer(); + ret = execute(performer, logger, buildVariableResolver); + } catch (InterruptedException e) { + build.setResult(Result.ABORTED); + stop(performer, logger); + throw e; + } catch (Exception cause) { + build.setResult(Result.FAILURE); + logger.print(String.format("Failed to execute test, Exception: %s", cause.getMessage())); + } + + return ret; + } + + private Result createRunResults(FilePath filePath, Testsuites testsuites, PrintStream logger) { + Result ret = Result.SUCCESS; + try { + if (testsuites != null && !testsuites.getTestsuite().isEmpty()) { + StringWriter writer = new StringWriter(); + JAXBContext context; + Thread t = Thread.currentThread(); + ClassLoader orig = t.getContextClassLoader(); + t.setContextClassLoader(SseBuilder.class.getClassLoader()); + try { + context = JAXBContext.newInstance(Testsuites.class); + } finally { + t.setContextClassLoader(orig); + } + Marshaller marshaller = context.createMarshaller(); + marshaller.marshal(testsuites, writer); + filePath.write(writer.toString(), null); + if (containsErrors(testsuites.getTestsuite())) { + ret = Result.UNSTABLE; + } + } else { + logger.println("Empty Results"); + ret = Result.FAILURE; + } + } catch (Exception cause) { + logger.print(String.format( + "Failed to create run results, Exception: %s", + cause.getMessage())); + ret = Result.FAILURE; + } + + return ret; + } + + private boolean containsErrors(List testsuites) { + + boolean ret = false; + for (Testsuite testsuite : testsuites) { + for (Testcase testcase : testsuite.getTestcase()) { + if ("error".equals(testcase.getStatus())) { + ret = true; + break; + } + } + } + + return ret; + } + + private String generateResultsFilename() { + + Format formatter = new SimpleDateFormat("ddMMyyyyHHmmssSSS"); + String time = formatter.format(new Date()); + _fileName = String.format("Results%s.xml", time); + return _fileName; + } + + private void stop(SSEBuilderPerformer performer, PrintStream logger) { + + try { + if (performer != null) { + performer.stop(); + } + } catch (Exception cause) { + logger.println(String.format("Failed to stop BVS. Exception: %s", cause.getMessage())); + } + } + + private Testsuites execute( + SSEBuilderPerformer performer, + final PrintStream logger, + VariableResolver buildVariableResolver) throws InterruptedException, + IOException { + + return performer.start(_sseModel, new Logger() { + + @Override + public void log(String message) { + + logger.println(message); + } + + @Override + public void error(String message) { + log(message); + } + }, buildVariableResolver); + } + + public String getServerUrl(String almServerName) { + + String ret = ""; + AlmServerSettingsModel[] almServers = getDescriptor().getAlmServers(); + if (almServers != null && almServers.length > 0) { + for (AlmServerSettingsModel almServer : almServers) { + if (almServerName.equals(almServer.getAlmServerName())) { + ret = almServer.getAlmServerUrl(); + break; + } + } + } + + return ret; + } + + public SseModel getSseModel() { + + return _sseModel; + } + + public String getRunResultsFileName() { + + return _fileName; + } + + @Override + public DescriptorImpl getDescriptor() { + + return (DescriptorImpl) super.getDescriptor(); + } + + // This indicates to Jenkins that this is an implementation of an extension point + @Extension + // To expose this builder in the Snippet Generator. + @Symbol("sseBuild") + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + + load(); + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + @Override + public String getDisplayName() { + return SseBuilderStepName(CompanyName()); + } + + public boolean hasAlmServers() { + + return AlmServerSettingsGlobalConfiguration.getInstance().hasAlmServers(); + } + + public AlmServerSettingsModel[] getAlmServers() { + return AlmServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + public FormValidation doCheckTimeslotDuration(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Timeslot duration must be set"); + } + + String val1 = value.trim(); + + if (!StringUtils.isNumeric(val1)) { + return FormValidation.error("Timeslot duration must be a number"); + } + + if (Integer.valueOf(val1) < 30) { + return FormValidation.error("Timeslot duration must be higher than 30"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmDomain(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Domain must be set"); + } + + return ret; + } + + public FormValidation doCheckAlmProject(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Project must be set"); + } + + return ret; + } + + public FormValidation doCheckAlmEntityId(@QueryParameter String value) { + + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Entity must be set."); + } + + return ret; + } + + public List getRunTypes() { + + return SseModel.getRunTypes(); + } + + public List getPostRunActions() { + + return SseModel.getPostRunActions(); + } + + public List getDeploymentActions() { + + return CdaDetails.getDeploymentActions(); + } + + public static List getDeprovisioningActions() { + + return CdaDetails.getDeprovisioningActions(); + } + + /** + * To fill in the credentials drop down list which's field is 'credentialsId'. + * This method's name works with tag . + */ + public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item project, + @QueryParameter String credentialsId) { + + if (project == null || !project.hasPermission(Item.CONFIGURE)) { + return new StandardUsernameListBoxModel().includeCurrentValue(credentialsId); + } + return new StandardUsernameListBoxModel() + .includeEmptyValue() + .includeAs( + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + project, + StandardUsernamePasswordCredentials.class, + URIRequirementBuilder.create().build()) + .includeCurrentValue(credentialsId); + } + + public FormValidation doCheckCredentialsId(@AncestorInPath Item project, + @QueryParameter String url, + @QueryParameter String value) { + if (project == null || !project.hasPermission(Item.EXTENDED_READ)) { + return FormValidation.ok(); + } + + value = Util.fixEmptyAndTrim(value); + if (value == null) { + return FormValidation.ok(); + } + + url = Util.fixEmptyAndTrim(url); + if (url == null) + // not set, can't check + { + return FormValidation.ok(); + } + + if (url.indexOf('$') >= 0) + // set by variable, can't check + { + return FormValidation.ok(); + } + + for (ListBoxModel.Option o : CredentialsProvider.listCredentials( + StandardUsernamePasswordCredentials.class, + project, + project instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) project) : ACL.SYSTEM, + URIRequirementBuilder.create().build(), + new IdMatcher(value))) { + + if (StringUtils.equals(value, o.value)) { + return FormValidation.ok(); + } + } + // no credentials available, can't check + return FormValidation.warning("Cannot find any credentials with id " + value); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SvChangeModeBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/SvChangeModeBuilder.java new file mode 100644 index 0000000000..3505cb2aa8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SvChangeModeBuilder.java @@ -0,0 +1,229 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import javax.annotation.Nonnull; +import java.io.PrintStream; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.microfocus.application.automation.tools.model.SvChangeModeModel; +import com.microfocus.application.automation.tools.model.SvDataModelSelection; +import com.microfocus.application.automation.tools.model.SvPerformanceModelSelection; +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRemoteRunner; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunBuilder; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunDescriptor; +import com.microfocus.application.automation.tools.sv.runner.ServiceInfo; +import com.microfocus.sv.svconfigurator.core.IProjectElement; +import com.microfocus.sv.svconfigurator.core.IService; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; +import com.microfocus.sv.svconfigurator.processor.ChmodeProcessor; +import com.microfocus.sv.svconfigurator.processor.ChmodeProcessorInput; +import com.microfocus.sv.svconfigurator.processor.IChmodeProcessor; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.TaskListener; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +/** + * Performs change mode of virtual service + */ +public class SvChangeModeBuilder extends AbstractSvRunBuilder { + private static final Logger LOG = Logger.getLogger(SvChangeModeBuilder.class.getName()); + + @DataBoundConstructor + public SvChangeModeBuilder(String serverName, boolean force, ServiceRuntimeConfiguration.RuntimeMode mode, + SvDataModelSelection dataModel, SvPerformanceModelSelection performanceModel, SvServiceSelectionModel serviceSelection) { + super(new SvChangeModeModel(serverName, force, mode, dataModel, performanceModel, serviceSelection)); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @SuppressWarnings("unused") + public SvDataModelSelection getDataModel() { + return model.getDataModel(); + } + + @SuppressWarnings("unused") + public SvPerformanceModelSelection getPerformanceModel() { + return model.getPerformanceModel(); + } + + @Override + protected RemoteRunner getRemoteRunner(@Nonnull FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + return new RemoteRunner(model, workspace, listener, server); + } + + private static class RemoteRunner extends AbstractSvRemoteRunner { + + private RemoteRunner(SvChangeModeModel model, FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + super(listener, model, workspace, server); + } + + @Override + public String call() throws Exception { + PrintStream logger = listener.getLogger(); + + ICommandExecutor exec = createCommandExecutor(); + for (ServiceInfo service : getServiceList(false, logger, workspace)) { + changeServiceMode(service, logger, exec); + } + + return null; + } + + private void changeServiceMode(ServiceInfo serviceInfo, PrintStream logger, ICommandExecutor commandExecutor) throws Exception { + + String dataModel = model.getDataModel().getSelectedModelName(); + String performanceModel = model.getPerformanceModel().getSelectedModelName(); + boolean useDefaultDataModel = model.getDataModel().isDefaultSelected(); + boolean useDefaultPerformanceModel = model.getPerformanceModel().isDefaultSelected(); + ServiceRuntimeConfiguration.RuntimeMode targetMode = getTargetMode(); + + ChmodeProcessorInput chmodeInput = new ChmodeProcessorInput(model.isForce(), null, serviceInfo.getId(), + dataModel, performanceModel, targetMode, useDefaultDataModel, useDefaultPerformanceModel); + + logger.printf(" Changing mode of service '%s' [%s] to %s mode%n", serviceInfo.getName(), serviceInfo.getId(), model.getMode()); + + IChmodeProcessor processor = new ChmodeProcessor(null); + + try { + processor.process(chmodeInput, commandExecutor); + } finally { + printServiceStatus(logger, serviceInfo, commandExecutor); + } + } + + private ServiceRuntimeConfiguration.RuntimeMode getTargetMode() { + // Set STAND_BY with PM in case of simulation without data model to be in accord with designer & SVM + if (model.getMode() == ServiceRuntimeConfiguration.RuntimeMode.SIMULATING + && !model.getPerformanceModel().isNoneSelected() + && model.getDataModel().isNoneSelected()) { + return ServiceRuntimeConfiguration.RuntimeMode.STAND_BY; + } + + return model.getMode(); + } + + private void printServiceStatus(PrintStream logger, ServiceInfo serviceInfo, ICommandExecutor commandExecutor) { + try { + IService service = commandExecutor.findService(serviceInfo.getId(), null); + ServiceRuntimeConfiguration info = commandExecutor.getServiceRuntimeInfo(service); + ServiceRuntimeConfiguration.RuntimeMode mode = getDisplayRuntimeMode(info); + + logger.printf(" Service '%s' [%s] is in %s mode%n", service.getName(), service.getId(), mode); + if (mode == ServiceRuntimeConfiguration.RuntimeMode.LEARNING || mode == ServiceRuntimeConfiguration.RuntimeMode.SIMULATING) { + logger.println(" Data model: " + getModelName(service.getDataModels(), info.getDataModelId())); + logger.println(" Performance model: " + getModelName(service.getPerfModels(), info.getPerfModelId())); + } + + if (info.getDeploymentErrorMessage() != null) { + logger.println(" Error message: " + info.getDeploymentErrorMessage()); + } + } catch (Exception e) { + String msg = String.format("Failed to get detail of service '%s' [%s]", serviceInfo.getName(), serviceInfo.getId()); + logger.printf(" %s: %s%n", msg, e.getMessage()); + LOG.log(Level.SEVERE, msg, e); + } + } + + private ServiceRuntimeConfiguration.RuntimeMode getDisplayRuntimeMode(ServiceRuntimeConfiguration info) { + // display SIMULATING in case of STAND_BY mode with PM set (as it is done in designer and SVM) + return (info.getRuntimeMode() == ServiceRuntimeConfiguration.RuntimeMode.STAND_BY && info.getPerfModelId() != null) + ? ServiceRuntimeConfiguration.RuntimeMode.SIMULATING + : info.getRuntimeMode(); + } + + private String getModelName(Collection models, String modelId) { + for (IProjectElement model : models) { + if (model.getId().equals(modelId)) { + return String.format("'%s' [%s]", model.getName(), modelId); + } + } + return null; + } + } + + @Override + protected void logConfig(PrintStream logger, String prefix) { + super.logConfig(logger, prefix); + logger.println(prefix + "Mode: " + model.getMode().toString()); + logger.println(prefix + "Data model: " + model.getDataModel().toString()); + logger.println(prefix + "Performance model: " + model.getPerformanceModel().toString()); + } + + @Extension + public static final class DescriptorImpl extends AbstractSvRunDescriptor { + + public DescriptorImpl() { + super("SV: Change Mode of Virtual Service"); + } + + @SuppressWarnings("unused") + public FormValidation doCheckDataModel(@QueryParameter String value, @QueryParameter("mode") String mode, @QueryParameter("serviceSelectionKind") String kind) { + if (StringUtils.isNotBlank(mode)) { + ServiceRuntimeConfiguration.RuntimeMode runtimeMode = ServiceRuntimeConfiguration.RuntimeMode.valueOf(mode); + if ((ServiceRuntimeConfiguration.RuntimeMode.SIMULATING == runtimeMode + || ServiceRuntimeConfiguration.RuntimeMode.LEARNING == runtimeMode) + && StringUtils.isBlank(value)) { + return FormValidation.ok("First data model will be used if not specified"); + } + if (ServiceRuntimeConfiguration.RuntimeMode.STAND_BY == runtimeMode && StringUtils.isNotBlank(value)) { + return FormValidation.warning("Data model will not be used in Stand-By mode"); + } + } + return FormValidation.ok(); + } + + @SuppressWarnings("unused") + public ListBoxModel doFillModeItems() { + ListBoxModel items = new ListBoxModel(); + items.add("Stand-By", ServiceRuntimeConfiguration.RuntimeMode.STAND_BY.toString()); + items.add("Simulate", ServiceRuntimeConfiguration.RuntimeMode.SIMULATING.toString()); + items.add("Learn", ServiceRuntimeConfiguration.RuntimeMode.LEARNING.toString()); + items.add("Offline", ServiceRuntimeConfiguration.RuntimeMode.OFFLINE.toString()); + return items; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SvDeployBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/SvDeployBuilder.java new file mode 100644 index 0000000000..7826bc2467 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SvDeployBuilder.java @@ -0,0 +1,162 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import javax.annotation.Nonnull; +import java.io.PrintStream; +import java.util.ArrayList; + +import com.microfocus.application.automation.tools.model.SvDeployModel; +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRemoteRunner; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunBuilder; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunDescriptor; +import com.microfocus.sv.svconfigurator.core.IDataModel; +import com.microfocus.sv.svconfigurator.core.IPerfModel; +import com.microfocus.sv.svconfigurator.core.IProject; +import com.microfocus.sv.svconfigurator.core.IService; +import com.microfocus.sv.svconfigurator.processor.DeployProcessor; +import com.microfocus.sv.svconfigurator.processor.DeployProcessorInput; +import com.microfocus.sv.svconfigurator.processor.IDeployProcessor; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import com.microfocus.sv.svconfigurator.util.ProjectUtils; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.TaskListener; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +public class SvDeployBuilder extends AbstractSvRunBuilder { + + @DataBoundConstructor + public SvDeployBuilder(String serverName, boolean force, String service, String projectPath, String projectPassword, + boolean firstAgentFallback) { + super(new SvDeployModel(serverName, force, service, projectPath, projectPassword, firstAgentFallback)); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + protected RemoteRunner getRemoteRunner(@Nonnull FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + return new RemoteRunner(model, workspace, listener, server); + } + + private static class RemoteRunner extends AbstractSvRemoteRunner { + + private RemoteRunner(SvDeployModel model, FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + super(listener, model, workspace, server); + } + + @Override + public String call() throws Exception { + PrintStream logger = listener.getLogger(); + + IProject project = loadProject(workspace); + printProjectContent(project, logger); + deployServiceFromProject(project, logger); + + return null; + } + + private void printProjectContent(IProject project, PrintStream logger) { + logger.println(" Project content:"); + for (IService service : project.getServices()) { + logger.println(" Service: " + service.getName() + " [" + service.getId() + "]"); + for (IDataModel dataModel : service.getDataModels()) { + logger.println(" DM: " + dataModel.getName() + " [" + dataModel.getId() + "]"); + } + for (IPerfModel perfModel : service.getPerfModels()) { + logger.println(" PM: " + perfModel.getName() + " [" + perfModel.getId() + "]"); + } + } + } + + private Iterable getServiceList(IProject project) { + if (model.getService() == null) { + return project.getServices(); + } else { + ArrayList list = new ArrayList<>(); + list.add(ProjectUtils.findProjElem(project.getServices(), model.getService())); + return list; + } + } + + private void deployServiceFromProject(IProject project, PrintStream logger) throws Exception { + IDeployProcessor processor = new DeployProcessor(null); + ICommandExecutor commandExecutor = createCommandExecutor(); + + for (IService service : getServiceList(project)) { + logger.printf(" Deploying service '%s' [%s] %n", service.getName(), service.getId()); + DeployProcessorInput deployInput = new DeployProcessorInput(model.isForce(), false, project, model.getService(), null, false); + deployInput.setFirstAgentFailover(model.isFirstAgentFallback()); + processor.process(deployInput, commandExecutor); + } + } + } + + @Override + protected void logConfig(PrintStream logger, String prefix) { + super.logConfig(logger, prefix); + logger.println(prefix + "First agent fallback: " + model.isFirstAgentFallback()); + } + + @Extension + public static final class DescriptorImpl extends AbstractSvRunDescriptor { + + public DescriptorImpl() { + super("SV: Deploy Virtual Service"); + } + + @SuppressWarnings("unused") + public FormValidation doCheckProjectPath(@QueryParameter String projectPath) { + if (StringUtils.isBlank(projectPath)) { + return FormValidation.error("Project path cannot be empty"); + } + return FormValidation.ok(); + } + + @SuppressWarnings("unused") + public FormValidation doCheckService(@QueryParameter String service) { + if (StringUtils.isBlank(service)) { + return FormValidation.ok("All services from project will be deployed if no service is specified"); + } + return FormValidation.ok(); + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SvExportBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/SvExportBuilder.java new file mode 100644 index 0000000000..4f81aecd64 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SvExportBuilder.java @@ -0,0 +1,199 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import javax.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; + +import com.microfocus.application.automation.tools.model.SvExportModel; +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRemoteRunner; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunBuilder; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunDescriptor; +import com.microfocus.application.automation.tools.sv.runner.ServiceInfo; +import com.microfocus.sv.svconfigurator.build.ProjectBuilder; +import com.microfocus.sv.svconfigurator.core.IProject; +import com.microfocus.sv.svconfigurator.core.IService; +import com.microfocus.sv.svconfigurator.core.impl.exception.CommandExecutorException; +import com.microfocus.sv.svconfigurator.core.impl.exception.CommunicatorException; +import com.microfocus.sv.svconfigurator.core.impl.exception.SVCParseException; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.ServiceRuntimeConfiguration; +import com.microfocus.sv.svconfigurator.processor.ChmodeProcessor; +import com.microfocus.sv.svconfigurator.processor.ChmodeProcessorInput; +import com.microfocus.sv.svconfigurator.processor.ExportProcessor; +import com.microfocus.sv.svconfigurator.processor.IChmodeProcessor; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.TaskListener; +import hudson.util.FormValidation; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +/** + * Performs export of of virtual service + */ +public class SvExportBuilder extends AbstractSvRunBuilder { + + @DataBoundConstructor + public SvExportBuilder(String serverName, boolean force, String targetDirectory, boolean cleanTargetDirectory, + SvServiceSelectionModel serviceSelection, boolean switchToStandByFirst, boolean archive) { + super(new SvExportModel(serverName, force, targetDirectory, cleanTargetDirectory, serviceSelection, switchToStandByFirst, archive)); + } + + @Override + protected void logConfig(PrintStream logger, String prefix) { + logger.println(prefix + "Target Directory: " + model.getTargetDirectory()); + logger.println(prefix + "Switch to Stand-By: " + model.isSwitchToStandByFirst()); + super.logConfig(logger, prefix); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + protected RemoteRunner getRemoteRunner(@Nonnull FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + return new RemoteRunner(model, workspace, listener, server); + } + + private static class RemoteRunner extends AbstractSvRemoteRunner { + + private RemoteRunner(SvExportModel model, FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + super(listener, model, workspace, server); + } + + @Override + public String call() throws Exception { + PrintStream logger = listener.getLogger(); + + verifyNotNull(model.getTargetDirectory(), "Target directory must be set"); + + ExportProcessor exportProcessor = new ExportProcessor(null); + IChmodeProcessor chmodeProcessor = new ChmodeProcessor(null); + IProject project = null; + String targetDirectory = workspace.child(model.getTargetDirectory()).getRemote(); + + ICommandExecutor exec = createCommandExecutor(); + + if (model.isCleanTargetDirectory()) { + cleanTargetDirectory(logger, new FilePath(new File(targetDirectory))); + } + + if (model.getServiceSelection().getSelectionType().equals(SvServiceSelectionModel.SelectionType.PROJECT)) { + project = new ProjectBuilder().buildProject(new File(model.getServiceSelection().getProjectPath()), model.getServiceSelection().getProjectPassword()); + } + + for (ServiceInfo serviceInfo : getServiceList(false, logger, workspace)) { + if (model.isSwitchToStandByFirst()) { + switchToStandBy(serviceInfo, chmodeProcessor, exec, logger); + } + + logger.printf(" Exporting service '%s' [%s] to %s %n", serviceInfo.getName(), serviceInfo.getId(), targetDirectory); + verifyNotLearningBeforeExport(logger, exec, serviceInfo); + if (!model.getServiceSelection().getSelectionType().equals(SvServiceSelectionModel.SelectionType.PROJECT)) { + exportProcessor.process(exec, targetDirectory, serviceInfo.getId(), project, false, model.isArchive(), false); + } + } + if (model.getServiceSelection().getSelectionType().equals(SvServiceSelectionModel.SelectionType.PROJECT)) { + exportProcessor.process(exec, targetDirectory, null, project, false, model.isArchive(), false); + } + return null; + } + + private void switchToStandBy(ServiceInfo service, IChmodeProcessor chmodeProcessor, ICommandExecutor exec, PrintStream logger) + throws CommandExecutorException, SVCParseException, CommunicatorException { + + logger.printf(" Switching service '%s' [%s] to Stand-By mode before export%n", service.getName(), service.getId()); + ChmodeProcessorInput chmodeInput = new ChmodeProcessorInput(model.isForce(), null, service.getId(), null, null, + ServiceRuntimeConfiguration.RuntimeMode.STAND_BY, false, false); + chmodeProcessor.process(chmodeInput, exec); + } + + private void cleanTargetDirectory(PrintStream logger, FilePath targetDirectory) throws IOException, InterruptedException { + if (targetDirectory.exists()) { + List subfolders = targetDirectory.listDirectories(); + List files = targetDirectory.list(new SuffixFileFilter(".vproj")); + if (subfolders.size() > 0 || files.size() > 0) { + logger.println(" Cleaning target directory..."); + } + for (FilePath file : files) { + file.delete(); + } + for (FilePath subfolder : subfolders) { + if (subfolder.list(new SuffixFileFilter(".vproj")).size() > 0) { + logger.println(" Deleting subfolder of target directory: " + subfolder.absolutize()); + subfolder.deleteRecursive(); + } else { + logger.println(" Skipping delete of directory '" + subfolder.absolutize() + "' because it does not contain any *.vproj file."); + } + } + } + } + + private void verifyNotLearningBeforeExport(PrintStream logger, ICommandExecutor exec, ServiceInfo serviceInfo) + throws CommunicatorException, CommandExecutorException { + + IService service = exec.findService(serviceInfo.getId(), null); + ServiceRuntimeConfiguration info = exec.getServiceRuntimeInfo(service); + if (info.getRuntimeMode() == ServiceRuntimeConfiguration.RuntimeMode.LEARNING) { + logger.printf(" WARNING: Service '%s' [%s] is in Learning mode. Exported model need not be complete!", + serviceInfo.getName(), serviceInfo.getId()); + } + } + } + + + @Extension + public static final class DescriptorImpl extends AbstractSvRunDescriptor { + + public DescriptorImpl() { + super("SV: Export Virtual Service"); + } + + @SuppressWarnings("unused") + public FormValidation doCheckTargetDirectory(@QueryParameter String targetDirectory) { + if (StringUtils.isBlank(targetDirectory)) { + return FormValidation.error("Target directory cannot be empty"); + } + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/SvUndeployBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/SvUndeployBuilder.java new file mode 100644 index 0000000000..29f7421951 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/SvUndeployBuilder.java @@ -0,0 +1,108 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import javax.annotation.Nonnull; +import java.io.PrintStream; + +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.application.automation.tools.model.SvUndeployModel; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRemoteRunner; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunBuilder; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunDescriptor; +import com.microfocus.application.automation.tools.sv.runner.ServiceInfo; +import com.microfocus.sv.svconfigurator.processor.IUndeployProcessor; +import com.microfocus.sv.svconfigurator.processor.UndeployProcessor; +import com.microfocus.sv.svconfigurator.processor.UndeployProcessorInput; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import hudson.Extension; +import hudson.FilePath; +import hudson.model.TaskListener; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Deletes selected virtual service from server + */ +public class SvUndeployBuilder extends AbstractSvRunBuilder { + + @DataBoundConstructor + public SvUndeployBuilder(String serverName, boolean continueIfNotDeployed, boolean force, SvServiceSelectionModel serviceSelection) { + super(new SvUndeployModel(serverName, continueIfNotDeployed, force, serviceSelection)); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + protected RemoteRunner getRemoteRunner(@Nonnull FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + return new RemoteRunner(model, workspace, listener, server); + } + + private static class RemoteRunner extends AbstractSvRemoteRunner { + + private RemoteRunner(SvUndeployModel model, FilePath workspace, TaskListener listener, SvServerSettingsModel server) { + super(listener, model, workspace, server); + } + + @Override + public String call() throws Exception { + PrintStream logger = listener.getLogger(); + + IUndeployProcessor processor = new UndeployProcessor(null); + ICommandExecutor exec = createCommandExecutor(); + for (ServiceInfo service : getServiceList(model.isContinueIfNotDeployed(), logger, workspace)) { + logger.printf(" Undeploying service '%s' [%s] %n", service.getName(), service.getId()); + UndeployProcessorInput undeployProcessorInput = new UndeployProcessorInput(model.isForce(), null, service.getId()); + processor.process(undeployProcessorInput, exec); + } + + return null; + } + } + @Override + protected void logConfig(PrintStream logger, String prefix) { + super.logConfig(logger, prefix); + logger.println(prefix + "Continue if not deployed: " + model.isContinueIfNotDeployed()); + } + + @Extension + public static final class DescriptorImpl extends AbstractSvRunDescriptor { + + public DescriptorImpl() { + super("SV: Undeploy Virtual Service"); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/UftOctaneUtils.java b/src/main/java/com/microfocus/application/automation/tools/run/UftOctaneUtils.java new file mode 100644 index 0000000000..693ec37f60 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/UftOctaneUtils.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.hp.octane.integrations.OctaneSDK; +import com.microfocus.application.automation.tools.octane.executor.UftConstants; +import com.microfocus.application.automation.tools.octane.model.processors.projects.JobProcessorFactory; +import com.microfocus.application.automation.tools.octane.tests.HPRunnerType; +import hudson.model.*; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; + +public class UftOctaneUtils { + + private UftOctaneUtils(){ + //for codeclimate + } + + /** + * This step is important for integration with Octane when job is executed as workflow job. + * Our plugin can recognize UFT build step when its executed in context of freeStyle job, but its not possible to do it + * when this step executed in workflow job. + * So , in this method we add parameter of RunnerType.UFT to sign this job as UFT runner. + * @param build + * @param listener + */ + public static void setUFTRunnerTypeAsParameter(@Nonnull Run build, @Nonnull TaskListener listener) { + if (JobProcessorFactory.WORKFLOW_RUN_NAME.equals(build.getClass().getName()) && OctaneSDK.hasClients()) { + listener.getLogger().println("Set HPRunnerType = HPRunnerType.UFT"); + ParametersAction parameterAction = build.getAction(ParametersAction.class); + List newParams = (parameterAction != null) ? new ArrayList<>(parameterAction.getAllParameters()) : new ArrayList<>(); + newParams.add(new StringParameterValue(HPRunnerType.class.getSimpleName(), HPRunnerType.UFT.name())); + ParametersAction newParametersAction = new ParametersAction(newParams); + build.addOrReplaceAction(newParametersAction); + + if (parameterAction == null || parameterAction.getParameter(UftConstants.UFT_CHECKOUT_FOLDER) == null) { + listener.getLogger().println("NOTE : If you need to integrate test results with an ALM Octane pipeline, and tests are located outside of the job workspace, define a parameter " + UftConstants.UFT_CHECKOUT_FOLDER + + " with the path to the repository root in the file system. This enables ALM Octane to display the test name, rather than the full path to your test."); + listener.getLogger().println(""); + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/run/UploadAppBuilder.java b/src/main/java/com/microfocus/application/automation/tools/run/UploadAppBuilder.java new file mode 100644 index 0000000000..9fe31cf824 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/run/UploadAppBuilder.java @@ -0,0 +1,310 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.run; + +import com.microfocus.application.automation.tools.mc.Constants; +import com.microfocus.application.automation.tools.mc.JobConfigurationProxy; +import com.microfocus.application.automation.tools.model.*; +import com.microfocus.application.automation.tools.settings.MCServerSettingsGlobalConfiguration; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Util; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.BuildListener; +import hudson.model.Result; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import org.apache.commons.io.FilenameUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.bind.JavaScriptMethod; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created with IntelliJ IDEA. + * User: jingwei + * Date: 5/17/16 + * Time: 4:36 PM + * To change this template use File | Settings | File Templates. + */ +public class UploadAppBuilder extends Builder { + + private final UploadAppModel uploadAppModel; + + @DataBoundConstructor + public UploadAppBuilder(String mcServerName, AuthModel authModel, ProxySettings proxySettings, List applicationPaths) { + uploadAppModel = new UploadAppModel(mcServerName, authModel, proxySettings, applicationPaths); + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) + throws InterruptedException, IOException { + // get the Digital Lab server settings + MCServerSettingsModel mcServerSettingsModel = getMCServerSettingsModel(); + JobConfigurationProxy job = JobConfigurationProxy.getInstance(); + JSONObject app = null; + String mcServerUrl = ""; + PrintStream out = listener.getLogger(); + List paths = null; + if (uploadAppModel != null) { + paths = uploadAppModel.getApplicationPaths(); + } + boolean allSuccess = true; + if (mcServerSettingsModel == null) { + out.println("Failed to upload app to Digital Lab server. Cause: Digital Lab URL was not configured."); + return false; + } else { + mcServerUrl = mcServerSettingsModel.getProperties().getProperty("MobileHostAddress"); + Map headers = job.login(mcServerUrl, uploadAppModel.getAuthModel(), uploadAppModel.getProxySettings()); + if (headers == null || headers.size() == 0) { + if (uploadAppModel.isUseProxy()) { + out.println(String.format("Failed to upload app, Cause Digital Lab connection info is incorrect. url:%s, Proxy url:%s", + mcServerUrl, uploadAppModel.getProxySettings().getFsProxyAddress())); + } else if (uploadAppModel.isUseAuthentication()) { + out.println(String.format("Failed to upload app, Cause Digital Lab connection info is incorrect. url:%s, Proxy url:%s, proxy userName:%s", + mcServerUrl, uploadAppModel.getProxySettings().getFsProxyAddress(), uploadAppModel.getProxySettings().getFsProxyUserName())); + } else { + out.println(String.format("Failed to upload app, Cause Digital Lab connection info is incorrect. url:%s", mcServerUrl)); + } + build.setResult(Result.FAILURE); + return false; + } + + if(paths == null || paths.size() == 0) { + return true; + } + + out.println(String.format("There are %d apps to be uploaded.", paths.size())); + String workspace = build.getWorkspace() == null ? "" : build.getWorkspace().toURI().getPath(); + + for (int i = 1; i <= paths.size(); i++) { + String appUploadWorkspace = paths.get(i - 1).getMcAppWorkspace(); + String path = paths.get(i - 1).getMcAppPath(); + String originPath = path; + if (StringUtils.isNullOrEmpty(path)) { + out.println(String.format("ignore the empty app %d upload", i)); + continue; + } + //case insensitive replace of workspace to its real path + if (path.toUpperCase(Locale.ENGLISH).startsWith("${WORKSPACE}")) { + path = path.replaceAll("(?i)" + Pattern.quote("${WORKSPACE}"), Matcher.quoteReplacement(workspace)); + if (!FilenameUtils.normalize(path).startsWith(FilenameUtils.normalize(workspace))) { + out.println(String.format("Failed to upload app, Cause invalid application file: %s", path)); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + } + } + FilePath filePath = new FilePath(build.getWorkspace().getChannel(), path); + File tempFile = null; + if (filePath.isRemote()) { + tempFile = File.createTempFile("uftm", "." + FilenameUtils.getExtension(path)); + try (OutputStream outputStream = new FileOutputStream(tempFile)) { + filePath.copyTo(outputStream); + path = tempFile.getCanonicalPath(); + } catch (NoSuchFileException noSuchFileException) { + out.println(String.format("Failed to upload app, Cause cannot find application file: %s", path)); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + } catch (Exception e) { + out.println(String.format("Failed to upload app, Cause failed to copy application file: %s", path)); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + } + } + //check workspace exist or not in MC server + String appUploadWorkspaceName = ""; + if(!StringUtils.isNullOrEmpty(appUploadWorkspace)){ + JSONObject result = job.isWorkspaceExist(headers, mcServerUrl, uploadAppModel.getProxySettings(), appUploadWorkspace); + if(result == null || (result != null && (!result.containsKey("uuid") || !result.getAsString("uuid").equals(appUploadWorkspace)))){ + out.println(String.format("Failed to upload app %d %s, Cause cannot find target workspace id: %s", i, originPath, appUploadWorkspace)); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + }else{ + appUploadWorkspaceName = result.getAsString("name"); + } + }else{ + appUploadWorkspaceName = Constants.SHARED_ASSETS; + } + //upload app + try { + out.println(String.format("starting to upload app %d %s to workspace %s", i, originPath, appUploadWorkspaceName)); + app = job.upload(headers, mcServerUrl, uploadAppModel.getProxySettings(), path, appUploadWorkspace); + if (app == null) { + out.println("Failed to upload app."); + build.setResult(Result.FAILURE); + return false; + } + if ((Boolean) app.get("error")) { + out.println("Job failed because got error message during the application uploading. " + app.toJSONString()); + allSuccess = false; + build.setResult(Result.FAILURE); + } + out.println("uploaded app info: " + app.toJSONString()); + } catch (FileNotFoundException fnf) { + out.println(String.format("Failed to upload app to Digital Lab server. Cause: File: %s is not found.", path)); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + } catch (IOException ioe) { + Util.displayIOException(ioe, listener); + build.setResult(Result.FAILURE); + allSuccess = false; + continue; + } catch (Exception e) { + out.println("Failed to upload app."); + build.setResult(Result.FAILURE); + return false; + } finally { + if (tempFile != null) { + Files.delete(tempFile.toPath()); + } + } + } + } + return allSuccess; + } + + public MCServerSettingsModel getMCServerSettingsModel() { + for (MCServerSettingsModel mcServer : getDescriptor().getMcServers()) { + if (this.uploadAppModel != null + && uploadAppModel.getMcServerName().equals(mcServer.getMcServerName())) { + return mcServer; + } + } + return null; + } + + public UploadAppModel getUploadAppModel() { + return uploadAppModel; + } + + // This indicates to Jenkins that this is an implementation of an extension point + @Extension + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + + load(); + } + + @Override + public boolean isApplicable( + @SuppressWarnings("rawtypes") Class jobType) { + + return true; + } + + @Override + public String getDisplayName() { + + return "Upload app to Digital Lab (formerly UFT Mobile) Server"; + } + + public boolean hasMCServers() { + return MCServerSettingsGlobalConfiguration.getInstance().hasMCServers(); + } + + public MCServerSettingsModel[] getMcServers() { + return MCServerSettingsGlobalConfiguration.getInstance().getInstallations(); + } + + /** + * Gets mc workspace list. + * + * @param mcUrl the server name + * @return the mc workspace list + */ + @SuppressWarnings("squid:S2259") + @JavaScriptMethod + public JSONArray getMcWorkspaces(String mcUrl, String authType, String mcUserName, String mcPassword, String mcTenantId, String mcExecToken, + boolean useProxy, String proxyAddress, boolean useAuthentication, String proxyUserName, String proxyPassword) { + JSONArray workspaces = null; + for (MCServerSettingsModel mcServer : this.getMcServers()) { + if (!StringUtils.isNullOrEmpty(mcUrl) + && mcUrl.equals(mcServer.getMcServerName())) { + mcUrl = mcServer.getMcServerUrl(); + } + } + AuthModel authModel = new AuthModel(mcUserName, mcPassword, mcTenantId, mcExecToken, authType); + ProxySettings proxySettings =new ProxySettings(useAuthentication, proxyAddress, proxyUserName, proxyPassword); + try { + JobConfigurationProxy job = JobConfigurationProxy.getInstance(); + workspaces = job.getAllMcWorkspaces(mcUrl, authModel, proxySettings); + } catch (Exception e) { + e.printStackTrace(); + } + return changeResult(workspaces); + } + + private JSONArray changeResult(JSONArray workspaces){ + JSONArray result = new JSONArray(); + if (workspaces != null) { + for (int i = 0; i < workspaces.size(); i++) { + JSONObject workspace = (JSONObject) workspaces.get(i); + if(workspace.getAsString("name").equals(Constants.SHARED_ASSETS)){ + result.add(workspace); + } + } + for (int i = 0; i < workspaces.size(); i++) { + JSONObject workspace = (JSONObject) workspaces.get(i); + if(!workspace.getAsString("name").equals(Constants.SHARED_ASSETS)){ + result.add(workspace); + } + } + } + return result; + } + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration.java new file mode 100644 index 0000000000..2485170dd1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration.java @@ -0,0 +1,217 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.model.CredentialsModel; +import com.microfocus.application.automation.tools.model.SSOCredentialsModel; +import hudson.CopyOnWrite; +import hudson.Extension; +import hudson.ProxyConfiguration; +import hudson.XmlFile; +import hudson.util.FormValidation; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import java.io.IOException; +import java.io.Serializable; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +@Extension(ordinal = 1) +public class AlmServerSettingsGlobalConfiguration extends GlobalConfiguration implements Serializable { + + public AlmServerSettingsGlobalConfiguration(){ + load(); + } + + public static AlmServerSettingsGlobalConfiguration getInstance() { + return GlobalConfiguration.all().get(AlmServerSettingsGlobalConfiguration.class); + } + + @Override + protected XmlFile getConfigFile() { + XmlFile xmlFile = super.getConfigFile(); + ConfigurationMigrationUtil.migrateConfigurationFileIfRequired(xmlFile, + "com.microfocus.application.automation.tools.settings.AlmServerSettingsBuilder.xml", + "AlmServerSettingsBuilder_-DescriptorImpl", + "AlmServerSettingsGlobalConfiguration"); + + return xmlFile; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + List models = new ArrayList<>(); + JSONArray jsonArray = new JSONArray(); + + Object data = formData.get("inst"); + if (data instanceof JSONObject) { + jsonArray.add(data); + } else if (data instanceof JSONArray) { + jsonArray.addAll((JSONArray) data); + } + + for (Object jsonObject : jsonArray) { + JSONObject json = (JSONObject) jsonObject; + Object credentialsObj = json.get("credentials"); + List credentials = new ArrayList<>(); + if (credentialsObj instanceof JSONArray) { + JSONArray credentialsObjArray = (JSONArray) credentialsObj; + credentials = req.bindJSONToList(CredentialsModel.class, credentialsObjArray); + } else if (credentialsObj instanceof JSONObject) { + CredentialsModel credentialsModel = req.bindJSON(CredentialsModel.class, (JSONObject) credentialsObj); + credentials.add(credentialsModel); + } + + Object ssoCredentialsObj = json.get("ssoCredentials"); + List ssoCredentials = new ArrayList<>(); + if (ssoCredentialsObj instanceof JSONArray) { + JSONArray ssoCredentialsObjArray = (JSONArray) ssoCredentialsObj; + ssoCredentials = req.bindJSONToList(SSOCredentialsModel.class, ssoCredentialsObjArray); + } else if (ssoCredentialsObj instanceof JSONObject) { + SSOCredentialsModel ssoCredentialsModel = req.bindJSON(SSOCredentialsModel.class, (JSONObject) ssoCredentialsObj); + ssoCredentials.add(ssoCredentialsModel); + } + + AlmServerSettingsModel newModel = req.bindJSON(AlmServerSettingsModel.class, json); + newModel.set_almCredentials(credentials); + newModel.set_almSSOCredentials(ssoCredentials); + if (!StringUtils.isEmpty(newModel.getAlmServerName()) && !(StringUtils.isEmpty(newModel.getAlmServerUrl()))) { + models.add(newModel); + } + } + + setInstallations(models.toArray(new AlmServerSettingsModel[0])); + + save(); + + return super.configure(req, formData); + } + + @RequirePOST + public FormValidation doCheckAlmServerUrl(@QueryParameter String value) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + return checkQcServerURL(value, false); + } + + @CopyOnWrite + private AlmServerSettingsModel[] installations = new AlmServerSettingsModel[0]; + + public AlmServerSettingsModel[] getInstallations() { + return installations; + } + + public void setInstallations(AlmServerSettingsModel... installations) { + this.installations = installations; + } + + public FormValidation doCheckAlmServerName(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("ALM server name cannot be empty"); + } + + return FormValidation.ok(); + } + + private FormValidation checkQcServerURL(String value, Boolean acceptEmpty) { + String url; + // Path to the page to check if the server is alive + String page = "servlet/tdservlet/TDAPI_GeneralWebTreatment"; + + // Do will allow empty value? + if (StringUtils.isBlank(value)) { + if (!acceptEmpty) { + return FormValidation.error("ALM server must be defined"); + } else { + return FormValidation.ok(); + } + } + + // Does the URL ends with a "/" ? if not, add it + if (value.lastIndexOf('/') == value.length() - 1) { + url = value + page; + } else { + url = value + "/" + page; + } + + // Open the connection and perform a HEAD request + HttpURLConnection connection; + try { + connection = (HttpURLConnection) ProxyConfiguration.open(new URL(url)); + connection.setRequestMethod("GET"); + + // Check the response code + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + return FormValidation.error(connection.getResponseMessage()); + } + } catch (MalformedURLException ex) { + // This is not a valid URL + return FormValidation.error("ALM server URL is malformed."); + } catch (IOException ex) { + // Cant open connection to the server + return FormValidation.error("Error opening a connection to the ALM server"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmUsername(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Username must be set"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckAlmClientID(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Client ID must be set"); + } + + return FormValidation.ok(); + } + + public Boolean hasAlmServers() { + return installations.length > 0; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/ConfigurationMigrationUtil.java b/src/main/java/com/microfocus/application/automation/tools/settings/ConfigurationMigrationUtil.java new file mode 100644 index 0000000000..62c3c88e0a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/ConfigurationMigrationUtil.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.XmlFile; +import jenkins.model.Jenkins; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class ConfigurationMigrationUtil { + + private static final Logger logger = SDKBasedLoggerProvider.getLogger(ConfigurationMigrationUtil.class); + + private ConfigurationMigrationUtil(){ + //codacy : Add a private constructor to hide the implicit public one. + } + + public static void migrateConfigurationFileIfRequired(XmlFile xmlFile, String oldFileName, String oldRootElementName, String newRootElementName) { + if (!xmlFile.exists()) { + //try to get from old path + File oldXmlFile = new File(Jenkins.get().getRootDir(), oldFileName); + if (oldXmlFile.exists()) { + try { + String configuration = FileUtils.readFileToString(oldXmlFile, StandardCharsets.UTF_8.name()); + String newConfiguration = StringUtils.replace(configuration, + oldRootElementName, + newRootElementName); + FileUtils.writeStringToFile(xmlFile.getFile(), newConfiguration, StandardCharsets.UTF_8.name()); + } catch (IOException e) { + logger.error("failed to migrate configuration to new 6.6 format " + newRootElementName + " : " + e.getMessage()); + } + } + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration.java new file mode 100644 index 0000000000..36f447d463 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.microfocus.application.automation.tools.model.MCServerSettingsModel; +import hudson.CopyOnWrite; +import hudson.Extension; +import hudson.XmlFile; +import hudson.util.FormValidation; +import jenkins.model.GlobalConfiguration; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; + +import java.io.Serializable; + +/** + * @author jingwei + */ +@Extension(ordinal = 1) +public class MCServerSettingsGlobalConfiguration extends GlobalConfiguration implements Serializable { + + public MCServerSettingsGlobalConfiguration(){ + load(); + } + + public static MCServerSettingsGlobalConfiguration getInstance() { + return GlobalConfiguration.all().get(MCServerSettingsGlobalConfiguration.class); + } + + @Override + protected XmlFile getConfigFile() { + XmlFile xmlFile = super.getConfigFile(); + ConfigurationMigrationUtil.migrateConfigurationFileIfRequired(xmlFile, + "com.microfocus.application.automation.tools.settings.MCServerSettingsBuilder.xml", + "MCServerSettingsBuilder_-MCDescriptorImpl", + "MCServerSettingsGlobalConfiguration"); + + return xmlFile; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + setInstallations(req.bindParametersToList(MCServerSettingsModel.class, "mc.").toArray( + new MCServerSettingsModel[0])); + + save(); + + return super.configure(req, formData); + } + + public FormValidation doCheckMCServerName(@QueryParameter String value) { + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Digital Lab server name cannot be empty"); + } + + return ret; + } + + public FormValidation doCheckMCServerURL(@QueryParameter String value) { + FormValidation ret = FormValidation.ok(); + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Digital Lab server cannot be empty"); + } + + return ret; + } + + @CopyOnWrite + private MCServerSettingsModel[] installations = new MCServerSettingsModel[0]; + + public MCServerSettingsModel[] getInstallations() { + return installations; + } + + public void setInstallations(MCServerSettingsModel... installations) { + this.installations = installations; + } + + public Boolean hasMCServers() { + return installations.length > 0; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration.java new file mode 100644 index 0000000000..ead6e1da62 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration.java @@ -0,0 +1,520 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.hp.octane.integrations.OctaneConfiguration; +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.entities.Entity; +import com.hp.octane.integrations.exceptions.OctaneConnectivityException; +import com.hp.octane.integrations.services.configurationparameters.FortifySSCTokenParameter; +import com.hp.octane.integrations.services.configurationparameters.factory.ConfigurationParameterFactory; +import com.hp.octane.integrations.utils.OctaneUrlParser; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.CIJenkinsServicesImpl; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationListener; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationValidator; +import com.microfocus.application.automation.tools.octane.configuration.SDKBasedLoggerProvider; +import hudson.CopyOnWrite; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.XmlFile; +import hudson.util.FormValidation; +import hudson.util.Secret; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +/** + * Octane configuration settings + */ +@Extension(ordinal = 1) +public class OctaneServerSettingsGlobalConfiguration extends GlobalConfiguration implements Serializable { + private static final Logger logger = SDKBasedLoggerProvider.getLogger(OctaneServerSettingsGlobalConfiguration.class); + + public static OctaneServerSettingsGlobalConfiguration getInstance() { + return GlobalConfiguration.all().get(OctaneServerSettingsGlobalConfiguration.class); + } + + @CopyOnWrite + private volatile OctaneServerSettingsModel[] servers; + + private transient Map octaneConfigurations = new HashMap<>(); + + @Override + protected XmlFile getConfigFile() { + XmlFile xmlFile = super.getConfigFile(); + ConfigurationMigrationUtil.migrateConfigurationFileIfRequired(xmlFile, + "com.microfocus.application.automation.tools.settings.OctaneServerSettingsBuilder.xml", + "OctaneServerSettingsBuilder_-OctaneDescriptorImpl", + "OctaneServerSettingsGlobalConfiguration"); + + return xmlFile; + } + + public OctaneServerSettingsGlobalConfiguration() { + load(); + convertFortifyParameters(); + + if (servers == null) { + servers = new OctaneServerSettingsModel[0]; + } + + boolean shouldSave = false; + // defense for non-octane users.Previously, before multi-configuration, octane had only one configuration, + // even empty. So after moving to multi-configuration, non-octane users have non-valid configuration and + // will fail to save jenkins configuration as missing valid octane configuration + if (servers.length == 1 && StringUtils.isEmpty(servers[0].getUiLocation())) { + servers = new OctaneServerSettingsModel[0]; + shouldSave = true; + } + + // upgrade flow to add internal ID to configuration + for (OctaneServerSettingsModel server : servers) { + if (server.getInternalId() == null || server.getInternalId().isEmpty()) { + server.setInternalId(UUID.randomUUID().toString()); + shouldSave = true; + } + } + if (shouldSave) { + save(); + } + } + + private void convertFortifyParameters() { + boolean updated = false; + if (servers != null) { + for (OctaneServerSettingsModel model : servers) { + if (convertFortifyParameters(model)) { + updated = true; + } + } + if (updated) { + save(); + } + } + } + + private boolean convertFortifyParameters(OctaneServerSettingsModel model) { + if (!model.isFortifyParamsConverted()) { + if (model.getSscBaseToken() != null && !model.getSscBaseToken().trim().isEmpty()) { + String params = StringUtils.isEmpty(model.getParameters()) ? "" : model.getParameters().trim() + System.lineSeparator(); + + params += FortifySSCTokenParameter.KEY + ":" + model.getSscBaseToken().trim(); + model.setParameters(params); + } + model.setFortifyParamsConverted(true); + return true; + } + return false; + } + + public void initOctaneClients() { + if (servers.length > 0) { + ExecutorService executor = Executors.newFixedThreadPool(Math.min(10, servers.length)); + for (OctaneServerSettingsModel innerServerConfiguration : servers) { + OctaneConfiguration octaneConfiguration = OctaneConfiguration.createWithUiLocation(innerServerConfiguration.getIdentity(), innerServerConfiguration.getUiLocation()); + octaneConfiguration.setClient(innerServerConfiguration.getUsername()); + octaneConfiguration.setSecret(innerServerConfiguration.getPassword().getPlainText()); + octaneConfiguration.setSuspended(innerServerConfiguration.isSuspend()); + octaneConfiguration.setImpersonatedUser(innerServerConfiguration.getImpersonatedUser()); + octaneConfiguration.clearParameters(); + innerServerConfiguration.getParametersAsMap().entrySet().forEach(entry -> { + ConfigurationParameterFactory.addParameter(octaneConfiguration, entry.getKey(), entry.getValue()); + }); + + octaneConfigurations.put(innerServerConfiguration.getInternalId(), octaneConfiguration); + executor.execute(() -> { + OctaneSDK.addClient(octaneConfiguration, CIJenkinsServicesImpl.class); + }); + } + } + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + Object data = formData.get("mqm"); + JSONArray jsonArray = new JSONArray(); + if (data instanceof JSONObject) { + jsonArray.add(data); + } else if (data instanceof JSONArray) { + jsonArray.addAll((JSONArray) data); + } + + handleDeletedConfigurations(jsonArray); + for (Object jsonObject : jsonArray) { + JSONObject json = (JSONObject) jsonObject; + OctaneServerSettingsModel newModel = req.bindJSON(OctaneServerSettingsModel.class, json); + OctaneServerSettingsModel oldModel; + + String internalId = json.getString("internalId"); + validateConfiguration(doCheckUiLocation(json.getString("uiLocation"), internalId), "Location"); + oldModel = getSettingsByInternalId(internalId); + if (oldModel != null) { + validateConfiguration(doCheckInstanceId(newModel.getIdentity()), "Plugin instance id"); + newModel.setInternalId(internalId); + } + + setModel(newModel); + } + + return super.configure(req, formData); + } + + private void handleDeletedConfigurations(JSONArray jsonArray) { + if (servers == null) { + return; + } + + Set foundInternalId = jsonArray.stream().map(jsonObj -> ((JSONObject) jsonObj).getString("internalId")).filter(s -> !s.isEmpty()).collect(Collectors.toSet()); + Set serversToRemove = Arrays.stream(servers).filter(server -> !foundInternalId.contains(server.getInternalId())).collect(Collectors.toSet()); + + if (!serversToRemove.isEmpty()) { + List serversToLeave = new ArrayList<>(Arrays.asList(servers)); + for (OctaneServerSettingsModel serverToRemove : serversToRemove) { + logger.info("Removing client with instance Id: " + serverToRemove.getIdentity()); + serversToLeave.remove(serverToRemove); + octaneConfigurations.remove(serverToRemove.getInternalId()); + + + try { + OctaneSDK.removeClient(OctaneSDK.getClientByInstanceId(serverToRemove.getIdentity())); + } catch (IllegalArgumentException | IllegalStateException e) { + //failed to remove from SDK + //just remove from jenkins + logger.warn("Failed to remove client with instance Id: " + serverToRemove.getIdentity() + " from SDK : " + e.getMessage()); + } + } + + servers = serversToLeave.toArray(new OctaneServerSettingsModel[0]); + save(); + } + } + + public void setModel(OctaneServerSettingsModel newModel) { + //infer uiLocation + + try { + OctaneUrlParser octaneUrlParser = ConfigurationValidator.parseUiLocation(newModel.getUiLocation()); + newModel.setSharedSpace(octaneUrlParser.getSharedSpace()); + newModel.setLocation(octaneUrlParser.getLocation()); + } catch (FormValidation fv) { + logger.warn("tested configuration failed on Octane URL parse: " + fv.getMessage(), fv); + } + + OctaneServerSettingsModel oldModel = getSettingsByInternalId(newModel.getInternalId()); + // set identity in new model + if (oldModel == null) { + if (newModel.getIdentity() == null || newModel.getIdentity().isEmpty()) { + newModel.setIdentity(UUID.randomUUID().toString()); + } + if (newModel.getIdentityFrom() == null) { + newModel.setIdentityFrom(System.currentTimeMillis()); + } + } else if (oldModel.getIdentity() != null && !oldModel.getIdentity().isEmpty()) { + newModel.setIdentityFrom(oldModel.getIdentityFrom()); + } + + OctaneServerSettingsModel[] serversBackup = servers; + if (oldModel == null) { + if (servers == null) { + servers = new OctaneServerSettingsModel[]{newModel}; + } else { + if (servers.length == 1 && !servers[0].isValid()) { + // replacing the first dummy one + servers[0] = newModel; + } else { + // adding new one + OctaneServerSettingsModel[] newServers = new OctaneServerSettingsModel[servers.length + 1]; + System.arraycopy(servers, 0, newServers, 0, servers.length); + newServers[servers.length] = newModel; + servers = newServers; + } + } + } else { + removeClientIfIdentityChanged(servers, newModel, oldModel); + } + OctaneConfiguration octaneConfiguration = octaneConfigurations.containsKey(newModel.getInternalId()) ? + octaneConfigurations.get(newModel.getInternalId()) : + OctaneConfiguration.create(newModel.getIdentity(), newModel.getLocation(), newModel.getSharedSpace()); + octaneConfiguration.setUrlAndSpace(newModel.getLocation(), newModel.getSharedSpace()); + octaneConfiguration.setClient(newModel.getUsername()); + octaneConfiguration.setSecret(newModel.getPassword().getPlainText()); + octaneConfiguration.setImpersonatedUser(newModel.getImpersonatedUser()); + octaneConfiguration.setSuspended(newModel.isSuspend()); + + octaneConfiguration.clearParameters(); + newModel.getParametersAsMap().entrySet().forEach(entry -> { + ConfigurationParameterFactory.addParameter(octaneConfiguration, entry.getKey(), entry.getValue()); + }); + + + if (!octaneConfigurations.containsValue(octaneConfiguration)) { + octaneConfigurations.put(newModel.getInternalId(), octaneConfiguration); + try { + OctaneSDK.addClient(octaneConfiguration, CIJenkinsServicesImpl.class); + } catch (Exception e) { + servers = serversBackup; + throw e; + } + } + + if (!newModel.equals(oldModel)) { + fireOnChanged(newModel, oldModel); + } + + save(); + } + + private void removeClientIfIdentityChanged(OctaneServerSettingsModel[] servers, OctaneServerSettingsModel newModel, OctaneServerSettingsModel oldModel) { + if (servers != null) { + for (int i = 0; i < servers.length; i++) { + if (newModel.getInternalId().equals(servers[i].getInternalId())) { + servers[i] = newModel; + if (!newModel.getIdentity().equals(oldModel.getIdentity())) { + logger.info("Removing client with instance Id: " + oldModel.getIdentity()); + OctaneSDK.removeClient(OctaneSDK.getClientByInstanceId(octaneConfigurations.get(oldModel.getInternalId()).getInstanceId())); + octaneConfigurations.remove(newModel.getInternalId()); + } + break; + } + } + } + } + + private void fireOnChanged(OctaneServerSettingsModel newConf, OctaneServerSettingsModel oldConf) { + //resetJobListCache + try { + OctaneSDK.getClientByInstanceId(newConf.getIdentity()).getTasksProcessor().resetJobListCache(); + } catch (Exception e) { + logger.info("Failed to resetJobListCache for client with instance Id: " + newConf.getIdentity() + ", " + e.getMessage()); + } + + //resetOctaneRootsCache + try { + OctaneSDK.getClientByInstanceId(newConf.getIdentity()).getConfigurationService().resetOctaneRootsCache(); + } catch (Exception e) { + logger.info("Failed to resetOctaneRootsCache for client with instance Id: " + newConf.getIdentity() + ", " + e.getMessage()); + } + + //update listeners + ExtensionList listeners = ExtensionList.lookup(ConfigurationListener.class); + for (ConfigurationListener listener : listeners) { + try { + listener.onChanged(newConf, oldConf); + } catch (ThreadDeath t) { + throw t; + } catch (Exception t) { + logger.warn(t); + } + } + } + + @RequirePOST + @SuppressWarnings("unused") + public FormValidation doTestConnection(StaplerRequest req, + @QueryParameter("uiLocation") String uiLocation, + @QueryParameter("username") String username, + @QueryParameter("password") String password, + @QueryParameter("impersonatedUser") String impersonatedUser, + @QueryParameter("suspend") Boolean isSuspend, + @QueryParameter("workspace2ImpersonatedUserConf") String workspace2ImpersonatedUserConf, + @QueryParameter("parameters") String parameters + ) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + String myImpersonatedUser = StringUtils.trim(impersonatedUser); + String myUsername = StringUtils.trim(username); + OctaneUrlParser octaneUrlParser; + try { + octaneUrlParser = ConfigurationValidator.parseUiLocation(StringUtils.trim(uiLocation)); + } catch (FormValidation fv) { + logger.warn("tested configuration failed on Octane URL parse: " + fv.getMessage(), fv); + return fv; + } + logger.info("test configuration to : " + octaneUrlParser.getLocation() + "?p=" + octaneUrlParser.getSharedSpace()); + + + // if parse is good, check authentication/authorization + List fails = new ArrayList<>(); + ConfigurationValidator.checkImpersonatedUser(fails, myImpersonatedUser); + ConfigurationValidator.checkHoProxySettins(fails); + List availableWorkspaces = ConfigurationValidator.checkConfiguration(fails, octaneUrlParser.getLocation(), octaneUrlParser.getSharedSpace(), myUsername, Secret.fromString(password)); + + Map workspace2ImpersonatedUser = ConfigurationValidator.checkWorkspace2ImpersonatedUserConf(workspace2ImpersonatedUserConf, availableWorkspaces, myImpersonatedUser, fails); + ConfigurationValidator.checkParameters(parameters, myImpersonatedUser, workspace2ImpersonatedUser, fails); + + String suspendMessage = "Note that current configuration is disabled (see in Advanced section)"; + if (fails.isEmpty()) { + String msg = Messages.ConnectionSuccess(); + + + if (availableWorkspaces != null && !availableWorkspaces.isEmpty()) { + int workspaceNumberLimit = 30; + String titleNewLine = " "; + String suffix = (availableWorkspaces.size() > workspaceNumberLimit) ? titleNewLine + "and more " + (availableWorkspaces.size() - workspaceNumberLimit) + " workspaces" : ""; + String tooltip = availableWorkspaces.stream() + .sorted(Comparator.comparingInt(e -> Integer.parseInt(e.getId()))) + .limit(workspaceNumberLimit) + .map(w -> w.getId() + " - " + w.getName() + getUserForWorkspace(w, workspace2ImpersonatedUser)) + .collect(Collectors.joining(titleNewLine, "Available workspaces are : " + titleNewLine, suffix)); + String icon = String.format("", tooltip); + msg = msg + icon; + } + + if (isSuspend != null && isSuspend) { + + msg += "
" + suspendMessage; + } + return ConfigurationValidator.wrapWithFormValidation(true, msg); + } else { + if (isSuspend != null && isSuspend && !fails.contains(OctaneConnectivityException.UNSUPPORTED_SDK_VERSION_MESSAGE)) { + fails.add(suspendMessage); + } + String errorMsg = "Validation failed :
  • " + + fails.stream().map(s -> StringEscapeUtils.escapeHtml(s)).collect(Collectors.joining("
  • ")) + + "
"; + return ConfigurationValidator.wrapWithFormValidation(false, errorMsg); + } + } + + private String getUserForWorkspace(Entity workspace, Map workspace2ImpersonatedUser) { + if (workspace2ImpersonatedUser == null || workspace2ImpersonatedUser.isEmpty()) { + return ""; + } + Long workspaceId = Long.parseLong(workspace.getId()); + if (workspace2ImpersonatedUser.containsKey(workspaceId)) { + return " (" + workspace2ImpersonatedUser.get(workspaceId) + ")"; + } else { + return ""; + } + } + + public OctaneServerSettingsModel[] getServers() { + return servers; + } + + public void setServers(OctaneServerSettingsModel... servers) { + this.servers = servers; + save(); + } + + public OctaneServerSettingsModel getSettings(String instanceId) { + if (instanceId == null || instanceId.isEmpty()) { + throw new IllegalArgumentException("instance ID MUST NOT be null nor empty"); + } + + OctaneServerSettingsModel result = null; + if (servers != null) { + for (OctaneServerSettingsModel setting : servers) { + if (instanceId.equals(setting.getIdentity())) { + result = setting; + break; + } + } + } + return result; + } + + public OctaneServerSettingsModel getSettingsByInternalId(String internalId) { + if (internalId == null || internalId.isEmpty()) { + return null; + } + + OctaneServerSettingsModel result = null; + if (servers != null) { + for (OctaneServerSettingsModel setting : servers) { + if (internalId.equals(setting.getInternalId())) { + result = setting; + break; + } + } + } + return result; + } + + + public FormValidation doCheckInstanceId(@QueryParameter String value) { + if (value == null || value.isEmpty()) { + return FormValidation.error("Plugin Instance Id cannot be empty"); + } + + return FormValidation.ok(); + } + + public FormValidation doCheckUiLocation(@QueryParameter String value, @QueryParameter(value = "internalId") String internalId) { + FormValidation ret = FormValidation.ok(); + //Relevant only for new server configuration (empty internalId) + if (!StringUtils.isBlank(internalId)) { + return ret; + } + if (StringUtils.isBlank(value)) { + ret = FormValidation.error("Location must be set"); + return ret; + } + OctaneUrlParser octaneUrlParser = null; + + try { + octaneUrlParser = ConfigurationValidator.parseUiLocation(value); + + } catch (Exception e) { + ret = FormValidation.error("Failed to parse location."); + } + for (OctaneServerSettingsModel serverSettingsModel : servers) { + if (octaneUrlParser != null && serverSettingsModel.getSharedSpace().equals(octaneUrlParser.getSharedSpace()) && + serverSettingsModel.getLocation().equals(octaneUrlParser.getLocation())) { + ret = FormValidation.error("This ALM Octane server configuration was already set."); + return ret; + } + } + return ret; + } + + private void validateConfiguration(FormValidation result, String formField) throws FormException { + if (!result.equals(FormValidation.ok())) { + throw new FormException("Validation of property '" + formField + "' in ALM Octane server Configuration failed: " + result.getMessage(), formField); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper.java b/src/main/java/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper.java new file mode 100644 index 0000000000..8453f39716 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper.java @@ -0,0 +1,93 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.microfocus.application.automation.tools.octane.events.OutputEnvironmentParametersHelper; +import hudson.EnvVars; +import hudson.Extension; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.BuildListener; +import hudson.tasks.BuildWrapper; +import hudson.tasks.BuildWrapperDescriptor; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; + +public class OutputEnvironmentVariablesBuildWrapper extends BuildWrapper implements Serializable { + + private String outputEnvironmentParameters; + @DataBoundConstructor + public OutputEnvironmentVariablesBuildWrapper(String outputEnvironmentParameters) { + setOutputEnvironmentParameters(outputEnvironmentParameters); + } + + public String getOutputEnvironmentParameters() { + return outputEnvironmentParameters; + } + + @DataBoundSetter + public void setOutputEnvironmentParameters(String outputEnvironmentParameters) { + this.outputEnvironmentParameters = outputEnvironmentParameters; + } + + @Override + public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { + EnvVars envVars = build.getEnvironment(listener); + return new Environment() { + @Override + public void buildEnvVars(Map env) { + env.putAll(envVars); + } + }; + } + + @Extension + public static final class DescriptorImpl extends BuildWrapperDescriptor { + + @Override + public boolean isApplicable(AbstractProject item) { + return true; + } + + @Override + public String getDisplayName() { + return "Define a list of environment variables to store in ValueEdge / ALM Octane"; + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration.java new file mode 100644 index 0000000000..ff0396f4dd --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration.java @@ -0,0 +1,177 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.util.FormValidation; +import jenkins.model.GlobalConfiguration; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import java.io.Serializable; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Extension(ordinal = 1, optional = true) +public class RunnerMiscSettingsGlobalConfiguration extends GlobalConfiguration implements Serializable { + + public static final String DEFAULT_UFT_DATE_PATTERN1 = "dd/MM/yyyy HH:mm:ss"; + // for backward compatibility only, after this it will be forced to use / as date separator + public static final String DEFAULT_UFT_DATE_PATTERN2 = "dd-MM-yyyy HH:mm:ss"; + public static final String DEFAULT_UFT_DATE_PATTERN3 = "dd.MM.yyyy HH:mm:ss"; + public static final List DEFAULT_UFT_DATE_PATTERNS = Arrays.asList(DEFAULT_UFT_DATE_PATTERN1, DEFAULT_UFT_DATE_PATTERN2, DEFAULT_UFT_DATE_PATTERN3); + + public static final String DEFAULT_BRANCHES = "master main trunk mainline"; + public static final String DEFAULT_OUTPUT_ENVIRONMENT_PARAMETERS = "BUILD_DISPLAY_NAME BUILD_TAG BUILD_URL"; + + private String dateFormat; + private String defaultBranches; + private String outputEnvironmentParameters; + private boolean agentToControllerEnabled; + + @DataBoundConstructor + public RunnerMiscSettingsGlobalConfiguration(String mfDateFormat, String defaultBranches, String outputEnvironmentParameters, boolean agentToControllerEnabled) { + setDateFormat(mfDateFormat); + setDefaultBranches(defaultBranches); + setAgentToControllerEnabled(agentToControllerEnabled); + setOutputEnvironmentParameters(outputEnvironmentParameters); + } + + public RunnerMiscSettingsGlobalConfiguration() { + load(); + } + + public static RunnerMiscSettingsGlobalConfiguration getInstance() throws NullPointerException { + RunnerMiscSettingsGlobalConfiguration config = GlobalConfiguration.all().get(RunnerMiscSettingsGlobalConfiguration.class); + + if (config == null) throw new NullPointerException(); + + return config; + } + + @NonNull + @Override + public String getDisplayName() { + return "Miscellaneous OpenText Plugin settings"; + } + + public String getDateFormat() { + return dateFormat; + } + + public String getDefaultBranches() { + return defaultBranches; + } + + public void setDefaultBranches(String defaultBranches) { + String validatedDefaultBranches = getValidatedDefaultBranches(defaultBranches); + if (!StringUtils.isNullOrEmpty(validatedDefaultBranches)) { + this.defaultBranches = validatedDefaultBranches; + } else { + this.defaultBranches = DEFAULT_BRANCHES; + } + + save(); + } + + public String getOutputEnvironmentParameters() { + return outputEnvironmentParameters != null ? outputEnvironmentParameters : DEFAULT_OUTPUT_ENVIRONMENT_PARAMETERS; + } + + public void setOutputEnvironmentParameters(String outputEnvironmentParameters) { + this.outputEnvironmentParameters = outputEnvironmentParameters; + save(); + } + + private String getValidatedDefaultBranches(String defaultBranches) { + String[] branches = defaultBranches.split(" "); + return Stream.of(branches).filter(branch -> !StringUtils.isNullOrEmpty(branch)) + .collect(Collectors.joining(" ")); + } + + public DateTimeFormatter getDateFormatter() { + return dateFormat != null ? DateTimeFormatter.ofPattern(dateFormat) : DateTimeFormatter.ofPattern(DEFAULT_UFT_DATE_PATTERN1); + } + + public void setDateFormat(String dateFormat) { + if (!StringUtils.isNullOrEmpty(dateFormat)) { + try { + DateTimeFormatter.ofPattern(dateFormat); + this.dateFormat = dateFormat; + } catch (IllegalArgumentException ignored) { + this.dateFormat = DEFAULT_UFT_DATE_PATTERN1; + } + } else { + this.dateFormat = DEFAULT_UFT_DATE_PATTERN1; + } + + save(); + } + + public boolean isAgentToControllerEnabled() { + return agentToControllerEnabled; + } + + public void setAgentToControllerEnabled(boolean agentToControllerEnabled) { + this.agentToControllerEnabled = agentToControllerEnabled; + save(); + } + + public FormValidation doCheckDateFormat(@QueryParameter String value) { + if (!StringUtils.isNullOrEmpty(value)) { + try { + DateTimeFormatter.ofPattern(value); + } catch (IllegalArgumentException ignored) { + return FormValidation.error("Invalid timestamp pattern specified."); + } + + return FormValidation.ok(); + } + + return FormValidation.warning("Will fallback to default pattern."); + } + + public FormValidation doCheckDefaultBranches(@QueryParameter String value) { + if (!StringUtils.isNullOrEmpty(value)) { + return FormValidation.ok(); + } + + return FormValidation.warning("Will fallback to default pattern."); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration.java new file mode 100644 index 0000000000..195078cf3a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.ServerInfo; +import com.microfocus.sv.svconfigurator.core.impl.processor.Credentials; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import com.microfocus.sv.svconfigurator.serverclient.impl.CommandExecutorFactory; +import hudson.CopyOnWrite; +import hudson.Extension; +import hudson.XmlFile; +import hudson.util.FormValidation; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import net.sf.json.JSONObject; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +@Extension(ordinal = 1) +public class SvServerSettingsGlobalConfiguration extends GlobalConfiguration implements Serializable { + + public static SvServerSettingsGlobalConfiguration getInstance() { + return GlobalConfiguration.all().get(SvServerSettingsGlobalConfiguration.class); + } + + @Override + protected XmlFile getConfigFile() { + XmlFile xmlFile = super.getConfigFile(); + ConfigurationMigrationUtil.migrateConfigurationFileIfRequired(xmlFile, + "com.microfocus.application.automation.tools.settings.SvServerSettingsBuilder.xml", + "SvServerSettingsBuilder_-DescriptorImpl", + "SvServerSettingsGlobalConfiguration"); + + return xmlFile; + } + + @CopyOnWrite + private SvServerSettingsModel[] servers; + + public SvServerSettingsGlobalConfiguration() { + load(); + } + + private static boolean isHttpsSchema(String url) { + try { + return "https".equals(new URL(url).getProtocol()); + } catch (MalformedURLException e) { + return false; + } + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + List list = req.bindJSONToList(SvServerSettingsModel.class, formData.get("srv")); + + validateMandatoryFields(list); + + servers = list.toArray(new SvServerSettingsModel[list.size()]); + + save(); + + return super.configure(req, formData); + } + + private void validateMandatoryFields(List servers) throws FormException { + for (SvServerSettingsModel server : servers) { + validateConfiguration(doCheckName(server.getName()), "name"); + validateConfiguration(doCheckUrl(server.getUrl()), "url"); + validateConfiguration(doCheckUsername(server.getUsername(), server.getUrl()), "username"); + validateConfiguration(doCheckPassword(server.getPassword(), server.getUrl()), "password"); + } + } + + private void validateConfiguration(FormValidation result, String formField) throws FormException { + if (!result.equals(FormValidation.ok())) { + throw new FormException("Validation of property in Service Virtualization server configuration failed: " + result.getMessage(), formField); + } + } + + public FormValidation doCheckUrl(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Management Endpoint URL cannot be empty"); + } + try { + new URL(value); + } catch (MalformedURLException e) { + return FormValidation.error("'" + value + "' is not valid URL"); + } + return FormValidation.ok(); + } + + public FormValidation doCheckUsername(@QueryParameter String value, @QueryParameter("url") final String url) { + if (isHttpsSchema(url) && StringUtils.isBlank(value)) { + return FormValidation.error("Username is required for secured server"); + } + return FormValidation.ok(); + } + + public FormValidation doCheckPassword(@QueryParameter String value, @QueryParameter("url") final String url) { + if (isHttpsSchema(url) && StringUtils.isBlank(value)) { + return FormValidation.error("Password is required for secured server"); + } + return FormValidation.ok(); + } + + @RequirePOST + @SuppressWarnings("unused") + public FormValidation doTestConnection(@QueryParameter("url") final String url, + @QueryParameter("trustEveryone") final boolean trustEveryone, + @QueryParameter("username") final String username, + @QueryParameter("password") final String password) { + try { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + Credentials credentials = (!StringUtils.isBlank(username)) ? new Credentials(username, password) : null; + ICommandExecutor commandExecutor = new CommandExecutorFactory().createCommandExecutor(new URL(url), trustEveryone, credentials); + ServerInfo serverInfo = commandExecutor.getClient().getServerInfo(); + return FormValidation.ok("Validation passed. Connected to %s server of version: %s", serverInfo.getServerType(), serverInfo.getProductVersion()); + } catch (Exception e) { + return FormValidation.error("Validation failed: " + e.getMessage()); + } + } + + public SvServerSettingsModel[] getServers() { + return servers; + } + + public void setServers(SvServerSettingsModel[] servers) { + this.servers = servers; + } + + public FormValidation doCheckName(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error("Name cannot be empty"); + } + + return FormValidation.ok(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration.java b/src/main/java/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration.java new file mode 100644 index 0000000000..80215e5ee1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration.java @@ -0,0 +1,90 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.settings; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.util.Secret; +import io.jenkins.cli.shaded.org.apache.commons.lang.RandomStringUtils; +import jenkins.model.GlobalConfiguration; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.Serializable; +import java.security.SecureRandom; + +@Extension +public class UFTEncryptionGlobalConfiguration extends GlobalConfiguration implements Serializable { + // won't be displayed anywhere, a bit of a hack, but should be secure + + // seems important, if further changes needed after release + private static final long serialVersionUID = 1L; + + private static Secret generateKey() { + return Secret.fromString(RandomStringUtils.random(32, 0, 0, true, true, null, new SecureRandom())); + } + + public static UFTEncryptionGlobalConfiguration getInstance() throws NullPointerException { + UFTEncryptionGlobalConfiguration config = GlobalConfiguration.all().get(UFTEncryptionGlobalConfiguration.class); + + if (config == null) throw new NullPointerException(); + + return config; + } + + private Secret encKey; + + @DataBoundConstructor + public UFTEncryptionGlobalConfiguration() { + load(); + } + + @NonNull + @Override + public String getDisplayName() { + return "UFT Encryption Global Configuration (Should not appear)"; + } + + /** + * Returns in encrypted form the current encryption key, generates one if this master doesn't have one. + * @return encrypted encryption key + */ + public String getEncKey() { + if (encKey == null) { + encKey = generateKey(); + save(); + } + + return encKey.getEncryptedValue(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/ArgsFactory.java b/src/main/java/com/microfocus/application/automation/tools/sse/ArgsFactory.java new file mode 100644 index 0000000000..fc86d804be --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/ArgsFactory.java @@ -0,0 +1,87 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse; + +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.sdk.Args; + +import hudson.Util; +import hudson.util.VariableResolver; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class ArgsFactory { + + public Args create(SseModel model) { + + return new Args( + + model.getAlmServerUrl(), + model.getAlmDomain(), + model.getClientType(), + model.getAlmProject(), + model.getAlmUserName(), + model.getAlmPassword(), + model.getRunType(), + model.getAlmEntityId(), + model.getTimeslotDuration(), + model.getDescription(), + model.getPostRunAction(), + model.getEnvironmentConfigurationId(), + model.getCdaDetails()); + } + + public Args createResolved(SseModel model, VariableResolver buildResolver) { + + return new Args( + + model.getAlmServerUrl(), + Util.replaceMacro(model.getAlmDomain(), buildResolver), + model.getClientType(), + Util.replaceMacro(model.getAlmProject(), buildResolver), + Util.replaceMacro(model.getAlmUserName(), buildResolver), + model.getAlmPassword(), + model.getRunType(), + Util.replaceMacro(model.getAlmEntityId(), buildResolver), + Util.replaceMacro(model.getTimeslotDuration(), buildResolver), + model.getDescription(), + model.getPostRunAction(), + Util.replaceMacro(model.getEnvironmentConfigurationId(), buildResolver), + model.getCdaDetails()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/SSEBuilderPerformer.java b/src/main/java/com/microfocus/application/automation/tools/sse/SSEBuilderPerformer.java new file mode 100644 index 0000000000..409fcf88b3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/SSEBuilderPerformer.java @@ -0,0 +1,76 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse; + +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import com.microfocus.application.automation.tools.sse.sdk.Args; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.RunManager; +import hudson.util.VariableResolver; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class SSEBuilderPerformer { + + private final RunManager _runManager = new RunManager(); + + public Testsuites start( + SseModel model, + Logger logger, + VariableResolver buildVariableResolver) throws InterruptedException { + + Testsuites ret; + + Args args = new ArgsFactory().createResolved(model, buildVariableResolver); + + RestClient restClient; + + restClient = new RestClient(args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + + ret = _runManager.execute(restClient, args, logger); + return ret; + } + + public void stop() { + _runManager.stop(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java new file mode 100644 index 0000000000..0ca987a794 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentBuilderPerformer.java @@ -0,0 +1,168 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.AUTEnvironmentResolvedModel; +import com.microfocus.application.automation.tools.model.AutEnvironmentParameterModel; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.authenticator.AuthenticationTool; +import hudson.EnvVars; +import hudson.util.VariableResolver; + +import java.util.Collection; +import java.util.List; + +/** + * Created by barush on 29/10/2014. + */ +public class AUTEnvironmentBuilderPerformer { + + private Logger logger; + private AUTEnvironmentResolvedModel model; + private RestClient restClient; + private VariableResolver buildVariableResolver; + private String autEnvironmentConfigurationIdToReturn; + + public AUTEnvironmentBuilderPerformer( + AUTEnvironmentResolvedModel model, + VariableResolver buildVariableResolver, + Logger logger) { + + this.model = model; + this.logger = logger; + this.buildVariableResolver = buildVariableResolver; + } + + public void start(EnvVars envVars) { + try { + if (AuthenticationTool.getInstance().authenticate(getClient(), + model.getAlmUserName(), + model.getAlmPassword(), + model.getAlmServerUrl(), + model.getClientType(), + logger)) { + logger.log(String.format( + "Alm server url: %s", model.getAlmServerUrl())); + performAutOperations(envVars); + } + } catch (Throwable cause) { + logger.log(String.format( + "Failed to update ALM AUT Environment. Cause: %s", + cause.getMessage())); + throw cause; + } + } + + public String getAutEnvironmentConfigurationIdToReturn() { + return autEnvironmentConfigurationIdToReturn; + } + + private void performAutOperations(EnvVars envVars) { + String autEnvironmentId = model.getAutEnvironmentId(); + + AUTEnvironmentManager autEnvironmentManager = + new AUTEnvironmentManager(getClient(), logger); + String parametersRootFolderId = + autEnvironmentManager.getParametersRootFolderIdByAutEnvId(autEnvironmentId); + String autEnvironmentConfigurationId = + getAutEnvironmentConfigurationId(autEnvironmentManager, autEnvironmentId); + + assignValuesToAutParameters(autEnvironmentConfigurationId, parametersRootFolderId, envVars); + autEnvironmentConfigurationIdToReturn = autEnvironmentConfigurationId; + + } + + private void assignValuesToAutParameters( + String autEnvironmentConfigurationId, + String parametersRootFolderId, + EnvVars envVars) { + + List autEnvironmentParameters = + model.getAutEnvironmentParameters(); + if (autEnvironmentParameters == null || autEnvironmentParameters.size() == 0) { + logger.log("There's no AUT Environment parameters to assign for this build..."); + return; + } + + String selectedNode = envVars.get("NODE_NAME"); + AUTEnvironmentParametersManager parametersManager = + new AUTEnvironmentParametersManager( + getClient(), + autEnvironmentParameters, + parametersRootFolderId, + autEnvironmentConfigurationId, + buildVariableResolver, + model.getPathToJsonFile(), + logger, + selectedNode); + + Collection parametersToUpdate = + parametersManager.getParametersToUpdate(); + parametersManager.updateParametersValues(parametersToUpdate); + logger.log("assignValuesToAutParameters"); + } + + private String getAutEnvironmentConfigurationId( + AUTEnvironmentManager autEnvironmentManager, + String autEnvironmentId) { + + String autEnvironmentConfigurationId = + autEnvironmentManager.shouldUseExistingConfiguration(model) + ? model.getExistingAutEnvConfId() + : autEnvironmentManager.createNewAutEnvironmentConfiguration( + autEnvironmentId, + model); + + if (StringUtils.isNullOrEmpty(autEnvironmentConfigurationId)) { + throw new SSEException("There's no AUT Environment Configuration in order to proceed"); + } + return autEnvironmentConfigurationId; + + } + + private RestClient getClient() { + if (restClient == null) { + restClient = + new RestClient( + model.getAlmServerUrl(), + model.getAlmDomain(), + model.getAlmProject(), + model.getAlmUserName()); + } + + return restClient; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java new file mode 100644 index 0000000000..3fa0e83910 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentFolder.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment; + +/** + * Created by barush on 02/11/2014. + */ +public class AUTEnvironmentFolder { + + public final static String ALM_PARAMETER_FOLDER_ID_FIELD = "id"; + public final static String ALM_PARAMETER_FOLDER_PARENT_ID_FIELD = "parent-id"; + public final static String ALM_PARAMETER_FOLDER_NAME_FIELD = "name"; + + private String id; + private String name; + private String parentId; + private String path; + + public AUTEnvironmentFolder(String id, String parentId, String name) { + + this.id = id; + this.parentId = parentId; + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getParentId() { + return parentId; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java new file mode 100644 index 0000000000..a910366b0d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentManager.java @@ -0,0 +1,161 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.AUTEnvironmentResolvedModel; +import com.microfocus.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentByIdOldApiRequest; +import com.microfocus.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentByIdRequest; +import com.microfocus.application.automation.tools.sse.autenvironment.request.get.GetAutEnvironmentConfigurationByIdRequest; +import com.microfocus.application.automation.tools.sse.autenvironment.request.post.CreateAutEnvConfRequest; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.net.HttpURLConnection; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +/** + * Created by barush on 03/11/2014. + */ +public class AUTEnvironmentManager { + + public final static String ALM_AUT_ENVIRONMENT_CONFIGURATION_ID_FIELD = "id"; + + private Logger logger; + private Client client; + + public AUTEnvironmentManager(Client client, Logger logger) { + + this.client = client; + this.logger = logger; + } + + public String getParametersRootFolderIdByAutEnvId(String autEnvironmentId) { + + String parametersRootFolderId = null; + Response response = new GetAutEnvironmentByIdRequest(client, autEnvironmentId).execute(); + /** + * This if here for backward compatibility to ALM 11.52. After the support for version < + * 12.00 will be removed this 'if' statement can be removed + * **/ + if (!response.isOk() && response.getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + response = new GetAutEnvironmentByIdOldApiRequest(client, autEnvironmentId).execute(); + } + try { + List> entities = XPathUtils.toEntities(response.toString()); + if (!response.isOk() || entities.size() != 1) { + throw new SSEException(String.format( + "Failed to get AUT Environment with ID: [%s]", + autEnvironmentId), response.getFailure()); + } + + Map autEnvironment = entities.get(0); + parametersRootFolderId = + autEnvironment == null ? null : autEnvironment.get("root-app-param-folder-id"); + } catch (Throwable e) { + logger.log(String.format("Failed to parse response: %s", response)); + } + + return parametersRootFolderId; + } + + public String createNewAutEnvironmentConfiguration( + String autEnvironmentId, + AUTEnvironmentResolvedModel autEnvironmentModel) { + + String newConfigurationName = + autEnvironmentModel.isUseExistingAutEnvConf() + || StringUtils.isNullOrEmpty(autEnvironmentModel.getNewAutEnvConfName()) + ? createTempConfigurationName() + : autEnvironmentModel.getNewAutEnvConfName(); + return createNewAutEnvironmentConfiguration(autEnvironmentId, newConfigurationName); + + } + + private String createNewAutEnvironmentConfiguration( + String autEnvironmentId, + String newAutEnvConfigurationName) { + + String newAutEnvironmentConfigurationId = null; + Response response = + new CreateAutEnvConfRequest(client, autEnvironmentId, newAutEnvConfigurationName).execute(); + if (!response.isOk()) { + logger.log(String.format( + "Failed to create new AUT Environment Configuration named: [%s] for AUT Environment with id: [%s]", + newAutEnvConfigurationName, + autEnvironmentId)); + return null; + } + try { + newAutEnvironmentConfigurationId = + XPathUtils.getAttributeValue( + response.toString(), + ALM_AUT_ENVIRONMENT_CONFIGURATION_ID_FIELD); + } catch (Throwable e) { + logger.log(String.format("Failed to parse response: %s", response)); + } + + return newAutEnvironmentConfigurationId; + } + + public boolean shouldUseExistingConfiguration(AUTEnvironmentResolvedModel autEnvironmentModel) { + + return autEnvironmentModel.isUseExistingAutEnvConf() + && isAutEnvironmentConfigurationExists(autEnvironmentModel.getExistingAutEnvConfId()); + + } + + private boolean isAutEnvironmentConfigurationExists(String existingAutEnvConfId) { + + Response response = + new GetAutEnvironmentConfigurationByIdRequest(client, existingAutEnvConfId).execute(); + if (!response.isOk() || XPathUtils.toEntities(response.toString()).size() != 1) { + logger.log(String.format( + "Failed to get AUT Environment Configuration with ID: [%s]. Will try to create a new one", + existingAutEnvConfId)); + return false; + } + return true; + + } + + private String createTempConfigurationName() { + + return "Configuration_" + Calendar.getInstance().getTime().toString(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java new file mode 100644 index 0000000000..e2555b987c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmentParametersManager.java @@ -0,0 +1,277 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.AutEnvironmentParameterModel; +import com.microfocus.application.automation.tools.sse.autenvironment.request.get.GetAutEnvFoldersByIdRequest; +import com.microfocus.application.automation.tools.sse.autenvironment.request.get.GetParametersByAutEnvConfIdRequest; +import com.microfocus.application.automation.tools.sse.autenvironment.request.put.PutAutEnvironmentParametersBulkRequest; +import com.microfocus.application.automation.tools.sse.common.JsonHandler; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import hudson.util.VariableResolver; + +import java.util.*; + +/** + * Created by barush on 29/10/2014. + */ +public class AUTEnvironmentParametersManager { + + public final static String PARAMETER_PATH_DELIMITER = "/"; + + private Logger logger; + private Client client; + private List parametersToAssign; + private String parametersRootFolderId; + private String autEnvironmentConfigurationId; + private Map parameters; + + private VariableResolver buildVariableResolver; + private String pathToJsonFile; + + private String selectedNode; + + public AUTEnvironmentParametersManager( + Client client, + List parametersToAssign, + String parametersRootFolderId, + String autEnvironmentConfigurationId, + VariableResolver buildVariableResolver, + String pathToJsonFile, + Logger logger, + String selectedNode) { + + this.logger = logger; + this.client = client; + this.parametersToAssign = parametersToAssign; + this.parametersRootFolderId = parametersRootFolderId; + this.autEnvironmentConfigurationId = autEnvironmentConfigurationId; + this.buildVariableResolver = buildVariableResolver; + this.pathToJsonFile = pathToJsonFile; + this.selectedNode = selectedNode; + } + + public Collection getParametersToUpdate() { + parameters = getAllParametersByAutEnvConfId(); + Map parametersFolders = getAllRelevantParametersFolders(); + + for (AUTEnvironmnentParameter parameter : parameters.values()) { + parameter.setFullPath(parametersFolders.get(parameter.getParentId()).getPath() + + PARAMETER_PATH_DELIMITER + + parameter.getName()); + + } + + resolveValuesOfParameters(); + return getResolvedParametersWithAssignedValues(); + } + + public void updateParametersValues(Collection parametersToUpdate) { + + Response response = + new PutAutEnvironmentParametersBulkRequest(client, parametersToUpdate).execute(); + if (!response.isOk()) { + throw new SSEException( + String.format( + "Failed to update the parameters of AUT Environment Configuration with ID: [%s]", + autEnvironmentConfigurationId), + response.getFailure()); + } + logger.log("Submitted all parameters to ALM"); + } + + private Map getAllParametersByAutEnvConfId() { + + Map parametersMap = + new HashMap(); + Response response = + new GetParametersByAutEnvConfIdRequest(client, autEnvironmentConfigurationId).execute(); + if (!response.isOk()) { + throw new SSEException( + String.format( + "Failed to retrieve the parameters of AUT Environment Configuration with ID: [%s]", + autEnvironmentConfigurationId), + response.getFailure()); + } + + List> parameters = XPathUtils.toEntities(response.toString()); + + for (Map parameter : parameters) { + + String id = parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_ID_FIELD); + AUTEnvironmnentParameter param = + new AUTEnvironmnentParameter( + id, + parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_PARENT_ID_FIELD), + parameter.get(AUTEnvironmnentParameter.ALM_PARAMETER_NAME_FIELD)); + parametersMap.put(id, param); + + } + + return parametersMap; + + } + + private Map getAllRelevantParametersFolders() { + + Map parametersFolders = + new HashMap(); + StringBuilder foldersToGet = new StringBuilder(parametersRootFolderId); + + for (AUTEnvironmnentParameter parameter : parameters.values()) { + foldersToGet.append("%20OR%20" + parameter.getParentId()); + } + + Response response = + new GetAutEnvFoldersByIdRequest(client, foldersToGet.toString()).execute(); + if (!response.isOk()) { + throw new SSEException( + String.format( + "Failed to retrieve parameters folders of AUT Environment Configuration with ID: [%s]", + autEnvironmentConfigurationId), + response.getFailure()); + } + + List> folders = XPathUtils.toEntities(response.toString()); + + for (Map folder : folders) { + + String folderId = folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_ID_FIELD); + if (!parametersFolders.containsKey(folderId)) { + AUTEnvironmentFolder autEnvironmentFolder = + new AUTEnvironmentFolder( + folderId, + folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_PARENT_ID_FIELD), + folder.get(AUTEnvironmentFolder.ALM_PARAMETER_FOLDER_NAME_FIELD)); + parametersFolders.put(folderId, autEnvironmentFolder); + + } + } + + for (AUTEnvironmentFolder folder : parametersFolders.values()) { + calculatePaths(folder, parametersFolders); + } + return parametersFolders; + } + + private String calculatePaths( + AUTEnvironmentFolder folder, + Map parametersFolders) { + + String calculatedPath; + if (folder.getId().equals(parametersRootFolderId)) { + calculatedPath = folder.getName(); + } else { + calculatedPath = + StringUtils.isNullOrEmpty(folder.getPath()) + ? calculatePaths( + parametersFolders.get(folder.getParentId()), + parametersFolders) + + PARAMETER_PATH_DELIMITER + + folder.getName() : folder.getPath(); + } + + folder.setPath(calculatedPath); + return calculatedPath; + } + + private void resolveValuesOfParameters() { + + boolean shouldLoadJsonObject = true; + Object jsonObject = null; + JsonHandler jsonHandler = new JsonHandler(logger); + + for (AutEnvironmentParameterModel parameter : parametersToAssign) { + String resolvedValue = ""; + switch (AutEnvironmentParameterModel.AutEnvironmentParameterType.get(parameter.getParamType())) { + + case ENVIRONMENT: + resolvedValue = buildVariableResolver.resolve(parameter.getValue()); + break; + case EXTERNAL: + if (shouldLoadJsonObject) { + jsonObject = jsonHandler.load(selectedNode, pathToJsonFile); + shouldLoadJsonObject = false; + } + resolvedValue = + jsonHandler.getValueFromJsonAsString( + jsonObject, + parameter.getValue(), + parameter.isShouldGetOnlyFirstValueFromJson()); + break; + case USER_DEFINED: + resolvedValue = parameter.getValue(); + break; + case UNDEFINED: + resolvedValue = ""; + break; + } + + parameter.setResolvedValue(resolvedValue); + } + + } + + private Collection getResolvedParametersWithAssignedValues() { + + Collection valuesToReturn = + new ArrayList(); + for (AutEnvironmentParameterModel parameterByModel : parametersToAssign) { + String parameterPathByModel = parameterByModel.getName(); + for (AUTEnvironmnentParameter parameter : parameters.values()) { + if (parameterPathByModel.equalsIgnoreCase(parameter.getFullPath())) { + String resolvedValue = parameterByModel.getResolvedValue(); + parameter.setValue(resolvedValue); + logger.log(String.format( + "Parameter: [%s] of type: [%s] will get the value: [%s] ", + parameter.getFullPath(), + parameterByModel.getParamType(), + resolvedValue)); + valuesToReturn.add(parameter); + break; + } + } + + } + logger.log(parametersToAssign.size() > 0 + ? "Finished assignment of values for all parameters" + : "There was no parameters to assign"); + + return valuesToReturn; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java new file mode 100644 index 0000000000..b9a77b4f30 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/AUTEnvironmnentParameter.java @@ -0,0 +1,85 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment; + +/** + * Created by barush on 02/11/2014. + */ +public class AUTEnvironmnentParameter { + + public final static String ALM_PARAMETER_ID_FIELD = "id"; + public final static String ALM_PARAMETER_PARENT_ID_FIELD = "parent-id"; + public final static String ALM_PARAMETER_NAME_FIELD = "name"; + public final static String ALM_PARAMETER_VALUE_FIELD = "value"; + + private String id; + private String parentId; + private String name; + private String value; + private String fullPath; + + public AUTEnvironmnentParameter(String id, String parentId, String name) { + + this.id = id; + this.parentId = parentId; + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getFullPath() { + return fullPath; + } + + public void setFullPath(String fullPath) { + this.fullPath = fullPath; + } + + public String getId() { + return id; + } + + public String getParentId() { + return parentId; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java new file mode 100644 index 0000000000..f3f67e7c1c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/AUTEnvironmentResources.java @@ -0,0 +1,47 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request; + +/** + * Created by barush on 29/10/2014. + */ +public class AUTEnvironmentResources { + + public final static String AUT_ENVIRONMENT_CONFIGURATIONS = "aut-environment-configurations"; + public final static String AUT_ENVIRONMENT_PARAMETER_VALUES = + "aut-environment-parameter-values"; + public final static String AUT_ENVIRONMENTS = "aut-environments"; + public final static String AUT_ENVIRONMENTS_OLD = "AppParamSets"; + public final static String AUT_ENVIRONMENT_PARAMETER_FOLDERS = + "aut-environment-parameter-folders"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java new file mode 100644 index 0000000000..887f1732b5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvFoldersByIdRequest.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.get; + +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralGetRequest; + +/** + * Created by barush on 02/11/2014. + */ +public class GetAutEnvFoldersByIdRequest extends GeneralGetRequest { + + private String folderId; + + public GetAutEnvFoldersByIdRequest(Client client, String folderId) { + + super(client); + this.folderId = folderId; + } + + @Override + protected String getSuffix() { + + return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_FOLDERS; + } + + @Override + protected String getQueryString() { + + return String.format("query={id[%s]}&page-size=2000", folderId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java new file mode 100644 index 0000000000..13c70e8714 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdOldApiRequest.java @@ -0,0 +1,64 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.get; + +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralGetRequest; + +/** + * Created by barush on 02/11/2014. + */ +public class GetAutEnvironmentByIdOldApiRequest extends GeneralGetRequest { + + private String autEnvironmentId; + + public GetAutEnvironmentByIdOldApiRequest(Client client, String autEnvironmentId) { + + super(client); + this.autEnvironmentId = autEnvironmentId; + } + + @Override + protected String getSuffix() { + + return AUTEnvironmentResources.AUT_ENVIRONMENTS_OLD; + + } + + @Override + protected String getQueryString() { + + return String.format("query={id[%s]}", autEnvironmentId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java new file mode 100644 index 0000000000..026e8642ab --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentByIdRequest.java @@ -0,0 +1,64 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.get; + +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralGetRequest; + +/** + * Created by barush on 02/11/2014. + */ +public class GetAutEnvironmentByIdRequest extends GeneralGetRequest { + + private String autEnvironmentId; + + public GetAutEnvironmentByIdRequest(Client client, String autEnvironmentId) { + + super(client); + this.autEnvironmentId = autEnvironmentId; + } + + @Override + protected String getSuffix() { + + return AUTEnvironmentResources.AUT_ENVIRONMENTS; + + } + + @Override + protected String getQueryString() { + + return String.format("query={id[%s]}", autEnvironmentId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java new file mode 100644 index 0000000000..68873f9b22 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetAutEnvironmentConfigurationByIdRequest.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.get; + +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralGetRequest; + +/** + * Created by barush on 03/11/2014. + */ +public class GetAutEnvironmentConfigurationByIdRequest extends GeneralGetRequest { + + private String autEnvironmentConfigurationId; + + public GetAutEnvironmentConfigurationByIdRequest( + Client client, + String autEnvironmentConfigurationId) { + + super(client); + this.autEnvironmentConfigurationId = autEnvironmentConfigurationId; + } + + @Override + protected String getSuffix() { + + return AUTEnvironmentResources.AUT_ENVIRONMENT_CONFIGURATIONS; + + } + + @Override + protected String getQueryString() { + + return String.format("query={id[%s]}", autEnvironmentConfigurationId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java new file mode 100644 index 0000000000..7dee827ba2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/get/GetParametersByAutEnvConfIdRequest.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.get; + +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralGetRequest; + +/** + * Created by barush on 30/10/2014. + */ +public class GetParametersByAutEnvConfIdRequest extends GeneralGetRequest { + + String configurationId; + + public GetParametersByAutEnvConfIdRequest(Client client, String configurationId) { + + super(client); + this.configurationId = configurationId; + } + + @Override + protected String getSuffix() { + + return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_VALUES; + } + + @Override + protected String getQueryString() { + + return String.format("query={app-param-value-set-id[%s]}&page-size=2000", configurationId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java new file mode 100644 index 0000000000..bddf82dea8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/post/CreateAutEnvConfRequest.java @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.post; + +import java.util.ArrayList; +import java.util.List; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralPostRequest; + +/** + * Created by barush on 29/10/2014. + */ +public class CreateAutEnvConfRequest extends GeneralPostRequest { + + private String autEnvironmentId; + private String name; + + public CreateAutEnvConfRequest(Client client, String autEnvironmentId, String name) { + + super(client); + this.autEnvironmentId = autEnvironmentId; + this.name = name; + } + + @Override + protected String getSuffix() { + return AUTEnvironmentResources.AUT_ENVIRONMENT_CONFIGURATIONS; + } + + @Override + protected List> getDataFields() { + + List> ret = new ArrayList>(); + ret.add(new Pair("app-param-set-id", autEnvironmentId)); + ret.add(new Pair("name", name)); + + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java new file mode 100644 index 0000000000..0d25e64456 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/autenvironment/request/put/PutAutEnvironmentParametersBulkRequest.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.autenvironment.request.put; + +import com.microfocus.application.automation.tools.sse.autenvironment.AUTEnvironmnentParameter; +import com.microfocus.application.automation.tools.sse.autenvironment.request.AUTEnvironmentResources; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.request.GeneralPutBulkRequest; + +import java.util.*; + +/** + * Created by barush on 03/11/2014. + */ +public class PutAutEnvironmentParametersBulkRequest extends GeneralPutBulkRequest { + + private Collection parameters; + + public PutAutEnvironmentParametersBulkRequest( + Client client, + Collection parameters) { + super(client); + this.parameters = parameters; + } + + @Override + protected List> getFields() { + + List> fieldsToUpdate = new ArrayList>(); + for (AUTEnvironmnentParameter autEnvironmnentParameter : parameters) { + Map mapOfValues = new HashMap(); + mapOfValues.put( + AUTEnvironmnentParameter.ALM_PARAMETER_ID_FIELD, + autEnvironmnentParameter.getId()); + mapOfValues.put( + AUTEnvironmnentParameter.ALM_PARAMETER_VALUE_FIELD, + autEnvironmnentParameter.getValue()); + fieldsToUpdate.add(mapOfValues); + } + + return fieldsToUpdate; + } + + @Override + protected String getSuffix() { + return AUTEnvironmentResources.AUT_ENVIRONMENT_PARAMETER_VALUES; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandler.java new file mode 100644 index 0000000000..27bca1e914 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandler.java @@ -0,0 +1,130 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.Option; +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import hudson.FilePath; +import hudson.model.Node; +import hudson.util.IOUtils; +import jenkins.model.Jenkins; +import net.minidev.json.JSONArray; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +/** + * Created by barush on 06/11/2014. + */ +public class JsonHandler { + + private static Logger logger; + + public JsonHandler(Logger logger) { + this.logger = logger; + } + + public Object load(String selectedNode, String path) { + + logger.log(String.format("Loading JSON file from: [%s]", path)); + Object parsedJson; + try { + String jsonTxt = ""; + if (selectedNode.equals("master")) { + jsonTxt = getStream(new File(path)); + } else { + Node node = Jenkins.getInstance().getNode(selectedNode); + FilePath filePath = new FilePath(node.getChannel(), path); + JsonHandlerMasterToSlave uftMasterToSlave = new JsonHandlerMasterToSlave(); + try { + jsonTxt = filePath.act(uftMasterToSlave); + } catch (IOException e) { + logger.log(String.format("File path not found %s", e.getMessage())); + } catch (InterruptedException e) { + logger.log(String.format("Remote operation failed %s", e.getMessage())); + } + } + parsedJson = + Configuration.defaultConfiguration().addOptions(Option.ALWAYS_RETURN_LIST).jsonProvider().parse( + jsonTxt); + } catch (Throwable e) { + throw new SSEException(String.format("Failed to load JSON from: [%s]", path), e); + } + + return parsedJson; + } + + public static String getStream(File path) { + InputStream is = null; + try { + is = new FileInputStream(String.valueOf(path)); + + } catch (FileNotFoundException e) { + logger.log(String.format("File path not found %s", e.getMessage())); + } + + String jsonText = ""; + try { + jsonText = IOUtils.toString(is, String.valueOf(StandardCharsets.UTF_8)); + } catch (IOException e) { + logger.log(String.format("Failed to create the json object %s", e.getMessage())); + } + + return jsonText; + } + + public String getValueFromJsonAsString( + Object jsonObject, + String pathToRead, + boolean shouldGetSingleValueOnly) { + + String value = ""; + try { + Object extractedObject = JsonPath.read(jsonObject, pathToRead); + while (extractedObject instanceof JSONArray && shouldGetSingleValueOnly) { + extractedObject = ((JSONArray) extractedObject).get(0); + } + value = extractedObject.toString(); + } catch (Throwable e) { + logger.log(String.format( + "Failed to get the value of [%s] from the JSON file.\n\tError was: %s", + pathToRead, + e.getMessage())); + } + return value; + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandlerMasterToSlave.java b/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandlerMasterToSlave.java new file mode 100644 index 0000000000..8a5b004af2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/common/JsonHandlerMasterToSlave.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; + +import java.io.File; + +public class JsonHandlerMasterToSlave extends MasterToSlaveFileCallable { + @Override + public String invoke(File f, VirtualChannel channel) { + return JsonHandler.getStream(f); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/common/RestXmlUtils.java b/src/main/java/com/microfocus/application/automation/tools/sse/common/RestXmlUtils.java new file mode 100644 index 0000000000..a589563310 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/common/RestXmlUtils.java @@ -0,0 +1,60 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; + +import java.util.HashMap; +import java.util.Map; + + +/*** + * @author Effi Bar-She'an + * @author Dani Schreiber + */ +public class RestXmlUtils { + + public static String fieldXml(String field, String value) { + + return String.format("%s", field, value); + } + + public static Map getAppXmlHeaders() { + + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + + return ret; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/common/StringUtils.java b/src/main/java/com/microfocus/application/automation/tools/sse/common/StringUtils.java new file mode 100644 index 0000000000..2ed62f9965 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/common/StringUtils.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class StringUtils { + + public static final String NEW_LINE = System.getProperty("line.separator"); + public static final String FILE_SEPARATOR = System.getProperty("file.separator"); + public static final String PATH_SEPARATOR = System.getProperty("path.separator"); + + public static final String EMPTY_STRING = ""; + public static final String SPACE = " "; + public static final String PERIOD = "."; + public static final String TAB = "\t"; + + public static boolean isNullOrEmpty(String value) { + + return (value == null) || (value.length() == 0); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/common/XPathUtils.java b/src/main/java/com/microfocus/application/automation/tools/sse/common/XPathUtils.java new file mode 100644 index 0000000000..305835ce24 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/common/XPathUtils.java @@ -0,0 +1,229 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import java.io.StringReader; +import java.util.*; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class XPathUtils { + + public static Map getEntityFieldsMap(String xml) { + Document document = getDocument(xml); + NodeList entities = document.getElementsByTagName("Field"); + Map entityFieldsMap = new HashMap(); + for (int i = 0; i < entities.getLength(); i++) { + Element element = ((Element) entities.item(i)); + entityFieldsMap.put(element.getAttribute("Label"), element.getAttribute("Name")); + } + return entityFieldsMap; + } + + public static Map getEntitySubtypesMap(String xml) { + Document document = getDocument(xml); + NodeList entities = document.getElementsByTagName("type"); + Map customizationMap = new HashMap(); + for (int i = 0; i < entities.getLength(); i++) { + Element element = ((Element) entities.item(i)); + customizationMap.put(element.getAttribute("name"), element.getAttribute("id")); + } + return customizationMap; + } + + public static List> toEntities(String xml) { + + Document document = getDocument(xml); + + List> ret = new ArrayList>(); + NodeList entities = document.getElementsByTagName("Entity"); + for (int i = 0; i < entities.getLength(); i++) { + Map currEntity = new HashMap(); + NodeList fields = ((Element) entities.item(i)).getElementsByTagName("Field"); + for (int j = 0; j < fields.getLength(); j++) { + Node item = fields.item(j); + currEntity.put(item.getAttributes().item(0).getNodeValue(), getFieldValue(item)); + } + ret.add(currEntity); + } + + return ret; + } + + public static String getAttributeValue(String xml, String attrName) { + + NodeList nodes = getChildNodes(xml, "Entity/Fields/Field"); + String ret = StringUtils.EMPTY_STRING; + for (int i = 0; i < nodes.getLength(); i++) { + Node currNode = nodes.item(i); + String attr; + try { + attr = getNecessaryAttribute(currNode, "Name"); + } catch (Throwable cause) { + throw new SSEException(cause); + } + if (attr.equals(attrName)) { + ret = getFieldValue(currNode); + break; + } + } + + return ret; + } + + private static String getFieldValue(Node node) { + + String ret = null; + Node child = node.getFirstChild(); + if (child != null) { + Node child2 = child.getFirstChild(); + if (child2 != null) { + ret = child2.getNodeValue(); + } + } + + return ret; + } + + private static NodeList getChildNodes(String xml, String xpath) { + + NodeList ret = null; + try { + Document document = getDocument(xml); + XPathFactory factory = XPathFactory.newInstance(); + XPathExpression expression = factory.newXPath().compile(xpath); + ret = (NodeList) expression.evaluate(document, XPathConstants.NODESET); + } catch (Throwable cause) { + throw new SSEException(cause); + } + + return ret; + } + + private static String getNecessaryAttribute(Node node, String attributeName) { + + if (!node.hasAttributes()) { + return null; + } + Node attr = node.getAttributes().getNamedItem(attributeName); + if (attr == null) { + throw new SSEException(String.format( + "Error parsing XML, missing mandatory attribute '%s'", + attributeName)); + } + String ret = attr.getNodeValue(); + if (StringUtils.isNullOrEmpty(ret)) { + throw new SSEException(String.format( + "Error parsing XML, mandatory attribute '%s' cannot be empty", //$NON-NLS-1$ + attributeName)); + } + + return ret; + } + + public static Document getDocument(String xml) { + + Document ret = null; + try { + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputSource inputSource = new InputSource(); + inputSource.setCharacterStream(new StringReader(xml)); + ret = builder.parse(inputSource); + } catch (Throwable cause) { + throw new SSEException(cause); + } + + return ret; + } + + public static boolean hasResults(String xml) { + boolean ok = false; + + try { + Document doc = getDocument(xml); + if (doc == null) { + return ok; + } + + Node root = doc.getDocumentElement(); + if (root == null) { + return ok; + } + + if ((root.hasAttributes() && Integer.parseInt(root.getAttributes().getNamedItem("TotalResults").getNodeValue()) > 0) + || (doc.hasChildNodes() && doc.getElementsByTagName("Entity").getLength() > 0)) { + ok = true; + } + } catch (SSEException | NumberFormatException cause) { + throw new SSEException(cause); + } + + return ok; + } + + public static List getTestSetIds(String xml) { + Document doc = getDocument(xml); + NodeList entities = doc.getElementsByTagName("Fields"); + + List ids = new LinkedList<>(); + + for (int i = 0; i < entities.getLength(); i++) { + Element element = (Element) (entities.item(i)).getFirstChild(); + + if (element.getAttribute("Name").equals("cycle-id")) { + ids.add(getFieldValue(element)); + } + } + + return ids; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/JUnitParser.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/JUnitParser.java new file mode 100644 index 0000000000..c78679fbd4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/JUnitParser.java @@ -0,0 +1,242 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.result.model.junit.Error; +import com.microfocus.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testcase; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuite; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; + +public class JUnitParser { + + private String entityId; + + public Testsuites toModel( + List> testInstanceRuns, + String entityId, + String entityName, + String runEntityId, + String url, + String domain, + String project) { + this.entityId = entityId; + Map testSetIdToTestsuite = getTestSets(testInstanceRuns); + addTestcases( + testInstanceRuns, + testSetIdToTestsuite, + entityName, + runEntityId, + url, + domain, + project); + + return createTestsuites(testSetIdToTestsuite); + } + + private Testsuites createTestsuites(Map testSetIdToTestsuite) { + + Testsuites ret = new Testsuites(); + List testsuites = ret.getTestsuite(); + for (Testsuite currTestsuite : testSetIdToTestsuite.values()) { + testsuites.add(currTestsuite); + } + + return ret; + } + + private void addTestcases( + List> testInstanceRuns, + Map testSetIdToTestsuite, + String bvsName, + String runEntityId, + String url, + String domain, + String project) { + + for (Map currEntity : testInstanceRuns) { + addTestcase( + testSetIdToTestsuite, + currEntity, + bvsName, + runEntityId, + url, + domain, + project); + } + } + + private void addTestcase( + Map testSetIdToTestsuite, + Map currEntity, + String bvsName, + String runEntityId, + String url, + String domain, + String project) { + + testSetIdToTestsuite.get(getTestSetId(currEntity)).getTestcase().add( + getTestcase(currEntity, bvsName, runEntityId, url, domain, project)); + } + + private Testcase getTestcase( + Map entity, + String bvsName, + String runEntityId, + String url, + String domain, + String project) { + + Testcase ret = new Testcase(); + ret.setClassname(getTestSetName(entity, bvsName, runEntityId)); + ret.setName(getTestName(entity)); + ret.setTime(getTime(entity)); + ret.setType(entity.get("test-subtype")); + new TestcaseStatusUpdater().update(ret, entity, url, domain, project); + + return ret; + } + + private String getTestSetName(Map entity, String bvsName, String runEntityId) { + String ret = String.format("%s.(Unnamed test set)", bvsName); + String testSetName = entity.get("testset-name"); + if (!StringUtils.isNullOrEmpty(testSetName)) { + ret = String.format("%s (id:%s).%s", bvsName, entityId, testSetName); + } + return ret; + } + + private String getTestName(Map entity) { + + String testName = entity.get("test-config-name"); + if (StringUtils.isNullOrEmpty(testName)) { + testName = "Unnamed test"; + } + + return String.format("%s", testName); + } + + private String getTime(Map entity) { + + String ret = entity.get("duration"); + if (StringUtils.isNullOrEmpty(ret)) { + ret = "0"; + } + + return ret; + } + + private Map getTestSets(List> testInstanceRuns) { + + Map ret = new HashMap(); + for (Map currEntity : testInstanceRuns) { + + String testSetId = getTestSetId(currEntity); + if (!ret.containsKey(testSetId)) { + ret.put(testSetId, new Testsuite()); + } + } + + return ret; + } + + private String getTestSetId(Map entity) { + + return entity.get("testcycl-id"); + } + + private static class TestcaseStatusUpdater { + + public void update( + Testcase testcase, + Map entity, + String url, + String domain, + String project) { + + String status = entity.get("status"); + testcase.setStatus(getJenkinsStatus(status)); + if (testcase.getStatus().equals(JUnitTestCaseStatus.ERROR)) { + String errorMessage = status; + if (errorMessage != null) { + Error error = new Error(); + error.setMessage(String.format( + "Error: %s. %s", + errorMessage, + getTestInstanceRunLink(entity, url, domain, project))); + testcase.getError().add(error); + } + } + } + + private String getTestInstanceRunLink( + Map entity, + String url, + String domain, + String project) { + + String ret = StringUtils.EMPTY_STRING; + String runId = entity.get("run-id"); + if (!StringUtils.isNullOrEmpty(runId)) { + try { + ret = + String.format( + "To see the test instance run in ALM, go to: td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", + project, + domain, + new URL(url).getHost(), + runId); + } catch (MalformedURLException ex) { + throw new SSEException(ex); + } + } + + return ret; + } + + private String getJenkinsStatus(String status) { + + return (!StringUtils.isNullOrEmpty(status) && "Passed".equals(status)) + ? JUnitTestCaseStatus.PASS + : JUnitTestCaseStatus.ERROR; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/LabPublisher.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/LabPublisher.java new file mode 100644 index 0000000000..5c49c1c0c9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/LabPublisher.java @@ -0,0 +1,81 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result; + +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.GetLabRunEntityTestSetRunsRequest; +import com.microfocus.application.automation.tools.sse.sdk.request.GetRequest; + +/** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class LabPublisher extends Publisher { + + public LabPublisher(Client client, String entityId, String runId) { + + super(client, entityId, runId); + } + + @Override + protected String getEntityName(String nameSuffix, Logger logger) { + + String ret = "Unnamed Entity"; + try { + Response response = getEntityName(nameSuffix); + if (response.isOk() && !response.toString().equals("")) { + ret = XPathUtils.getAttributeValue(response.toString(), "name"); + } else { + Throwable failure = response.getFailure(); + logger.log(String.format( + "Failed to get Entity name. Exception: %s", + failure == null ? "null" : failure.getMessage())); + } + } catch (Throwable e) { + logger.log("Failed to get Entity name"); + } + + return ret; + } + + @Override + protected GetRequest getRunEntityTestSetRunsRequest(Client client, String runId) { + + return new GetLabRunEntityTestSetRunsRequest(_client, _runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/PCPublisher.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/PCPublisher.java new file mode 100644 index 0000000000..55da27f3d0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/PCPublisher.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result; + +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.GetPCRunEntityTestSetRunsRequest; +import com.microfocus.application.automation.tools.sse.sdk.request.GetRequest; + +/** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class PCPublisher extends Publisher { + + public PCPublisher(Client client, String entityId, String runId) { + + super(client, entityId, runId); + } + + protected String getEntityName(String nameSuffix, Logger logger) { + + String ret = "Unnamed Entity"; + try { + Response response = getEntityName(nameSuffix); + if (response.isOk() && !response.toString().equals("")) { + String runId = XPathUtils.getAttributeValue(response.toString(), "id"); + String testId = XPathUtils.getAttributeValue(response.toString(), "testcycl-id"); + String testSetId = XPathUtils.getAttributeValue(response.toString(), "cycle-id"); + ret = + String.format( + "PC Test ID: %s, Run ID: %s, Test Set ID: %s", + testId, + runId, + testSetId); + } else { + Throwable failure = response.getFailure(); + logger.log(String.format( + "Failed to get Entity name. Exception: %s", + failure == null ? "null" : failure.getMessage())); + } + } catch (Throwable e) { + logger.log("Failed to get Entity name"); + } + + return ret; + } + + @Override + protected GetRequest getRunEntityTestSetRunsRequest(Client client, String runId) { + + return new GetPCRunEntityTestSetRunsRequest(client, runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/Publisher.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/Publisher.java new file mode 100644 index 0000000000..c6d057d6a5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/Publisher.java @@ -0,0 +1,113 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result; + +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.handler.Handler; +import com.microfocus.application.automation.tools.sse.sdk.request.GetRequest; +import com.microfocus.application.automation.tools.sse.sdk.request.GetRunEntityNameRequest; + +public abstract class Publisher extends Handler { + + public Publisher(Client client, String entityId, String runId) { + + super(client, entityId, runId); + } + + public Testsuites publish( + String nameSuffix, + String url, + String domain, + String project, + Logger logger) { + + Testsuites ret = null; + GetRequest testSetRunsRequest = getRunEntityTestSetRunsRequest(_client, _runId); + Response response = testSetRunsRequest.execute(); + List> testInstanceRun = getTestInstanceRun(response, logger); + String entityName = getEntityName(nameSuffix, logger); + if (testInstanceRun != null && testInstanceRun.size() > 0) { + ret = + new JUnitParser().toModel( + testInstanceRun, + this.getEntityId(), + entityName, + _runId, + url, + domain, + project); + } + + return ret; + } + + protected Response getEntityName(String nameSuffix) { + + return new GetRunEntityNameRequest(_client, nameSuffix, _entityId).execute(); + } + + protected List> getTestInstanceRun(Response response, Logger logger) { + + List> ret = null; + try { + if (!StringUtils.isNullOrEmpty(response.toString())) { + ret = XPathUtils.toEntities(response.toString()); + } + + if (ret ==null || ret.size() == 0) { + logger.log(String.format( + "Parse TestInstanceRuns from response XML got no result. Response: %s", + response.toString())); + } + } catch (Throwable cause) { + logger.log(String.format( + "Failed to parse TestInstanceRuns response XML. Exception: %s, XML: %s", + cause.getMessage(), + response.toString())); + } + + return ret; + } + + protected abstract GetRequest getRunEntityTestSetRunsRequest(Client client, String runId); + + protected abstract String getEntityName(String nameSuffix, Logger logger); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/PublisherFactory.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/PublisherFactory.java new file mode 100644 index 0000000000..4538be76e7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/PublisherFactory.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class PublisherFactory { + + public Publisher create(Client client, String runType, String entityId, String runId) { + + Publisher ret = null; + if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { + ret = new LabPublisher(client, entityId, runId); + } else if (SseModel.PC.equals(runType)) { + ret = new PCPublisher(client, entityId, runId); + } else { + throw new SSEException("PublisherFactory: Unrecognized run type"); + } + + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Error.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Error.java new file mode 100644 index 0000000000..ffe5b51905 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Error.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "content" }) +@XmlRootElement(name = "error") +@XStreamAlias("error") +@XStreamConverter(value= ToAttributedValueConverter.class, strings={"content"}) +public class Error { + + @XmlValue + protected String content; + @XmlAttribute + @XStreamAsAttribute + protected String type; + @XmlAttribute + @XStreamAsAttribute + protected String message; + + /** + * Gets the value of the content property. + * + * @return possible object is {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return possible object is {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return possible object is {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Failure.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Failure.java new file mode 100644 index 0000000000..fd41bf3de8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Failure.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="message" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "content" }) +@XmlRootElement(name = "failure") +@XStreamAlias("failure") +@XStreamConverter(value= ToAttributedValueConverter.class, strings={"content"}) +public class Failure { + + @XmlValue + protected String content; + @XmlAttribute + @XStreamAsAttribute + protected String type; + @XmlAttribute + @XStreamAsAttribute + protected String message; + + /** + * Gets the value of the content property. + * + * @return possible object is {@link String } + * + */ + public String getContent() { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setContent(String value) { + this.content = value; + } + + /** + * Gets the value of the type property. + * + * @return possible object is {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the message property. + * + * @return possible object is {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java new file mode 100644 index 0000000000..8eef670eb6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/JUnitTestCaseStatus.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +/** + * + * @author Amir Zahavi + * + */ +public interface JUnitTestCaseStatus { + + String ERROR = "error"; + String PASS = "pass"; + String FAILURE = "failure"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Properties.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Properties.java new file mode 100644 index 0000000000..126be87dde --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Properties.java @@ -0,0 +1,108 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}property" maxOccurs="unbounded"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "property" }) +@XmlRootElement(name = "properties") +public class Properties { + + @XmlElement(required = true) + protected List property; + + /** + * Gets the value of the property property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the property property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getProperty().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link Property } + * + * + */ + public List getProperty() { + if (property == null) { + property = new ArrayList(); + } + return this.property; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Property.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Property.java new file mode 100644 index 0000000000..d0ed8f7c9a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Property.java @@ -0,0 +1,120 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "property") +public class Property { + + @XmlAttribute(required = true) + protected String name; + @XmlAttribute(required = true) + protected String value; + + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the value property. + * + * @return possible object is {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testcase.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testcase.java new file mode 100644 index 0000000000..f3da99c233 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testcase.java @@ -0,0 +1,407 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}skipped" minOccurs="0"/>
+ *         <element ref="{}error" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}failure" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-err" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="assertions" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="classname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="status" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="report" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "skipped", "error", "failure", "systemOut", "systemErr" }) +@XmlRootElement(name = "testcase") +@XStreamAlias("testcase") +public class Testcase { + + protected String skipped; + @XStreamImplicit + protected List error; + @XStreamImplicit + protected List failure; + @XmlElement(name = "system-out") + @XStreamImplicit(itemFieldName="system-out") + protected List systemOut; + @XmlElement(name = "system-err") + @XStreamImplicit(itemFieldName="system-err") + protected List systemErr; + @XmlAttribute(required = true) + @XStreamAsAttribute + protected String name; + @XmlAttribute + @XStreamAsAttribute + protected String assertions; + @XmlAttribute + @XStreamAsAttribute + protected String time; + @XmlAttribute + @XStreamAsAttribute + protected String classname; + @XmlAttribute + @XStreamAsAttribute + protected String status; + @XmlAttribute + @XStreamAsAttribute + protected String type; + @XmlAttribute + @XStreamAsAttribute + protected String report; + + /** + * Gets the value of the skipped property. + * + * @return possible object is {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the error property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the error property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getError().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link Error } + * + * + */ + public List getError() { + if (error == null) { + error = new ArrayList(); + } + return this.error; + } + + /** + * Gets the value of the failure property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the failure property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getFailure().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link Failure } + * + * + */ + public List getFailure() { + if (failure == null) { + failure = new ArrayList(); + } + return this.failure; + } + + /** + * Gets the value of the systemOut property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the systemOut property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getSystemOut().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link String } + * + * + */ + public List getSystemOut() { + if (systemOut == null) { + systemOut = new ArrayList(); + } + return this.systemOut; + } + + /** + * Gets the value of the systemErr property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the systemErr property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getSystemErr().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link String } + * + * + */ + public List getSystemErr() { + if (systemErr == null) { + systemErr = new ArrayList(); + } + return this.systemErr; + } + + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the assertions property. + * + * @return possible object is {@link String } + * + */ + public String getAssertions() { + return assertions; + } + + /** + * Sets the value of the assertions property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setAssertions(String value) { + this.assertions = value; + } + + /** + * Gets the value of the time property. + * + * @return possible object is {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the classname property. + * + * @return possible object is {@link String } + * + */ + public String getClassname() { + return classname; + } + + /** + * Sets the value of the classname property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setClassname(String value) { + this.classname = value; + } + + /** + * Gets the value of the status property. + * + * @return possible object is {@link String } + * + */ + public String getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setStatus(String value) { + this.status = value; + } + + /** + * Gets the value of the type property. + * + * @return possible object is {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the report property. + * + * @return possible object is {@link String } + * + */ + public String getReport() { + return report; + } + + /** + * Sets the value of the report property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setReport(String value) { + this.report = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuite.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuite.java new file mode 100644 index 0000000000..d2f8a29915 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuite.java @@ -0,0 +1,463 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}properties" minOccurs="0"/>
+ *         <element ref="{}testcase" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element ref="{}system-out" minOccurs="0"/>
+ *         <element ref="{}system-err" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="tests" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="skipped" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="timestamp" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="hostname" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="package" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "properties", "testcase", "systemOut", "systemErr" }) +@XmlRootElement(name = "testsuite") +@XStreamAlias("testsuite") +public class Testsuite { + + protected Properties properties; + @XStreamImplicit + protected List testcase; + @XmlElement(name = "system-out") + @XStreamAlias("system-out") + protected String systemOut; + @XmlElement(name = "system-err") + @XStreamAlias("system-err") + protected String systemErr; + @XmlAttribute(required = true) + @XStreamAsAttribute + protected String name; + @XmlAttribute(required = true) + @XStreamAsAttribute + protected String tests; + @XmlAttribute + @XStreamAsAttribute + protected String failures; + @XmlAttribute + @XStreamAsAttribute + protected String errors; + @XmlAttribute + @XStreamAsAttribute + protected String time; + @XmlAttribute + @XStreamAsAttribute + protected String disabled; + @XmlAttribute + @XStreamAsAttribute + protected String skipped; + @XmlAttribute + @XStreamAsAttribute + protected String timestamp; + @XmlAttribute + @XStreamAsAttribute + protected String hostname; + @XmlAttribute + @XStreamAsAttribute + protected String id; + @XmlAttribute(name = "package") + @XStreamAlias("package") + @XStreamAsAttribute + protected String _package; + + /** + * Gets the value of the properties property. + * + * @return possible object is {@link Properties } + * + */ + public Properties getProperties() { + return properties; + } + + /** + * Sets the value of the properties property. + * + * @param value + * allowed object is {@link Properties } + * + */ + public void setProperties(Properties value) { + this.properties = value; + } + + /** + * Gets the value of the testcase property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the testcase property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getTestcase().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link Testcase } + * + * + */ + public List getTestcase() { + if (testcase == null) { + testcase = new ArrayList(); + } + return this.testcase; + } + + /** + * Gets the value of the systemOut property. + * + * @return possible object is {@link String } + * + */ + public String getSystemOut() { + return systemOut; + } + + /** + * Sets the value of the systemOut property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setSystemOut(String value) { + this.systemOut = value; + } + + /** + * Gets the value of the systemErr property. + * + * @return possible object is {@link String } + * + */ + public String getSystemErr() { + return systemErr; + } + + /** + * Sets the value of the systemErr property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setSystemErr(String value) { + this.systemErr = value; + } + + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the tests property. + * + * @return possible object is {@link String } + * + */ + public String getTests() { + return tests; + } + + /** + * Sets the value of the tests property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTests(String value) { + this.tests = value; + } + + /** + * Gets the value of the failures property. + * + * @return possible object is {@link String } + * + */ + public String getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setFailures(String value) { + this.failures = value; + } + + /** + * Gets the value of the errors property. + * + * @return possible object is {@link String } + * + */ + public String getErrors() { + return errors; + } + + /** + * Sets the value of the errors property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setErrors(String value) { + this.errors = value; + } + + /** + * Gets the value of the time property. + * + * @return possible object is {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the disabled property. + * + * @return possible object is {@link String } + * + */ + public String getDisabled() { + return disabled; + } + + /** + * Sets the value of the disabled property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setDisabled(String value) { + this.disabled = value; + } + + /** + * Gets the value of the skipped property. + * + * @return possible object is {@link String } + * + */ + public String getSkipped() { + return skipped; + } + + /** + * Sets the value of the skipped property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setSkipped(String value) { + this.skipped = value; + } + + /** + * Gets the value of the timestamp property. + * + * @return possible object is {@link String } + * + */ + public String getTimestamp() { + return timestamp; + } + + /** + * Sets the value of the timestamp property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTimestamp(String value) { + this.timestamp = value; + } + + /** + * Gets the value of the hostname property. + * + * @return possible object is {@link String } + * + */ + public String getHostname() { + return hostname; + } + + /** + * Sets the value of the hostname property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setHostname(String value) { + this.hostname = value; + } + + /** + * Gets the value of the id property. + * + * @return possible object is {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + /** + * Gets the value of the package property. + * + * @return possible object is {@link String } + * + */ + public String getPackage() { + return _package; + } + + /** + * Sets the value of the package property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setPackage(String value) { + this._package = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuites.java b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuites.java new file mode 100644 index 0000000000..b00fda498c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/result/model/junit/Testsuites.java @@ -0,0 +1,255 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.01.09 at 04:58:42 PM IST +// + +package com.microfocus.application.automation.tools.sse.result.model.junit; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

+ * Java class for anonymous complex type. + * + *

+ * The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}testsuite" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="time" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="tests" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="failures" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="disabled" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="errors" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "testsuite" }) +@XmlRootElement(name = "testsuites") +@XStreamAlias("testsuites") +public class Testsuites { + @XStreamImplicit + protected List testsuite; + @XmlAttribute + protected String name; + @XmlAttribute + protected String time; + @XmlAttribute + protected String tests; + @XmlAttribute + protected String failures; + @XmlAttribute + protected String disabled; + @XmlAttribute + protected String errors; + + /** + * Gets the value of the testsuite property. + * + *

+ * This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is + * why there is not a set method for the testsuite property. + * + *

+ * For example, to add a new item, do as follows: + * + *

+     * getTestsuite().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list {@link Testsuite } + * + * + */ + public List getTestsuite() { + if (testsuite == null) { + testsuite = new ArrayList(); + } + return this.testsuite; + } + + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the time property. + * + * @return possible object is {@link String } + * + */ + public String getTime() { + return time; + } + + /** + * Sets the value of the time property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTime(String value) { + this.time = value; + } + + /** + * Gets the value of the tests property. + * + * @return possible object is {@link String } + * + */ + public String getTests() { + return tests; + } + + /** + * Sets the value of the tests property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setTests(String value) { + this.tests = value; + } + + /** + * Gets the value of the failures property. + * + * @return possible object is {@link String } + * + */ + public String getFailures() { + return failures; + } + + /** + * Sets the value of the failures property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setFailures(String value) { + this.failures = value; + } + + /** + * Gets the value of the disabled property. + * + * @return possible object is {@link String } + * + */ + public String getDisabled() { + return disabled; + } + + /** + * Sets the value of the disabled property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setDisabled(String value) { + this.disabled = value; + } + + /** + * Gets the value of the errors property. + * + * @return possible object is {@link String } + * + */ + public String getErrors() { + return errors; + } + + /** + * Sets the value of the errors property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setErrors(String value) { + this.errors = value; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java new file mode 100644 index 0000000000..83f7a4249c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ALMRunReportUrlBuilder.java @@ -0,0 +1,99 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.common.ALMRESTVersionUtils; +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.ALMVersion; +import com.microfocus.application.automation.tools.sse.sdk.request.GetALMVersionRequest; + +/** + * @author Effi Bar-She'an + */ +public class ALMRunReportUrlBuilder { + + public String build(Client client, String serverUrl, String domain, String project, String runId) { + String ret = "NA"; + try { + ALMVersion version = getALMVersion(client); + int majorVersion = toInt(version.getMajorVersion()); + int minorVersion = toInt(version.getMinorVersion()); + if (majorVersion < 12 || (majorVersion == 12 && minorVersion < 2)) { + ret = client.buildWebUIRequest(String.format("lab/index.jsp?processRunId=%s", runId)); + } else if (majorVersion >= 16) { + // Url change due to angular js upgrade from ALM16 + ret = String.format("%sui/?redirected&p=%s/%s&execution-report#!/test-set-report/%s", + serverUrl, + domain, + project, + runId); + } else { + ret = String.format("%sui/?redirected&p=%s/%s&execution-report#/test-set-report/%s", + serverUrl, + domain, + project, + runId); + } + } catch (Exception e) { + // result url will be NA (in case of failure like getting ALM version, convert ALM version to number) + } + return ret; + } + + public boolean isNewReport(Client client) { + ALMVersion version = getALMVersion(client); + // Newer than 12.2x, including 12.5x, 15.x and later + return (toInt(version.getMajorVersion()) == 12 && toInt(version.getMinorVersion()) >= 2) + || toInt(version.getMajorVersion()) > 12; + } + + private int toInt(String str) { + + return Integer.parseInt(str); + } + + private ALMVersion getALMVersion(Client client) { + + ALMVersion ret = null; + Response response = new GetALMVersionRequest(client).execute(); + if(response.isOk()) { + ret = ALMRESTVersionUtils.toModel(response.getData()); + } else { + throw new SSEException( + String.format("Failed to get ALM version. HTTP status code: %d", response.getStatusCode()), + response.getFailure()); + } + + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Args.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Args.java new file mode 100644 index 0000000000..4565184c32 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Args.java @@ -0,0 +1,150 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.model.CdaDetails; + +/** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class Args { + + private final String _url; + private final String _domain; + private final String clientType; + private final String _project; + private final String _username; + private final String _password; + private final String _runType; + private final String _entityId; + private final String _duration; + private final String _description; + private final String _postRunAction; + private final String _environmentConfigurationId; + + private final CdaDetails _cdaDetails; + + public Args( + String url, + String domain, + String clientType, + String project, + String username, + String password, + String runType, + String entityId, + String duration, + String description, + String postRunAction, + String environmentConfigurationId, + CdaDetails cdaDetails) { + + _url = url; + _domain = domain; + this.clientType = clientType; + _project = project; + _username = username; + _password = password; + _entityId = entityId; + _runType = runType; + _duration = duration; + _description = description; + _postRunAction = postRunAction; + _environmentConfigurationId = environmentConfigurationId; + _cdaDetails = cdaDetails; + } + + public String getClientType() { return clientType; } + + public String getUrl() { + + return _url; + } + + public String getDomain() { + + return _domain; + } + + public String getProject() { + + return _project; + } + + public String getUsername() { + + return _username; + } + + public String getPassword() { + + return _password; + } + + public String getEntityId() { + + return _entityId; + } + + public String getRunType() { + return _runType; + } + + public String getDuration() { + + return _duration; + } + + public String getDescription() { + + return _description; + } + + public String getPostRunAction() { + + return _postRunAction; + } + + public String getEnvironmentConfigurationId() { + + return _environmentConfigurationId; + } + + public CdaDetails getCdaDetails() { + + return _cdaDetails; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Base64Encoder.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Base64Encoder.java new file mode 100644 index 0000000000..d2b06b32e9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Base64Encoder.java @@ -0,0 +1,87 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class Base64Encoder { + + private final static char[] ALPHABET = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static int[] _toInt = new int[128]; + + static { + for (int i = 0; i < ALPHABET.length; i++) { + _toInt[ALPHABET[i]] = i; + } + } + + /** + * Translates the specified byte array into Base64 string. + * + * @param buf + * the byte array (not null) + * @return the translated Base64 string (not null) + */ + public static String encode(byte[] buf) { + + int size = buf.length; + char[] ar = new char[((size + 2) / 3) * 4]; + int a = 0; + int i = 0; + while (i < size) { + byte b0 = buf[i++]; + byte b1 = (i < size) ? buf[i++] : 0; + byte b2 = (i < size) ? buf[i++] : 0; + + int mask = 0x3F; + ar[a++] = ALPHABET[(b0 >> 2) & mask]; + ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask]; + ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask]; + ar[a++] = ALPHABET[b2 & mask]; + } + switch (size % 3) { + case 1: + ar[--a] = '='; + case 2: + ar[--a] = '='; + break; + } + + return new String(ar); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Client.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Client.java new file mode 100644 index 0000000000..99265f261b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Client.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.util.Map; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public interface Client { + + Response httpGet( + String url, + String queryString, + Map headers, + ResourceAccessLevel resourceAccessLevel); + + Response httpPost( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel); + + Response httpPut( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel); + + String build(String suffix); + + String buildRestRequest(String suffix); + + String buildWebUIRequest(String suffix); + + String getServerUrl(); + + String getUsername(); + + + String getXsrfTokenValue(); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ConsoleLogger.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ConsoleLogger.java new file mode 100644 index 0000000000..4c98193659 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ConsoleLogger.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +/** + * + * @author Amir Zahavi + * + */ +public class ConsoleLogger implements Logger { + + @Override + public void log(String message) { + + System.out.println(message); + } + + @Override + public void error(String message) { + log(message); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/HttpRequestDecorator.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/HttpRequestDecorator.java new file mode 100644 index 0000000000..f76f9b2830 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/HttpRequestDecorator.java @@ -0,0 +1,98 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import com.microfocus.application.automation.tools.common.SSEException; + +public class HttpRequestDecorator { + + /** + * + * @param headers + * headrs to decorate with user info depending on the resource access level. + * @param userName + * @param resourceAccessLevel + */ + public static void decorateHeaderWithUserInfo( + final Map headers, + String userName, + ResourceAccessLevel resourceAccessLevel) { + + if (headers == null) { + throw new IllegalArgumentException("header must not be null"); + } + //attach encrypted user name for protected and public resources + if (resourceAccessLevel.equals(ResourceAccessLevel.PROTECTED) + || resourceAccessLevel.equals(ResourceAccessLevel.PRIVATE)) { + String userHeaderName = resourceAccessLevel.getUserHeaderName(); + String encryptedUserName = getDigestString("MD5", userName); + if (userHeaderName != null) { + headers.put(userHeaderName, encryptedUserName); + } + } + } + + private static String getDigestString(String algorithmName, String dataToDigest) { + + try { + MessageDigest md = MessageDigest.getInstance(algorithmName); + byte[] digested = md.digest(dataToDigest.getBytes()); + + return digestToString(digested); + } catch (NoSuchAlgorithmException ex) { + throw new SSEException(ex); + } + } + + /** + * This method convert byte array to string regardless the charset + * + * @param b + * byte array input + * @return the corresponding string + */ + private static String digestToString(byte[] b) { + + StringBuilder result = new StringBuilder(128); + for (byte aB : b) { + result.append(Integer.toString((aB & 0xff) + 0x100, 16).substring(1)); + } + + return result.toString(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Logger.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Logger.java new file mode 100644 index 0000000000..f8d3b37470 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Logger.java @@ -0,0 +1,47 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public interface Logger { + + public void log(String message); + + public void error(String message); +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/PCRunResponse.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/PCRunResponse.java new file mode 100644 index 0000000000..2e78535781 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/PCRunResponse.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class PCRunResponse extends RunResponse { + + @Override + protected String parseRunId(String runIdResponse) { + String ret = runIdResponse; + if (!StringUtils.isNullOrEmpty(ret)) { + String runIdStr = "qcRunID="; + if (ret.contains(runIdStr)) { + ret = ret.substring(ret.indexOf(runIdStr) + runIdStr.length(), ret.length()); + } + } + return ret; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ResourceAccessLevel.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ResourceAccessLevel.java new file mode 100644 index 0000000000..91ffd43462 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/ResourceAccessLevel.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; + +public enum ResourceAccessLevel { + PUBLIC(null), PROTECTED(RESTConstants.PtaL), PRIVATE(RESTConstants.PvaL); + + private String _headerName; + + private ResourceAccessLevel(String headerName) { + + _headerName = headerName; + } + + public String getUserHeaderName() { + + return _headerName; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Response.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Response.java new file mode 100644 index 0000000000..9a6ab2031c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/Response.java @@ -0,0 +1,132 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.net.HttpURLConnection; +import java.util.List; +import java.util.Map; +import java.nio.charset.StandardCharsets; + +/** + * This is a naive implementation of an HTTP response. We use it to simplify matters in the + * examples. It is nothing more than a container of the response headers and the response body. + */ +public class Response { + + private Map> _headers; + private byte[] _data; + private Throwable _failure; + private int _statusCode = -1; + + public Response() { + + this(null, null, null, -1); + } + + public Response(Exception failure) { + + this(null, null, failure, -1); + } + + public Response( + Map> headers, + byte[] data, + Exception failure, + int statusCode) { + + _headers = headers; + _data = data; + _failure = failure; + _statusCode = statusCode; + } + + public Map> getHeaders() { + + return _headers; + } + + public void setHeaders(Map> responseHeaders) { + + _headers = responseHeaders; + } + + public byte[] getData() { + + return _data; + } + + public void setData(byte[] data) { + + _data = data; + } + + /** + * @return the failure if the access to the requested URL failed, such as a 404 or 500. If no + * such failure occurred this method returns null. + */ + public Throwable getFailure() { + + return _failure; + } + + public void setFailure(Throwable cause) { + + this._failure = cause; + } + + public int getStatusCode() { + + return _statusCode; + } + + public void setStatusCode(int statusCode) { + + _statusCode = statusCode; + } + + public boolean isOk() { + + return getFailure() == null + && (getStatusCode() == HttpURLConnection.HTTP_OK + || getStatusCode() == HttpURLConnection.HTTP_CREATED || getStatusCode() == HttpURLConnection.HTTP_ACCEPTED); + } + + /** + * @see Object#toString() return the contents of the byte[] data as a string. + */ + @Override + public String toString() { + + return new String(_data, StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunManager.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunManager.java new file mode 100644 index 0000000000..4623b1e05f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunManager.java @@ -0,0 +1,324 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.result.PublisherFactory; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import com.microfocus.application.automation.tools.sse.sdk.authenticator.AuthenticationTool; +import com.microfocus.application.automation.tools.sse.sdk.handler.PollHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.PollHandlerFactory; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import com.microfocus.application.automation.tools.sse.sdk.request.*; + +import java.util.*; + +/** + * @author Effi Bar-She'an + * @author Dani Schreiber + */ +public class RunManager { + + private static final String BVS = "Business Verification Suite"; + private static final String TESTSET = "Test Set"; + + private RunHandler _runHandler; + private PollHandler _pollHandler; + private Logger _logger; + private boolean _running = false; + private boolean _polling = false; + + /** + * Execute + */ + public Testsuites execute(RestClient client, Args args, Logger logger) + throws InterruptedException { + Testsuites ret = null; + _logger = logger; + _running = true; + if (AuthenticationTool.getInstance().authenticate(client, args.getUsername(), args.getPassword(), args.getUrl(), args.getClientType(), logger)) { + initialize(args, client); + + if (isValidBvsOrTestSet(client, args) && start(args)) { + _polling = true; + if (poll()) { + ret = + new PublisherFactory().create( + client, + args.getRunType(), + args.getEntityId(), + _runHandler.getRunId()).publish( + _runHandler.getNameSuffix(), + args.getUrl(), + args.getDomain(), + args.getProject(), + logger); + } + _polling = false; + } else { + ret = new Testsuites(); // empty test suite, containing no tests at all + this.stop(); + } + } + + return ret; + } + + private boolean isValidBvsOrTestSet(RestClient client, Args args) { + if (args.getRunType().equals(SseModel.BVS)) { + if (isExistingBvs(client, args)) { + return isValidBvs(client, args); + } else { + _logger.error(String.format("No %s could be found by ID %s!", BVS, args.getEntityId())); + } + } else if (args.getRunType().equals(SseModel.TEST_SET)) { + if (isExistingTestSet(client, args)) { + return hasTestInstances(client, args.getEntityId()); + } else { + _logger.error(String.format("No %s of Functional type could be found by ID %s! " + + "\nNote: You can run only functional test sets and build verification suites using this task. Check to make sure that the configured ID is valid (and that it is not a performance test ID).", TESTSET, args.getEntityId())); + } + } else { + _logger.error("Unknown run type, please check the configuration."); + } + + return false; + } + + private boolean isExistingBvs(RestClient client, Args args) { + Response res = new GetBvsRequest(client, args.getEntityId()).execute(); + return res != null && res.isOk() && res.getData() != null && XPathUtils.hasResults(res.toString()); + } + + private boolean isExistingTestSet(RestClient client, Args args) { + Response res = new GetTestSetRequest(client, args.getEntityId()).execute(); + return res != null && res.isOk() && res.getData() != null && XPathUtils.hasResults(res.toString()); + } + + private boolean isValidBvs(RestClient client, Args args) { + List ids = getBvsTestSetsIds(client, args); + boolean ok = !ids.isEmpty(); + + if (ok) { + Response res = new GetTestInstancesRequest(client, ids).execute(); + + if (res != null && res.isOk() && res.getData() != null) { + List nonEmptyIds = XPathUtils.getTestSetIds(res.toString()); + ids.removeAll(nonEmptyIds); + + if (!ids.isEmpty()) { + ok = false; + _logger.error(String.format("%s with ID %s is invalid, the following test sets contain no tests or are not type of functional: %s", BVS, args.getEntityId(), Arrays.toString(ids.toArray()))); + } + } else { + ok = false; + _logger.error(String.format("Cannot get the test sets of %s with ID %s!", BVS, args.getEntityId())); + } + } else { + _logger.error(String.format("%s with ID %s is empty or contains no test sets of type functional!", BVS, args.getEntityId())); + } + + return ok; + } + + private List getBvsTestSetsIds(RestClient client, Args args) { + Response res = new GetBvsTestSetsRequest(client, args.getEntityId()).execute(); + + if (res == null || !res.isOk() || res.getData() == null) { + return Collections.emptyList(); + } + + return XPathUtils.getTestSetIds(res.toString()); + } + + private boolean hasTestInstances(RestClient client, String id) { + Response res = new GetTestInstancesRequest(client, id).execute(); + boolean ok = res.isOk() && res.getData() != null && XPathUtils.hasResults(res.toString()); + + if (!ok) { + _logger.error(String.format("%s with ID %s is empty or is not of type functional!", TESTSET, id)); + } + + return ok; + } + + /** + * Initialize + */ + private void initialize(Args args, RestClient client) { + String entityId = args.getEntityId(); + _runHandler = new RunHandlerFactory().create(client, args.getRunType(), entityId); + _pollHandler = new PollHandlerFactory().create(client, args.getRunType(), entityId); + } + + /** + * Poll + */ + private boolean poll() throws InterruptedException { + return _pollHandler.poll(_logger); + } + + /** + * Stop + */ + public void stop() { + _logger.log("Stopping run..."); + if (_runHandler != null) { + _runHandler.stop(); + _running = false; + } + if (_pollHandler != null) { + _polling = false; + } + } + + /** + * Start + */ + private boolean start(Args args) { + boolean ret = false; + Response response = + _runHandler.start( + args.getDuration(), + args.getPostRunAction(), + args.getEnvironmentConfigurationId(), + args.getCdaDetails()); + if (isOk(response, args)) { + RunResponse runResponse = getRunResponse(response); + setRunId(runResponse); + if (runResponse.isSucceeded()) { + ret = true; + } + } + logReportUrl(ret, args, response); + return ret; + } + + /** + * Set Run id + */ + private void setRunId(RunResponse runResponse) { + String runId = runResponse.getRunId(); + if (StringUtils.isNullOrEmpty(runId)) { + _logger.log("No run ID"); + throw new SSEException("No run ID"); + } else { + _runHandler.setRunId(runId); + _pollHandler.setRunId(runId); + } + } + + /** + * Log report url + */ + private void logReportUrl(boolean isSucceeded, Args args, Response response) { + if (isSucceeded) { + _logger.log(String.format( + "%s run report for run id %s is at: %s", + args.getRunType(), + _runHandler.getRunId(), + _runHandler.getReportUrl(args))); + } else { + String errMessage = "Failed to prepare timeslot for run. No entity of type " + args.getRunType() + " with id " + args.getEntityId() + " exists."; + _logger.log(String.format( + errMessage + + "\nNote: You can run only functional test sets and build verification suites using this plugin. " + + "Check to make sure that the configured ID is valid " + + "(and that it is not a performance test ID).")); + _logger.log(response.toString()); + } + } + + /** + * Get run response + */ + private RunResponse getRunResponse(Response response) { + return _runHandler.getRunResponse(response); + } + + /** + * Is response ok + */ + private boolean isOk(Response response, Args args) { + boolean ret = false; + if (response.isOk()) { + _logger.log(String.format( + "Executing %s ID: %s in %s/%s %sDescription: %s", + args.getRunType(), + args.getEntityId(), + args.getDomain(), + args.getProject(), + StringUtils.NEW_LINE, + args.getDescription())); + ret = true; + } else { + Throwable cause = response.getFailure(); + if (cause != null) { + _logger.log(String.format( + "Failed to start %s ID: %s, ALM Server URL: %s (Exception: %s)", + args.getRunType(), + args.getEntityId(), + args.getUrl(), + cause.getMessage())); + } else { + _logger.log(String.format( + "Failed to execute %s ID: %s, ALM Server URL: %s (Response: %s)", + args.getRunType(), + args.getEntityId(), + args.getUrl(), + response.getStatusCode())); + } + } + return ret; + } + + /** + * Get running + */ + public boolean getRunning() { + return _running; + } + + /** + * Get polling + */ + public boolean getPolling() { + return _polling; + } + +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunResponse.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunResponse.java new file mode 100644 index 0000000000..8e543dbfb0 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/RunResponse.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class RunResponse { + + private String _successStatus; + private String _runId; + + public void initialize(Response response) { + + String xml = response.toString(); + _successStatus = XPathUtils.getAttributeValue(xml, "SuccessStaus"); + _runId = parseRunId(XPathUtils.getAttributeValue(xml, "info")); + } + + protected String parseRunId(String runIdResponse) { + + String ret = runIdResponse; + if (StringUtils.isNullOrEmpty(ret)) { + ret = "No Run ID"; + } + + return ret; + } + + public String getRunId() { + + return _runId; + } + + public boolean isSucceeded() { + + return "1".equals(_successStatus); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/ApiKeyAuthenticator.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/ApiKeyAuthenticator.java new file mode 100644 index 0000000000..8ecf871f98 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/ApiKeyAuthenticator.java @@ -0,0 +1,84 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.authenticator; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.HashMap; +import java.util.Map; + +/** + * For ALM1260sso and 15sso, there's a different API to authenticated with api key. + */ +public class ApiKeyAuthenticator implements Authenticator { + + private static final String APIKEY_LOGIN_API = "rest/oauth2/login"; + private static final String CLIENT_TYPE = "ALM-CLIENT-TYPE"; + + @Override + public boolean login(Client client, String clientId, String secret, String clientType, Logger logger) { + logger.log("Start login to ALM server with APIkey..."); + Map headers = new HashMap(); + headers.put(CLIENT_TYPE, clientType); + headers.put(RESTConstants.ACCEPT, "application/json"); + headers.put(RESTConstants.CONTENT_TYPE, "application/json"); + + Response response = + client.httpPost( + client.build(APIKEY_LOGIN_API), + String.format("{clientId:%s, secret:%s}", clientId, secret).getBytes(), + headers, + ResourceAccessLevel.PUBLIC); + boolean result = response.isOk(); + logger.log( + result ? String.format( + "Logged in successfully to ALM Server %s using %s", + client.getServerUrl(), + clientId) + : String.format( + "Login to ALM Server at %s failed. Status Code: %s", + client.getServerUrl(), + response.getStatusCode())); + return result; + } + + @Override + public boolean logout(Client client, String username) { + // No logout + return true; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/AuthenticationTool.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/AuthenticationTool.java new file mode 100644 index 0000000000..74830a2425 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/AuthenticationTool.java @@ -0,0 +1,84 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.authenticator; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unify the rest authentication process here from separated part, ALMRestTool and RunManager. + * Any authentication change will only need to change here. + * Created by llu2 on 4/5/2017. + */ +public class AuthenticationTool { + + private List authenticators; + private static AuthenticationTool instance; + + private AuthenticationTool() { + authenticators = new ArrayList<>(); + authenticators.add(new RestAuthenticator()); + authenticators.add(new ApiKeyAuthenticator()); + } + + public static synchronized AuthenticationTool getInstance() { + if (instance == null) { + instance = new AuthenticationTool(); + } + return instance; + } + + /** + * Try authenticate use a list of authenticators and then create session. + */ + public boolean authenticate(Client client, String username, String password, String url, String clientType, Logger logger) { + boolean result = false; + for(Authenticator authenticator : authenticators) { + try { + result = authenticator.login(client, username, password, clientType, logger); + if (result) { + break; + } + } catch (Exception e) { + logger.error(String.format( + "Failed login to ALM Server URL: (%s). Exception: %s", + url.endsWith("/") ? url : String.format("%s/", url), + e.getMessage())); + } + } + return result; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/Authenticator.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/Authenticator.java new file mode 100644 index 0000000000..56aaa250b5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/Authenticator.java @@ -0,0 +1,45 @@ +/* + * 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. + * ___________________________________________________________________ + */ +package com.microfocus.application.automation.tools.sse.sdk.authenticator; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +/** + * Created by llu4 on 1/16/2017. + */ +public interface Authenticator { + + boolean login(Client client, String username, String password, String clientType, Logger logger); + boolean logout(Client client, String username); + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/RestAuthenticator.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/RestAuthenticator.java new file mode 100644 index 0000000000..e9d08dfce8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/authenticator/RestAuthenticator.java @@ -0,0 +1,279 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.authenticator; + +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.sdk.Base64Encoder; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +/** + * @author Effi Bar-She'an + * @author Dani Schreiber + */ + +public class RestAuthenticator implements Authenticator { + + public static final String IS_AUTHENTICATED = "rest/is-authenticated"; + public static final String AUTHENTICATE_HEADER = "WWW-Authenticate"; + public static final String AUTHENTICATION_INFO = "AuthenticationInfo"; + public static final String USER_NAME = "Username"; + public static final String AUTHENTICATE_POINT = "authentication-point/authenticate"; + + private String authenticationPoint; + private Logger logger; + + public boolean login(Client client, String username, String password, String clientType, Logger logger) { + this.logger = logger; + + this.logger.log("Start login to ALM server..."); + if (isAuthenticated(client)) { + return true; + } + prepareAuthenticationPoint(client); + boolean ret = authenticate(client, authenticationPoint, username, password); + if (ret) { + ret = appendQCSessionCookies(client, clientType); + } + return ret; + } + + /** + * Some customer always got wrong authenticate point because of an issue of ALM. + * But they still can login with a right authenticate point. + * So try to login with that anyway. + * @param client + */ + private void prepareAuthenticationPoint(Client client) { + if (authenticationPoint != null && !isAuthenticatePointRight(authenticationPoint, client.getServerUrl())) { + authenticationPoint = null; + } + if (authenticationPoint == null) { + authenticationPoint = client.getServerUrl().endsWith("/") ? + client.getServerUrl() + AUTHENTICATE_POINT : + client.getServerUrl() + "/" + AUTHENTICATE_POINT; + } + logger.log("Try to authenticate through: " + authenticationPoint); + } + + /** + * Some ALM server generates wrong authenticate point and port. + * @param authenticatePointStr + * @param serverUrlStr + * @return + */ + private boolean isAuthenticatePointRight(String authenticatePointStr, String serverUrlStr) { + URL serverUrl; + URL authenticatePoint; + + try { + serverUrl = new URL(serverUrlStr); + } catch (MalformedURLException e) { + logger.log(String.format("Server url %s is not a valid url.", e.getMessage())); + return false; + } + + try { + authenticatePoint = new URL(authenticatePointStr); + } catch (MalformedURLException e) { + logger.log(String.format("Authenticate Point url %s is not a valid url.", e.getMessage())); + return false; + } + + boolean result = serverUrl.getProtocol().equalsIgnoreCase(authenticatePoint.getProtocol()) + && serverUrl.getPort() == authenticatePoint.getPort(); + + if (!result) { + logger.log("Authenticate point schema or port is different with server's. Please check with ALM site admin."); + } + return result; + } + + /** + * @param loginUrl + * to authenticate at + * @return true on operation success, false otherwise Basic authentication (must store returned + * cookies for further use) + */ + private boolean authenticate(Client client, String loginUrl, String username, String password) { + // create a string that looks like: + // "Basic ((username:password))<64encoded>" + byte[] credBytes = (username + ":" + password).getBytes(); + String credEncodedString = "Basic " + Base64Encoder.encode(credBytes); + Map headers = new HashMap(); + headers.put(RESTConstants.AUTHORIZATION, credEncodedString); + Response response = client.httpGet(loginUrl, null, headers, ResourceAccessLevel.PUBLIC); + + boolean ret = response.isOk(); + if (ret) { + logger.log(String.format( + "Logged in successfully to ALM Server %s using %s", + client.getServerUrl(), + username)); + } else { + logger.log(String.format( + "Login to ALM Server at %s failed. Status Code: %s", + client.getServerUrl(), + response.getStatusCode())); + } + return ret; + } + + /** + * @return true if logout successful + * @throws Exception + * close session on server and clean session cookies on client + */ + public boolean logout(Client client, String username) { + // note the get operation logs us out by setting authentication cookies to: + // LWSSO_COOKIE_KEY="" via server response header Set-Cookie + Response response = + client.httpGet( + client.build("authentication-point/logout"), + null, + null, + ResourceAccessLevel.PUBLIC); + return response.isOk(); + } + + /** + * Verify is the client is already authenticated. If not, try get the authenticate point. + * @param client + * @return + */ + private boolean isAuthenticated(Client client) { + Response response = + client.httpGet( + client.build(IS_AUTHENTICATED), + null, + null, + ResourceAccessLevel.PUBLIC); + + if (checkAuthResponse(response, client.getUsername())) { + return true; + } + + // Try to get authenticate point regardless the response status. + authenticationPoint = getAuthenticatePoint(response); + + if (authenticationPoint == null) { + logger.log(String.format("Failed to get authenticate authenticate point. Exception %s", response.getFailure())); + } + else { + authenticationPoint = authenticationPoint.replace("\"", ""); + authenticationPoint += "/authenticate"; + logger.log("Got authenticate point:" + authenticationPoint); + } + + return false; + } + + private boolean checkAuthResponse(Response response, String authUser) { + if (response.getStatusCode() == HttpURLConnection.HTTP_OK) { + if (response.getData() != null + && new String(response.getData()).contains(AUTHENTICATION_INFO) + && new String(response.getData()).contains(USER_NAME) + && new String(response.getData()).contains(authUser)) { + logger.log(String.format("Already logged in to ALM Server using %s", authUser)); + return true; + } + logger.log("Failed to check authenticate response header."); + return false; + } + + if (response.getStatusCode() == HttpURLConnection.HTTP_UNAUTHORIZED) { + logger.log(String.format("User %s unauthorized.", authUser)); + return false; + } + + logger.log(String.format("Failed to check authenticate status. Exception: %s", response.getFailure())); + return false; + } + + /** + * Try get authenticate point from response. + * @param response response + * @return null or authenticate point + */ + private String getAuthenticatePoint(Response response) { + Map> headers = response.getHeaders(); + if (headers == null || headers.size() == 0) { + return null; + } + if (headers.get(AUTHENTICATE_HEADER) == null || headers.get(AUTHENTICATE_HEADER).isEmpty()) { + return null; + } + String authenticateHeader = headers.get(AUTHENTICATE_HEADER).get(0); + String[] authenticateHeaderArray = authenticateHeader.split("="); + if (authenticateHeaderArray.length == 1) { + return null; + } + return authenticateHeaderArray[1]; + } + + private boolean appendQCSessionCookies(Client client, String clientType) { + logger.log("Creating session..."); + Map headers = new HashMap<>(); + headers.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); + headers.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + + // issue a post request so that cookies relevant to the QC Session will be added to the RestClient + Response response = + client.httpPost( + client.build("rest/site-session"), + generateClientTypeData(clientType), + headers, + ResourceAccessLevel.PUBLIC); + boolean ret = response.isOk(); + if (!ret) { + logger.log(String.format("Cannot append QCSession cookies. Exception: %s", response.getFailure())); + } else { + logger.log("Session created."); + } + return ret; + } + + private byte[] generateClientTypeData(String clientType) { + String data = String.format("%s", clientType); + return data.getBytes(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/BvsRunHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/BvsRunHandler.java new file mode 100644 index 0000000000..229d2c61f4 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/BvsRunHandler.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class BvsRunHandler extends RunHandler { + + public BvsRunHandler(Client client, String entityId) { + + super(client, entityId); + } + + @Override + protected String getStartSuffix() { + + return String.format("procedures/%s/startrunprocedure", _entityId); + } + + @Override + public String getNameSuffix() { + + return String.format("procedures/%s", getEntityId()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/EventLogHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/EventLogHandler.java new file mode 100644 index 0000000000..a78350a527 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/EventLogHandler.java @@ -0,0 +1,102 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.EventLogRequest; + +public class EventLogHandler extends Handler { + + private String _timeslotId = StringUtils.EMPTY_STRING; + private int _lastRead = -1; + + public EventLogHandler(Client client, String timeslotId) { + + super(client, timeslotId); + _timeslotId = timeslotId; + } + + public boolean log(Logger logger) { + + boolean ret = false; + Response eventLog = null; + try { + eventLog = getEventLog(); + String xml = eventLog.toString(); + List> entities = XPathUtils.toEntities(xml); + for (Map currEntity : entities) { + if (isNew(currEntity)) { + logger.log(String.format( + "%s:%s", + currEntity.get("creation-time"), + currEntity.get("description"))); + } + } + ret = true; + } catch (Throwable cause) { + logger.log(String.format( + "Failed to print Event Log: %s (run id: %s, reservation id: %s). Cause: %s", + eventLog, + _runId, + _timeslotId, + cause)); + } + + return ret; + } + + private boolean isNew(Map currEntity) { + + boolean ret = false; + int currEvent = Integer.parseInt(currEntity.get("id")); + if (currEvent > _lastRead) { + _lastRead = currEvent; + ret = true; + } + + return ret; + } + + private Response getEventLog() { + + return new EventLogRequest(_client, _timeslotId).execute(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/Handler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/Handler.java new file mode 100644 index 0000000000..0d2e1a24fc --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/Handler.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public abstract class Handler { + + protected final Client _client; + protected final String _entityId; + protected String _runId = StringUtils.EMPTY_STRING; + protected String _timeslotId = StringUtils.EMPTY_STRING; + + public Handler(Client client, String entityId) { + + _client = client; + _entityId = entityId; + } + + public Handler(Client client, String entityId, String runId) { + + this(client, entityId); + _runId = runId; + } + + public String getRunId() { + + return _runId; + } + + public String getEntityId() { + + return _entityId; + } + + public void setRunId(String runId) { + _runId = runId; + } + + public String getTimeslotId() { + + return _timeslotId; + } + + public void setTimeslotId(String timeslotId) { + + _timeslotId = timeslotId; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/LabPollHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/LabPollHandler.java new file mode 100644 index 0000000000..bf1016cfea --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/LabPollHandler.java @@ -0,0 +1,169 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.GetLabRunEntityDataRequest; +import com.microfocus.application.automation.tools.sse.sdk.request.PollSSERunRequest; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class LabPollHandler extends PollHandler { + + private EventLogHandler _eventLogHandler; + + public LabPollHandler(Client client, String entityId) { + + super(client, entityId); + } + + public LabPollHandler(Client client, String entityId, int interval) { + + super(client, entityId, interval); + } + + @Override + protected boolean doPoll(Logger logger) throws InterruptedException { + boolean ret = false; + + Response runEntityResponse = getRunEntityData(); + if (isOk(runEntityResponse, logger)) { + setTimeslotId(runEntityResponse, logger); + _eventLogHandler = new EventLogHandler(_client, _timeslotId); + if (!StringUtils.isNullOrEmpty(_timeslotId)) { + ret = super.doPoll(logger); + } + } + return ret; + } + + @Override + protected Response getResponse() { + + return new PollSSERunRequest(_client, _runId).execute(); + } + + @Override + protected void log(Logger logger) { + + _eventLogHandler.log(logger); + } + + @Override + protected boolean isFinished(Response response, Logger logger) { + + boolean ret = false; + try { + String xml = response.toString(); + String endTime = XPathUtils.getAttributeValue(xml, "end-time"); + if (!StringUtils.isNullOrEmpty(endTime)) { + String startTime = XPathUtils.getAttributeValue(xml, "start-time"); + String currentRunState = XPathUtils.getAttributeValue(xml, "state"); + logger.log(String.format( + "Timeslot %s is %s.\nRun start time: %s, Run end time: %s", + _timeslotId, + currentRunState, + startTime, + endTime)); + ret = true; + } + } catch (Throwable cause) { + logger.log(String.format("Failed to parse response: %s", response)); + ret = true; + } + + return ret; + } + + @Override + protected boolean logRunEntityResults(Response response, Logger logger) { + + boolean ret = false; + try { + String xml = response.toString(); + String state = XPathUtils.getAttributeValue(xml, "state"); + String completedSuccessfully = + XPathUtils.getAttributeValue(xml, "completed-successfully"); + logger.log(String.format( + "Run state of %s: %s, Completed successfully: %s", + _runId, + state, + completedSuccessfully)); + ret = true; + + } catch (Throwable cause) { + logger.log(String.format("Failed to parse response: %s", response)); + } + + return ret; + } + + private void setTimeslotId(Response runEntityResponse, Logger logger) { + + _timeslotId = getTimeslotId(runEntityResponse, logger); + if (!StringUtils.isNullOrEmpty(_timeslotId)) { + logger.log(String.format("Timeslot id: %s", _timeslotId)); + } + } + + private Response getRunEntityData() { + + return new GetLabRunEntityDataRequest(_client, _runId).execute(); + } + + private String getTimeslotId(Response response, Logger logger) { + + String ret = StringUtils.EMPTY_STRING; + try { + String xml = response.toString(); + ret = XPathUtils.getAttributeValue(xml, "reservation-id"); + } catch (Throwable cause) { + logger.log(String.format("Failed to parse response for timeslot ID: %s", response)); + } + + return ret; + } + + @Override + protected Response getRunEntityResultsResponse() { + return new GetLabRunEntityDataRequest(_client, _runId).execute(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCPollHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCPollHandler.java new file mode 100644 index 0000000000..de473eb1f9 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCPollHandler.java @@ -0,0 +1,118 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import java.util.Arrays; +import java.util.List; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.request.GetPCRunEntityDataRequest; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class PCPollHandler extends PollHandler { + + private final static List FINAL_STATES = Arrays.asList("N/A", "Failed", "Passed"); + + public PCPollHandler(Client client, String entityId) { + + super(client, entityId); + } + + public PCPollHandler(Client client, String entityId, int interval) { + + super(client, entityId, interval); + } + + @Override + protected Response getResponse() { + + return new GetPCRunEntityDataRequest(_client, _runId).execute(); + } + + @Override + protected boolean isFinished(Response response, Logger logger) { + + boolean ret = false; + try { + String xml = response.toString(); + String pcEndTime = XPathUtils.getAttributeValue(xml, "pc-end-time"); + String status = XPathUtils.getAttributeValue(xml, "status"); + if (!StringUtils.isNullOrEmpty(pcEndTime)) { + logger.log(String.format("PC test end time: %s", pcEndTime)); + ret = true; + } else if (!StringUtils.isNullOrEmpty(status)) { + if (FINAL_STATES.contains(status)) { + ret = true; + } + } + } catch (Throwable cause) { + logger.log(String.format("Failed to parse response: %s", response)); + ret = true; + } + + return ret; + } + + @Override + protected boolean logRunEntityResults(Response response, Logger logger) { + + boolean ret = false; + try { + String xml = response.toString(); + String status = XPathUtils.getAttributeValue(xml, "status"); + String state = XPathUtils.getAttributeValue(xml, "state"); + logger.log(String.format("Run status of %s: %s, State: %s", _runId, status, state)); + ret = true; + + } catch (Throwable cause) { + logger.log(String.format("Failed to parse response: %s", response)); + } + + return ret; + } + + @Override + protected Response getRunEntityResultsResponse() { + + return new GetPCRunEntityDataRequest(_client, _runId).execute(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCRunHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCRunHandler.java new file mode 100644 index 0000000000..159deec55b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PCRunHandler.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import java.net.MalformedURLException; +import java.net.URL; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.sse.sdk.Args; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.PCRunResponse; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.RunResponse; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class PCRunHandler extends RunHandler { + + public PCRunHandler(Client client, String entityId) { + + super(client, entityId); + } + + @Override + protected String getStartSuffix() { + + return String.format("test-instances/%s/startrun", _entityId); + } + + @Override + public String getNameSuffix() { + + return String.format("runs/%s", _runId); + } + + @Override + public String getReportUrl(Args args) { + + String ret = "No report URL available"; + try { + ret = + String.format( + "td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", + args.getProject(), + args.getDomain(), + new URL(args.getUrl()).getHost(), + _runId); + } catch (MalformedURLException ex) { + throw new SSEException(ex); + } + return ret; + } + + @Override + public RunResponse getRunResponse(Response response) { + + RunResponse ret = new PCRunResponse(); + ret.initialize(response); + + return ret; + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandler.java new file mode 100644 index 0000000000..f093c5045c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandler.java @@ -0,0 +1,128 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Logger; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +public abstract class PollHandler extends Handler { + + private int _interval = 5000; // millisecond + + public PollHandler(Client client, String entityId) { + + super(client, entityId); + } + + public PollHandler(Client client, String entityId, int interval) { + + super(client, entityId); + _interval = interval; + } + + public PollHandler(Client client, String entityId, String runId) { + + super(client, entityId, runId); + } + + public boolean poll(Logger logger) throws InterruptedException { + + logger.log(String.format("Polling... Run ID: %s", _runId)); + + return doPoll(logger); + } + + protected boolean doPoll(Logger logger) throws InterruptedException { + boolean ret = false; + int failures = 0; + + while (failures < 3) { + Response response = getResponse(); + if (isOk(response, logger)) { + log(logger); + if (isFinished(response, logger)) { + ret = true; + logRunEntityResults(getRunEntityResultsResponse(), logger); + break; + } + } else { + ++failures; + } + if (sleep(logger)) { // interrupted + break; + } + } + + return ret; + } + + protected abstract Response getRunEntityResultsResponse(); + + protected abstract boolean logRunEntityResults(Response response, Logger logger); + + protected abstract boolean isFinished(Response response, Logger logger); + + protected abstract Response getResponse(); + + protected boolean isOk(Response response, Logger logger) { + + boolean ret = false; + if (!response.isOk()) { + Throwable cause = response.getFailure(); + logger.log(String.format( + "Polling try failed. Status code: %s, Exception: %s", + response.getStatusCode(), + cause != null ? cause.getMessage() : "Not Available")); + } else { + ret = true; + } + + return ret; + } + + protected boolean sleep(Logger logger) throws InterruptedException { + + boolean ret = false; + try { + Thread.sleep(_interval); + } catch (InterruptedException ex) { + logger.log("Interrupted while polling"); + throw ex; + } + + return ret; + } + + protected void log(Logger logger) {} +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java new file mode 100644 index 0000000000..5fa9760a01 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/PollHandlerFactory.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class PollHandlerFactory { + + public PollHandler create(Client client, String runType, String entityId) { + + PollHandler ret = null; + if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { + ret = new LabPollHandler(client, entityId); + } else if (SseModel.PC.equals(runType)) { + ret = new PCPollHandler(client, entityId); + } else { + throw new SSEException("PollHandlerFactory: Unrecognized run type"); + } + + return ret; + } + + public PollHandler create(Client client, String runType, String entityId, int interval) { + + PollHandler ret = null; + if ((SseModel.BVS.equals(runType)) || (SseModel.TEST_SET.equals(runType))) { + ret = new LabPollHandler(client, entityId, interval); + } else if (SseModel.PC.equals(runType)) { + ret = new PCPollHandler(client, entityId, interval); + } else { + throw new SSEException("PollHandlerFactory: Unrecognized run type"); + } + + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandler.java new file mode 100644 index 0000000000..5ded4474f2 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandler.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.sse.sdk.request.StartRunEntityRequest; +import com.microfocus.application.automation.tools.sse.sdk.request.StopEntityRequest; +import com.microfocus.application.automation.tools.sse.sdk.ALMRunReportUrlBuilder; +import com.microfocus.application.automation.tools.sse.sdk.Args; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.sdk.RunResponse; + +public abstract class RunHandler extends Handler { + + protected abstract String getStartSuffix(); + + public abstract String getNameSuffix(); + + public RunHandler(Client client, String entityId) { + + super(client, entityId); + } + + public Response start( + String duration, + String postRunAction, + String environmentConfigurationId, + CdaDetails cdaDetails) { + + return new StartRunEntityRequest( + _client, + getStartSuffix(), + _entityId, + duration, + postRunAction, + environmentConfigurationId, + cdaDetails).execute(); + } + + public Response stop() { + + return new StopEntityRequest(_client, _runId).execute(); + } + + public String getReportUrl(Args args) { + + return new ALMRunReportUrlBuilder().build(_client, _client.getServerUrl(), args.getDomain(), args.getProject(), _runId); + } + + public RunResponse getRunResponse(Response response) { + + RunResponse ret = new RunResponse(); + ret.initialize(response); + + return ret; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java new file mode 100644 index 0000000000..acd998edbb --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/RunHandlerFactory.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class RunHandlerFactory { + + public RunHandler create(Client client, String runType, String entityId) { + + RunHandler ret = null; + if (SseModel.BVS.equals(runType)) { + ret = new BvsRunHandler(client, entityId); + } else if (SseModel.TEST_SET.equals(runType)) { + ret = new TestSetRunHandler(client, entityId); + } else if (SseModel.PC.equals(runType)) { + ret = new PCRunHandler(client, entityId); + } else { + throw new SSEException("RunHandlerFactory: Unrecognized run type"); + } + + return ret; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java new file mode 100644 index 0000000000..89c3ad0cc6 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/handler/TestSetRunHandler.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.handler; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class TestSetRunHandler extends RunHandler { + + public TestSetRunHandler(Client client, String entityId) { + + super(client, entityId); + } + + @Override + protected String getStartSuffix() { + + return String.format("test-sets/%s/startruntestset", _entityId); + } + + @Override + public String getNameSuffix() { + + return String.format("test-sets/%s", getEntityId()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java new file mode 100644 index 0000000000..d1b5696c1d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/CreateSiteSessionRequest.java @@ -0,0 +1,62 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +import java.util.HashMap; +import java.util.Map; + +public class CreateSiteSessionRequest extends GeneralPostRequest { + + public CreateSiteSessionRequest(Client client) { + + super(client); + } + + @Override + protected String getUrl() { + + return _client.build("rest/site-session"); + } + + @Override + protected Map getHeaders() { + + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.TEXT_PLAIN); + + return ret; + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/EventLogRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/EventLogRequest.java new file mode 100644 index 0000000000..ab07fa8380 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/EventLogRequest.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class EventLogRequest extends GetRequest { + + private final String _timeslotId; + + public EventLogRequest(Client client, String timeslotId) { + + super(client, timeslotId); + _timeslotId = timeslotId; + } + + @Override + protected String getSuffix() { + + return String.format( + "event-log-reads?query={context[\"*Timeslot:%%20%s%%3B*\"]}&fields=id,event-type,creation-time,action,description", + _timeslotId); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralGetRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralGetRequest.java new file mode 100644 index 0000000000..19ffd5c3db --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralGetRequest.java @@ -0,0 +1,62 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +/** + * Created by barush on 29/10/2014. + */ +public abstract class GeneralGetRequest extends GeneralRequest { + + protected GeneralGetRequest(Client client) { + super(client); + } + + protected String getQueryString() { + + return null; + } + + @Override + public Response perform() { + + return _client.httpGet( + getUrl(), + getQueryString(), + getHeaders(), + ResourceAccessLevel.PROTECTED); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPostRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPostRequest.java new file mode 100644 index 0000000000..ccc2ba9c4d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPostRequest.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.common.RestXmlUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.nio.charset.StandardCharsets; + +/** + * Created by barush on 29/10/2014. + */ +public abstract class GeneralPostRequest extends GeneralRequest { + + protected GeneralPostRequest(Client client) { + super(client); + } + + @Override + protected Map getHeaders() { + + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + ret.put("X-XSRF-TOKEN", _client.getXsrfTokenValue()); + return ret; + } + + @Override + public Response perform() { + + return _client.httpPost( + getUrl(), + getDataBytes(), + getHeaders(), + ResourceAccessLevel.PROTECTED); + } + + private byte[] getDataBytes() { + + StringBuilder builder = new StringBuilder(""); + for (Pair currPair : getDataFields()) { + builder.append(RestXmlUtils.fieldXml(currPair.getFirst(), currPair.getSecond())); + } + + return builder.append("").toString().getBytes(StandardCharsets.UTF_8); + } + + protected List> getDataFields() { + + return new ArrayList>(0); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java new file mode 100644 index 0000000000..2f0568de91 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralPutBulkRequest.java @@ -0,0 +1,89 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.common.RestXmlUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by barush on 03/11/2014. + */ +public abstract class GeneralPutBulkRequest extends GeneralRequest { + + protected GeneralPutBulkRequest(Client client) { + super(client); + } + + protected abstract List> getFields(); + + @Override + protected Map getHeaders() { + + Map ret = new HashMap(); + ret.put(RESTConstants.CONTENT_TYPE, RESTConstants.APP_XML_BULK); + ret.put(RESTConstants.ACCEPT, RESTConstants.APP_XML); + ret.put("X-XSRF-TOKEN", _client.getXsrfTokenValue()); + return ret; + } + + @Override + protected Response perform() { + return _client.httpPut( + getUrl(), + getDataBytes(), + getHeaders(), + ResourceAccessLevel.PROTECTED); + } + + private byte[] getDataBytes() { + + StringBuilder builder = new StringBuilder(""); + for (Map values : getFields()) { + builder.append(""); + for (String key : values.keySet()) { + builder.append(RestXmlUtils.fieldXml(key, values.get(key))); + } + builder.append(""); + } + + return builder.append("").toString().getBytes(); + + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralRequest.java new file mode 100644 index 0000000000..dd042e725f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GeneralRequest.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.Response; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by barush on 29/10/2014. + */ +public abstract class GeneralRequest { + + protected final Client _client; + + protected GeneralRequest(Client client) { + + _client = client; + } + + public final Response execute() { + + Response ret = new Response(); + try { + ret = perform(); + } catch (Throwable cause) { + ret.setFailure(cause); + } + + return ret; + } + + protected abstract Response perform(); + + protected String getSuffix() { + return null; + } + + protected Map getHeaders() { + Map ret = new HashMap(); + ret.put("X-XSRF-TOKEN", _client.getXsrfTokenValue()); + return ret; + } + + protected String getBody() { + + return null; + } + + protected String getUrl() { + + return _client.buildRestRequest(getSuffix()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java new file mode 100644 index 0000000000..361a8c3805 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetALMVersionRequest.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.adm.performancecenter.plugins.common.rest.RESTConstants; +import com.microfocus.application.automation.tools.sse.common.RestXmlUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +import java.util.Map; + +/** + * @author Effi Bar-She'an + */ +public class GetALMVersionRequest extends GetRequest { + + public GetALMVersionRequest(Client client) { + + super(client, null); + } + + @Override + protected String getSuffix() { + + return String.format("%s/sa/version", RESTConstants.REST_PROTOCOL); + } + + @Override + protected String getUrl() { + + return String.format("%s%s", _client.getServerUrl(), getSuffix()); + } + + @Override + protected Map getHeaders() { + + return RestXmlUtils.getAppXmlHeaders(); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsRequest.java new file mode 100644 index 0000000000..e88e32bc51 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsRequest.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class GetBvsRequest extends GeneralGetRequest { + + private final String _bvsId; + + public GetBvsRequest(Client client, String bvsId) { + super(client); + _bvsId = bvsId; + } + + @Override + protected String getSuffix() { + return "procedures"; + } + + @Override + protected String getQueryString() { + return String.format("query={id[%s]}&fields=id,name&page-size=1", _bvsId); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsTestSetsRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsTestSetsRequest.java new file mode 100644 index 0000000000..7af9e4bf18 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetBvsTestSetsRequest.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class GetBvsTestSetsRequest extends GeneralGetRequest { + + private final String _bvsId; + + public GetBvsTestSetsRequest(Client client, String bvsId) { + super(client); + _bvsId = bvsId; + } + + @Override + protected String getSuffix() { + return "procedure-testsets"; + } + + @Override + protected String getQueryString() { + return String.format("query={parent-id[%s]}&fields=cycle-id", _bvsId); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java new file mode 100644 index 0000000000..f91482a154 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityDataRequest.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class GetLabRunEntityDataRequest extends GetRequest { + + public GetLabRunEntityDataRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + + return String.format("procedure-runs/%s", _runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java new file mode 100644 index 0000000000..aa3067f577 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetLabRunEntityTestSetRunsRequest.java @@ -0,0 +1,71 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.common.RestXmlUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +import java.util.Map; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class GetLabRunEntityTestSetRunsRequest extends GetRequest { + + public GetLabRunEntityTestSetRunsRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + return "procedure-testset-instance-runs"; + } + + @Override + protected String getQueryString() { + + return String.format("query={procedure-run[%s]}&page-size=2000", _runId); + } + + @Override + protected Map getHeaders() { + // It's pretty weird that in 1260 p1 the xml header should be provided. + // Otherwise the server would generate wrong query sql. + return RestXmlUtils.getAppXmlHeaders(); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java new file mode 100644 index 0000000000..9aa937355b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityDataRequest.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class GetPCRunEntityDataRequest extends GetRequest { + + public GetPCRunEntityDataRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + + return String.format("runs/%s", _runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java new file mode 100644 index 0000000000..a5c78927d7 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetPCRunEntityTestSetRunsRequest.java @@ -0,0 +1,55 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class GetPCRunEntityTestSetRunsRequest extends GetRequest { + + public GetPCRunEntityTestSetRunsRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + + return String.format("runs/%s", _runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRequest.java new file mode 100644 index 0000000000..9169d625a8 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRequest.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public abstract class GetRequest extends GeneralGetRequest { + + protected final String _runId; + + protected GetRequest(Client client, String runId) { + + super(client); + _runId = runId; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java new file mode 100644 index 0000000000..6f2a0fd31d --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetRunEntityNameRequest.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public class GetRunEntityNameRequest extends GetRequest { + + private final String _nameSuffix; + + public GetRunEntityNameRequest(Client client, String suffix, String entityId) { + + super(client, entityId); + _nameSuffix = suffix; + + } + + @Override + protected String getSuffix() { + + return _nameSuffix; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestInstancesRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestInstancesRequest.java new file mode 100644 index 0000000000..8a81557c39 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestInstancesRequest.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +import java.util.*; + +public class GetTestInstancesRequest extends GeneralGetRequest { + + private String _bulkIds; + + public GetTestInstancesRequest(Client client, String setId) { + super(client); + _bulkIds = setId; + } + + public GetTestInstancesRequest(Client client, List setIds) { + super(client); + _bulkIds = String.join("%20OR%20", setIds); + } + + @Override + protected String getSuffix() { + return "test-instances"; + } + + @Override + protected String getQueryString() { + return String.format("query={cycle-id[%s]}&fields=cycle-id&page-size=max", _bulkIds); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestSetRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestSetRequest.java new file mode 100644 index 0000000000..6e7bfa4201 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/GetTestSetRequest.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +public class GetTestSetRequest extends GeneralGetRequest { + + private String _id; + + public GetTestSetRequest(Client client, String id) { + super(client); + _id = id; + } + + @Override + protected String getSuffix() { + return "test-sets"; + } + + @Override + protected String getQueryString() { + return String.format("query={id[%s];subtype-id[\"hp.sse.test-set.process\"]}&fields=id,name&page-size=1", _id); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PollSSERunRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PollSSERunRequest.java new file mode 100644 index 0000000000..9c5c71bc50 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PollSSERunRequest.java @@ -0,0 +1,59 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class PollSSERunRequest extends GetRequest { + + private final String _runId; + + public PollSSERunRequest(Client client, String runId) { + + super(client, runId); + _runId = runId; + } + + @Override + protected String getSuffix() { + + return String.format("procedure-runs/%s", _runId); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PostRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PostRequest.java new file mode 100644 index 0000000000..6e5d098bc1 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/PostRequest.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ +public abstract class PostRequest extends GeneralPostRequest { + + protected final String _runId; + + protected PostRequest(Client client, String runId) { + + super(client); + _runId = runId; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java new file mode 100644 index 0000000000..dfd4478070 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StartRunEntityRequest.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import java.util.ArrayList; +import java.util.List; + +import com.microfocus.application.automation.tools.common.Pair; +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class StartRunEntityRequest extends PostRequest { + + private final String _duration; + private final String _suffix; + private final String _environmentConfigurationId; + private final CdaDetails _cdaDetails; + + public StartRunEntityRequest( + Client client, + String suffix, + String runId, + String duration, + String postRunAction, + String environmentConfigurationId, + CdaDetails cdaDetails) { + + super(client, runId); + _duration = duration; + _suffix = suffix; + _environmentConfigurationId = environmentConfigurationId; + _cdaDetails = cdaDetails; + } + + @Override + protected List> getDataFields() { + + List> ret = new ArrayList>(); + ret.add(new Pair("duration", _duration)); + ret.add(new Pair("vudsMode", "false")); + ret.add(new Pair("reservationId", "-1")); + if (!StringUtils.isNullOrEmpty(_environmentConfigurationId)) { + ret.add(new Pair("valueSetId", _environmentConfigurationId)); + if (_cdaDetails != null) { + ret.add(new Pair("topologyAction", _cdaDetails.getTopologyAction())); + ret.add(new Pair( + "realizedTopologyName", + _cdaDetails.getDeployedEnvironmentName())); + + } + } + + return ret; + } + + @Override + protected String getSuffix() { + + return _suffix; + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StopEntityRequest.java b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StopEntityRequest.java new file mode 100644 index 0000000000..4d072be47f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sse/sdk/request/StopEntityRequest.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk.request; + +import com.microfocus.application.automation.tools.sse.sdk.Client; + +/*** + * + * @author Effi Bar-She'an + * @author Dani Schreiber + * + */ + +public class StopEntityRequest extends PostRequest { + + public StopEntityRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + + return String.format("procedure-runs/%s/stop", _runId); + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/model/AbstractSvRunModel.java b/src/main/java/com/microfocus/application/automation/tools/sv/model/AbstractSvRunModel.java new file mode 100644 index 0000000000..342f541043 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/model/AbstractSvRunModel.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.model; + +import java.io.Serializable; + +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import org.apache.commons.lang.StringUtils; + +public class AbstractSvRunModel implements Serializable { + /** + * Name of SvServerSettingsModel instance + */ + protected final String serverName; + /** + * Force operation regardless virtual service is locked + */ + protected final boolean force; + protected final SvServiceSelectionModel serviceSelection; + + public AbstractSvRunModel(String serverName, boolean force, SvServiceSelectionModel serviceSelection) { + this.serverName = serverName; + this.force = force; + this.serviceSelection = serviceSelection; + } + + public String getServerName() { + return (StringUtils.isNotBlank(serverName)) ? serverName : null; + } + + public boolean isForce() { + return force; + } + + public SvServiceSelectionModel getServiceSelection() { + return serviceSelection; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStep.java b/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStep.java new file mode 100644 index 0000000000..57573bbe0a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStep.java @@ -0,0 +1,56 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.pipeline; + +import jenkins.tasks.SimpleBuildStep; +import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; + +public abstract class AbstractSvStep extends AbstractStepImpl { + protected final boolean force; + protected final String serverName; + + public AbstractSvStep(String serverName, boolean force) { + this.serverName = serverName; + this.force = force; + } + + public abstract SimpleBuildStep getBuilder(); + + public String getServerName() { + return serverName; + } + + public boolean isForce() { + return force; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStepDescriptor.java b/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStepDescriptor.java new file mode 100644 index 0000000000..008db09272 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/pipeline/AbstractSvStepDescriptor.java @@ -0,0 +1,78 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.pipeline; + +import javax.annotation.Nonnull; + +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.sv.runner.AbstractSvRunDescriptor; +import hudson.util.ListBoxModel; +import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; +import org.jenkinsci.plugins.workflow.steps.StepExecution; + +public abstract class AbstractSvStepDescriptor extends AbstractStepDescriptorImpl { + + final protected T builderDescriptor; + final private String functionName; + + protected AbstractSvStepDescriptor(Class executionType, String functionName, T builderDescriptor) { + super(executionType); + this.functionName = functionName; + this.builderDescriptor = builderDescriptor; + } + + @Override + public String getFunctionName() { + return functionName; + } + + @Nonnull + @Override + public String getDisplayName() { + return builderDescriptor.getDisplayName(); + } + + @Override + public String getConfigPage() { + return builderDescriptor.getConfigPage(); + } + + public SvServerSettingsModel[] getServers() { + return builderDescriptor.getServers(); + } + + @SuppressWarnings("unused") + public ListBoxModel doFillServerNameItems() { + return builderDescriptor.doFillServerNameItems(); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRemoteRunner.java b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRemoteRunner.java new file mode 100644 index 0000000000..3fcdb7d5a5 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRemoteRunner.java @@ -0,0 +1,125 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.runner; + +import java.io.File; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import com.microfocus.sv.svconfigurator.build.ProjectBuilder; +import com.microfocus.sv.svconfigurator.core.IProject; +import com.microfocus.sv.svconfigurator.core.IService; +import com.microfocus.sv.svconfigurator.core.impl.exception.CommandExecutorException; +import com.microfocus.sv.svconfigurator.core.impl.exception.CommunicatorException; +import com.microfocus.sv.svconfigurator.core.impl.exception.ProjectBuilderException; +import com.microfocus.sv.svconfigurator.core.impl.jaxb.atom.ServiceListAtom; +import com.microfocus.sv.svconfigurator.serverclient.ICommandExecutor; +import com.microfocus.sv.svconfigurator.serverclient.impl.CommandExecutorFactory; +import hudson.FilePath; +import hudson.model.TaskListener; +import jenkins.security.MasterToSlaveCallable; + +public abstract class AbstractSvRemoteRunner extends MasterToSlaveCallable { + protected T model; + protected FilePath workspace; + protected TaskListener listener; + protected SvServerSettingsModel server; + + public AbstractSvRemoteRunner(TaskListener listener, T model, FilePath workspace, SvServerSettingsModel server) { + this.listener = listener; + this.model = model; + this.workspace = workspace; + this.server = server; + } + + protected List getServiceList(boolean ignoreMissingServices, PrintStream logger, FilePath workspace) throws Exception { + SvServiceSelectionModel s = getServiceSelection(); + ICommandExecutor exec = createCommandExecutor(); + + ArrayList res = new ArrayList<>(); + + switch (s.getSelectionType()) { + case SERVICE: + addServiceIfDeployed(s.getService(), res, ignoreMissingServices, exec, logger); + break; + case PROJECT: + IProject project = loadProject(workspace); + for (IService svc : project.getServices()) { + addServiceIfDeployed(svc.getId(), res, ignoreMissingServices, exec, logger); + } + break; + case ALL_DEPLOYED: + for (ServiceListAtom.ServiceEntry entry : exec.getServiceList(null).getEntries()) { + res.add(new ServiceInfo(entry.getId(), entry.getTitle())); + } + break; + case DEPLOY: + break; + default: + throw new IllegalArgumentException(); + } + return res; + } + + protected IProject loadProject(FilePath workspace) throws ProjectBuilderException { + SvServiceSelectionModel s = getServiceSelection(); + FilePath projectPath = workspace.child(s.getProjectPath()); + return new ProjectBuilder().buildProject(new File(projectPath.getRemote()), s.getProjectPassword()); + } + + public SvServiceSelectionModel getServiceSelection() { + return model.getServiceSelection(); + } + + private void addServiceIfDeployed(String service, ArrayList results, boolean ignoreMissingServices, + ICommandExecutor exec, PrintStream logger) throws CommunicatorException, CommandExecutorException { + try { + IService svc = exec.findService(service, null); + results.add(new ServiceInfo(svc.getId(), svc.getName())); + } catch (CommandExecutorException e) { + if (!ignoreMissingServices) { + throw e; + } + logger.printf("Service '%s' is not deployed, ignoring%n", service); + } + } + + protected ICommandExecutor createCommandExecutor() throws Exception { + return new CommandExecutorFactory() + .createCommandExecutor(server.getUrlObject(), server.isTrustEveryone(), server.getCredentials()); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunBuilder.java b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunBuilder.java new file mode 100644 index 0000000000..01e3eec966 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunBuilder.java @@ -0,0 +1,154 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.runner; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.microfocus.application.automation.tools.sv.model.AbstractSvRunModel; +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.model.SvServiceSelectionModel; +import hudson.AbortException; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.Builder; +import jenkins.tasks.SimpleBuildStep; +import org.apache.commons.lang.StringUtils; + +public abstract class AbstractSvRunBuilder extends Builder implements SimpleBuildStep { + private static final Logger LOG = Logger.getLogger(AbstractSvRunBuilder.class.getName()); + + protected final T model; + + protected AbstractSvRunBuilder(T model) { + this.model = model; + } + + protected static void verifyNotNull(Object value, String errorMessage) throws IllegalArgumentException { + if (value == null) { + throw new IllegalArgumentException(errorMessage); + } + } + + public T getModel() { + return model; + } + + public SvServiceSelectionModel getServiceSelection() { + return model.getServiceSelection(); + } + + protected SvServerSettingsModel getSelectedServerSettings() throws IllegalArgumentException { + SvServerSettingsModel[] servers = ((AbstractSvRunDescriptor) getDescriptor()).getServers(); + if (servers != null) { + for (SvServerSettingsModel serverSettings : servers) { + if (model.getServerName() != null && model.getServerName().equals(serverSettings.getName())) { + return serverSettings; + } + } + } + throw new IllegalArgumentException("Selected server configuration '" + model.getServerName() + "' does not exist."); + } + + protected abstract AbstractSvRemoteRunner getRemoteRunner(@Nonnull FilePath workspace, TaskListener listener, SvServerSettingsModel server); + + @Override + public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { + PrintStream logger = listener.getLogger(); + Date startDate = new Date(); + try { + SvServerSettingsModel serverModel = getSelectedServerSettings(); + + logger.printf("%nStarting %s for SV Server '%s' (%s as %s, ignoreSslErrors=%s) on %s%n", getDescriptor().getDisplayName(), + serverModel.getName(), serverModel.getUrlObject(), serverModel.getUsername(), serverModel.isTrustEveryone(), startDate); + logConfig(logger, " "); + validateServiceSelection(); + + SvServerSettingsModel server = getSelectedServerSettings(); + AbstractSvRemoteRunner runner = getRemoteRunner(workspace, listener, server); + launcher.getChannel().call(runner); + + } catch (Exception e) { + LOG.log(Level.SEVERE, "Build failed: " + e.getMessage(), e); + throw new AbortException(e.getMessage()); + } finally { + double duration = (new Date().getTime() - startDate.getTime()) / 1000.; + logger.printf("Finished: %s in %.3f seconds%n%n", getDescriptor().getDisplayName(), duration); + } + } + + protected void logConfig(PrintStream logger, String prefix) { + SvServiceSelectionModel ss = model.getServiceSelection(); + switch (ss.getSelectionType()) { + case SERVICE: + logger.println(prefix + "Service name or id: " + ss.getService()); + break; + case PROJECT: + logger.println(prefix + "Project path: " + ss.getProjectPath()); + logger.println(prefix + "Project password: " + ((StringUtils.isNotBlank(ss.getProjectPassword())) ? "*****" : null)); + break; + case ALL_DEPLOYED: + logger.println(prefix + "All deployed services"); + break; + case DEPLOY: + logger.println(prefix + "Project path: " + ss.getProjectPath()); + logger.println(prefix + "Project password: " + ((StringUtils.isNotBlank(ss.getProjectPassword())) ? "*****" : null)); + logger.println(prefix + "Service name or id: " + ss.getService()); + break; + } + logger.println(prefix + "Force: " + model.isForce()); + } + + protected void validateServiceSelection() throws IllegalArgumentException { + SvServiceSelectionModel s = getServiceSelection(); + switch (s.getSelectionType()) { + case SERVICE: + verifyNotNull(s.getService(), "Service name or id must not be empty if service selection by name or id set"); + break; + case PROJECT: + verifyNotNull(s.getProjectPath(), "Project path must not be empty if service selection by project is set"); + break; + case ALL_DEPLOYED: + break; + case DEPLOY: + verifyNotNull(s.getProjectPath(), "Project path must not be empty for deployment"); + break; + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunDescriptor.java b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunDescriptor.java new file mode 100644 index 0000000000..ef5d97c207 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/runner/AbstractSvRunDescriptor.java @@ -0,0 +1,83 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.runner; + +import javax.annotation.Nonnull; + +import com.microfocus.application.automation.tools.model.SvServerSettingsModel; +import com.microfocus.application.automation.tools.settings.SvServerSettingsGlobalConfiguration; +import hudson.model.AbstractProject; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Builder; +import hudson.util.ListBoxModel; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; + +public abstract class AbstractSvRunDescriptor extends BuildStepDescriptor { + private final String displayName; + + protected AbstractSvRunDescriptor(String displayName) { + this.displayName = displayName; + load(); + } + + @Override + public boolean isApplicable(@SuppressWarnings("rawtypes") Class jobType) { + return true; + } + + @Nonnull + @Override + public String getDisplayName() { + return displayName; + } + + public SvServerSettingsModel[] getServers() { + return SvServerSettingsGlobalConfiguration.getInstance().getServers(); + } + + @SuppressWarnings("unused") + public ListBoxModel doFillServerNameItems() { + ListBoxModel items = new ListBoxModel(); + SvServerSettingsModel[] servers = getServers(); + if (servers != null) { + for (SvServerSettingsModel server : servers) { + if (StringUtils.isNotBlank(server.getName())) { + items.add(server.getName(), server.getName()); + } + } + } + + return items; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/sv/runner/ServiceInfo.java b/src/main/java/com/microfocus/application/automation/tools/sv/runner/ServiceInfo.java new file mode 100644 index 0000000000..00f698dc13 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/sv/runner/ServiceInfo.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sv.runner; + +public class ServiceInfo { + private final String id; + private final String name; + + public ServiceInfo(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/model/FilterTestsModel.java b/src/main/java/com/microfocus/application/automation/tools/uft/model/FilterTestsModel.java new file mode 100644 index 0000000000..6941a0c32c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/model/FilterTestsModel.java @@ -0,0 +1,145 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.model; + +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import javax.annotation.Nonnull; +import java.util.Properties; + +/** + * Contains the model for the filtering options in case of a failed build, when running the tests through ALM + */ +public class FilterTestsModel extends AbstractDescribableImpl { + private String testName; + private Boolean blockedCheckbox; + private Boolean failedCheckbox; + private Boolean notCompletedCheckbox; + private Boolean noRunCheckbox; + private Boolean passedCheckbox; + + @DataBoundConstructor + public FilterTestsModel(String testName, Boolean blockedCheckbox, Boolean failedCheckbox, + Boolean notCompletedCheckbox, Boolean noRunCheckbox, Boolean passedCheckbox) { + this.testName = testName; + this.blockedCheckbox = blockedCheckbox; + this.failedCheckbox = failedCheckbox; + this.notCompletedCheckbox = notCompletedCheckbox; + this.noRunCheckbox = noRunCheckbox; + this.passedCheckbox = passedCheckbox; + } + + public String getTestName() { + return testName; + } + + @DataBoundSetter + public void setTestName(String testName) { + this.testName = testName; + } + + public Boolean getBlockedCheckbox() { + return blockedCheckbox; + } + + public void setBlockedCheckbox(Boolean blockedCheckbox) { + this.blockedCheckbox = blockedCheckbox; + } + + public Boolean getFailedCheckbox() { + return failedCheckbox; + } + + public void setFailedCheckbox(Boolean failedCheckbox) { + this.failedCheckbox = failedCheckbox; + } + + public Boolean getNotCompletedCheckbox() { + return notCompletedCheckbox; + } + + public void setNotCompletedCheckbox(Boolean notCompletedCheckbox) { + this.notCompletedCheckbox = notCompletedCheckbox; + } + + public Boolean getNoRunCheckbox() { + return noRunCheckbox; + } + + public void setNoRunCheckbox(Boolean noRunCheckbox) { + this.noRunCheckbox = noRunCheckbox; + } + + public Boolean getPassedCheckbox() { + return passedCheckbox; + } + + public void setPassedCheckbox(Boolean passedCheckbox) { + this.passedCheckbox = passedCheckbox; + } + + public void addProperties(Properties props) { + props.put("FilterTests", "true"); + props.put("FilterByName", this.testName); + + StringBuilder statusList = new StringBuilder(); + addStatus(blockedCheckbox,"Blocked", statusList); + addStatus(failedCheckbox,"Failed", statusList); + addStatus(notCompletedCheckbox,"\"Not Completed\"", statusList); + addStatus(noRunCheckbox,"\"No Run\"", statusList); + addStatus(passedCheckbox,"Passed", statusList); + + if(statusList.length() > 0){ + statusList.replace(statusList.lastIndexOf(","), statusList.lastIndexOf(" "),""); + } + + props.put("FilterByStatus", statusList.toString()); + } + + public void addStatus(boolean status, String statusName, StringBuilder statusList){ + if(status){ + statusList.append(statusName); + statusList.append(", "); + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() {return "Filter tests model";} + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel.java new file mode 100644 index 0000000000..4b2ca32c5a --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel.java @@ -0,0 +1,108 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.model; + +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; + +public class RerunSettingsModel extends AbstractDescribableImpl { + private String test; + private Boolean checked; + private Integer numberOfReruns; + private String cleanupTest; + + @DataBoundConstructor + public RerunSettingsModel(String test, Boolean checked, Integer numberOfReruns, String cleanupTest) { + this.test = test; + this.checked = checked; + this.numberOfReruns = numberOfReruns; + this.cleanupTest = cleanupTest; + } + + public String getTest() { + return test; + } + + @DataBoundSetter + public void setTest(String test) { + this.test = test; + } + + public Boolean getChecked() { + return checked; + } + + @DataBoundSetter + public void setChecked(Boolean checked) { + this.checked = checked; + } + + public Integer getNumberOfReruns() { + return numberOfReruns; + } + + @DataBoundSetter + public void setNumberOfReruns(Integer numberOfReruns) { + this.numberOfReruns = numberOfReruns; + } + + public String getCleanupTest() { + return cleanupTest; + } + + @DataBoundSetter + public void setCleanupTest(String cleanupTest) { + this.cleanupTest = cleanupTest; + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "Rerun settings model"; + } + + public FormValidation doCheckNumberOfReruns(@QueryParameter String value) { + return UftToolUtils.doCheckNumberOfReruns(value); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel.java b/src/main/java/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel.java new file mode 100644 index 0000000000..a12a22e94b --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel.java @@ -0,0 +1,150 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.model; + +import com.microfocus.application.automation.tools.EncryptionUtils; +import com.microfocus.application.automation.tools.model.EnumDescription; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.model.Node; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; + +import org.apache.commons.lang3.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.util.*; +import java.util.stream.Collectors; + +public class SpecifyParametersModel extends AbstractDescribableImpl { + private final static String PWD = "Password"; + + // FOR GUI + private final static EnumDescription STRING_TYPE = new EnumDescription("String", "String"); + private final static EnumDescription NUMBER_TYPE = new EnumDescription("Number", "Number"); + private final static EnumDescription DATE_TYPE = new EnumDescription("Date", "Date"); + private final static EnumDescription BOOL_TYPE = new EnumDescription("Boolean", "Boolean"); + private final static EnumDescription ANY_TYPE = new EnumDescription("Any", "Any"); + private final static EnumDescription PWD_TYPE = new EnumDescription(PWD, PWD); + + public final static List paramTypesGUI = Arrays.asList(STRING_TYPE, NUMBER_TYPE, DATE_TYPE, BOOL_TYPE, ANY_TYPE, PWD_TYPE); + + // FOR API + private final static EnumDescription INT_TYPE = new EnumDescription("Int", "Int"); + private final static EnumDescription FLOAT_TYPE = new EnumDescription("Float", "Float"); + private final static EnumDescription DATETIME_TYPE = new EnumDescription("DateTime", "DateTime"); + private final static EnumDescription LONG_TYPE = new EnumDescription("Long", "Long"); + private final static EnumDescription DOUBLE_TYPE = new EnumDescription("Double", "Double"); + private final static EnumDescription DECIMAL_TYPE = new EnumDescription("Decimal", "Decimal"); + + public final static List paramTypesAPI = Arrays.asList(STRING_TYPE, INT_TYPE, FLOAT_TYPE, DATETIME_TYPE, BOOL_TYPE, LONG_TYPE, DOUBLE_TYPE, DECIMAL_TYPE); + + public final static Map> mapping = new HashMap<>(); + public final static int NUM_OF_TYPES = paramTypesAPI.size() + paramTypesGUI.size(); + + static { + mapping.put("GUI", paramTypesGUI); + mapping.put("API", paramTypesAPI); + } + + private String parameterJson; + + @DataBoundConstructor + public SpecifyParametersModel(String parameterJson) { + this.parameterJson = parameterJson; + } + + public String getParameterJson() { + return parameterJson; + } + + public void setParameterJson(String parameterJson) { + this.parameterJson = parameterJson; + } + + public void addProperties(Properties props, String searchStr, Node node) throws Exception { + JSONArray testParams = (JSONArray) JSONValue.parseStrict(parameterJson); + + int pidx = 1; + while (props.getProperty(searchStr + pidx) != null) { + final int currPidx = pidx; + + List relevant = testParams.stream().filter(elem -> Integer.parseInt((String) (((JSONObject) elem).get("index"))) == currPidx).collect(Collectors.toList()); + + for (int i = 0; i < relevant.size(); ++i) { + JSONObject curr = ((JSONObject) relevant.get(i)); + String name = curr.get("name").toString(); + String type = curr.get("type").toString(); + String val = curr.get("value").toString(); + if (type.equals(PWD) && StringUtils.isNotBlank(val)) + { + val = EncryptionUtils.encrypt(val, node); + } + + props.setProperty(String.format("Param%d_Name_%d", currPidx, i + 1), name); + props.setProperty(String.format("Param%d_Value_%d", currPidx, i + 1), val); + props.setProperty(String.format("Param%d_Type_%d", currPidx, i + 1), type); + } + + ++pidx; + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + public String getDisplayName() { + return "Specify test parameters model"; + } + + public List getParamTypesGUI() { + return paramTypesGUI; + } + + public List getParamTypesAPI() { + return paramTypesAPI; + } + + public Map> getMapping() { + return mapping; + } + + public int getNumOfTypes() { + return NUM_OF_TYPES; + } + } + +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/model/UftRunAsUser.java b/src/main/java/com/microfocus/application/automation/tools/uft/model/UftRunAsUser.java new file mode 100644 index 0000000000..e0f68390e3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/model/UftRunAsUser.java @@ -0,0 +1,83 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.model; + +import com.microfocus.application.automation.tools.EncryptionUtils; +import hudson.model.Node; +import hudson.util.Secret; +import org.apache.commons.lang.StringUtils; + +import static com.microfocus.application.automation.tools.uft.utils.Constants.*; + +public class UftRunAsUser { + private String username; + private String encodedPwd; + private Secret pwd; + + public UftRunAsUser(String username, String encodedPwd) { + if (StringUtils.isBlank(username) ) { + throw new IllegalArgumentException(String.format("%s is required", UFT_RUN_AS_USER_NAME)); + } else if (StringUtils.isBlank(encodedPwd)) { + throw new IllegalArgumentException(String.format("%s is required", UFT_RUN_AS_USER_ENCODED_PWD)); + } + this.username = username; + this.encodedPwd = encodedPwd; + } + public UftRunAsUser(String username, Secret pwd) { + if (StringUtils.isBlank(username) ) { + throw new IllegalArgumentException(String.format("%s is required", UFT_RUN_AS_USER_NAME)); + } else if (pwd == null) { + throw new IllegalArgumentException(String.format("%s is required", UFT_RUN_AS_USER_PWD)); + } + this.username = username; + this.pwd = pwd; + } + + public String getUsername() { + return username; + } + + public String getEncodedPassword() { + return encodedPwd; + } + + public String getEncodedPasswordAsEncrypted(Node node) throws EncryptionUtils.EncryptionException { + return EncryptionUtils.encrypt(encodedPwd, node); + } + + public Secret getPassword() { return pwd; } + + public String getPasswordAsEncrypted(Node node) throws EncryptionUtils.EncryptionException { + return EncryptionUtils.encrypt(pwd.getPlainText(), node); + } +} \ No newline at end of file diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/model/UftSettingsModel.java b/src/main/java/com/microfocus/application/automation/tools/uft/model/UftSettingsModel.java new file mode 100644 index 0000000000..07566d411f --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/model/UftSettingsModel.java @@ -0,0 +1,267 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.model; + +import com.microfocus.application.automation.tools.model.EnumDescription; +import com.microfocus.application.automation.tools.uft.utils.UftToolUtils; +import hudson.Extension; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.util.FormValidation; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +public class UftSettingsModel extends AbstractDescribableImpl { + public static final String ENTIRE_TEST_SET = "Rerun the entire set of tests"; + public static final String SPECIFIC_TESTS = "Rerun specific tests in the build"; + public static final String ONLY_FAILED_TESTS = "Rerun only failed tests"; + public static final EnumDescription ANY_BUILD_TEST = new EnumDescription( ENTIRE_TEST_SET, ENTIRE_TEST_SET); + public static final EnumDescription SPECIFIC_BUILD_TEST = new EnumDescription(SPECIFIC_TESTS, SPECIFIC_TESTS); + public static final EnumDescription FAILED_BUILD_TEST = new EnumDescription(ONLY_FAILED_TESTS, ONLY_FAILED_TESTS); + public static final List fsTestTypes = Arrays.asList(ANY_BUILD_TEST, SPECIFIC_BUILD_TEST, FAILED_BUILD_TEST); + + private String selectedNode; + private String fsTestPath; + private String numberOfReruns; + private String cleanupTest; + private String onCheckFailedTest; + private String fsTestType; + private List rerunSettingsModels; + + @DataBoundConstructor + public UftSettingsModel(String selectedNode, String numberOfReruns, String cleanupTest, String onCheckFailedTest, + String fsTestType, List rerunSettingsModels) { + this.selectedNode = selectedNode; + this.numberOfReruns = numberOfReruns; + this.cleanupTest = cleanupTest; + this.onCheckFailedTest = onCheckFailedTest; + this.fsTestType = fsTestType; + this.setRerunSettingsModels(UftToolUtils.updateRerunSettings(getSelectedNode(), getFsTestPath(), + rerunSettingsModels)); + } + + public List getNodes() { + return UftToolUtils.getNodesList(); + } + + public String getSelectedNode() { + return selectedNode; + } + + @DataBoundSetter + public void setSelectedNode(String selectedNode) { + this.selectedNode = selectedNode; + } + + public String getFsTestPath() { + return fsTestPath; + } + + public void setFsTestPath(String fsTestPath) { + this.fsTestPath = fsTestPath; + } + + public String getNumberOfReruns() { + return numberOfReruns; + } + + @DataBoundSetter + public void setNumberOfReruns(String numberOfReruns) { + this.numberOfReruns = numberOfReruns; + } + + public String getCleanupTest() { + return cleanupTest; + } + + @DataBoundSetter + public void setCleanupTest(String cleanupTest) { + this.cleanupTest = cleanupTest; + } + + public String getOnCheckFailedTest() { + return onCheckFailedTest; + } + + @DataBoundSetter + public void setOnCheckFailedTest(String onCheckFailedTest) { + this.onCheckFailedTest = onCheckFailedTest; + } + + public String getFsTestType() { + return fsTestType; + } + + @DataBoundSetter + public void setFsTestType(String fsTestType) { + this.fsTestType = fsTestType; + } + + /** + * Gets the rerun settings + * + * @return the rerun settings + */ + public List getRerunSettingsModels() { + return UftToolUtils.updateRerunSettings(selectedNode, getFsTestPath(), rerunSettingsModels); + } + + @DataBoundSetter + public void setRerunSettingsModels(List rerunSettingsModels) { + this.rerunSettingsModels = rerunSettingsModels; + } + + public List getFsTestTypes() { + return fsTestTypes; + } + + /** + * Add properties (failed tests, cleanup tests, number of reruns) to properties file + * + * @param props + */ + public void addToProperties(Properties props) { + if (!StringUtils.isEmpty(this.selectedNode)) { + props.put("Selected node", this.selectedNode); + } + + String onCheckFailedTestVal = StringUtils.isEmpty(this.onCheckFailedTest) ? "false" : this.onCheckFailedTest; + props.put("onCheckFailedTest", onCheckFailedTestVal); + + props.put("testType", this.fsTestType); + + switch(this.fsTestType){ + case ENTIRE_TEST_SET : + addPropertiesForEntireSet(props); + break; + + case SPECIFIC_TESTS: + addPropertiesForSpecificTests(props); + break; + + case ONLY_FAILED_TESTS: + addPropertiesForFailedTests(props); + break; + + default: break; + } + } + + + /** + * Add failed tests, number of reruns and cleanup to the set of properties in case of on failure scenario (rerun the entire test set) + * @param props task properties + */ + private void addPropertiesForEntireSet(Properties props) { + int i = 1; + int index = 1; + while (props.getProperty("Test" + index) != null) { + props.put("FailedTest" + index, props.getProperty("Test" + index)); + index++; + } + + //add number of reruns + if (!StringUtils.isEmpty(this.numberOfReruns)) { + props.put("Reruns" + i, this.numberOfReruns); + } + + //add cleanup test + if (!StringUtils.isEmpty(this.cleanupTest)) { + props.put("CleanupTest" + i, this.cleanupTest); + } + } + + /** + * dd failed tests, number of reruns and cleanup to the set of properties in case of on failure scenario (rerun specific tests) + * @param props task properties + */ + private void addPropertiesForSpecificTests(Properties props){ + int j = 1; + if(this.rerunSettingsModels != null && !this.rerunSettingsModels.isEmpty()) { + for (RerunSettingsModel settings : this.rerunSettingsModels) { + if (settings.getChecked()) {//test is selected + props.put("FailedTest" + j, settings.getTest()); + props.put("Reruns" + j, String.valueOf(settings.getNumberOfReruns())); + if (StringUtils.isEmpty(settings.getCleanupTest())){ + j++; continue; + } + props.put("CleanupTest" + j, settings.getCleanupTest()); + j++; + } + } + } + } + + /** + * Add failed tests, number of reruns and cleanup to the set of properties in case of on failure scenario (rerun only failed tests) + * @param props task properties + */ + private void addPropertiesForFailedTests(Properties props) { + //add number of reruns + if (!StringUtils.isEmpty(this.numberOfReruns)) { + props.put("Reruns1", this.numberOfReruns); + } + //add cleanup test + if (!StringUtils.isEmpty(this.cleanupTest)) { + props.put("CleanupTest1", this.cleanupTest); + } + } + + @Extension + public static class DescriptorImpl extends Descriptor { + @Nonnull + @Override + public String getDisplayName() { + return "UFT Settings Model"; + } + + public FormValidation doCheckNumberOfReruns(@QueryParameter String value) { + return UftToolUtils.doCheckNumberOfReruns(value); + } + + public List getFsTestTypes() { + return fsTestTypes; + } + + public List getNodes() { + return UftToolUtils.getNodesList(); + } + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/utils/Constants.java b/src/main/java/com/microfocus/application/automation/tools/uft/utils/Constants.java new file mode 100644 index 0000000000..74e48b2ae3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/utils/Constants.java @@ -0,0 +1,43 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.utils; + +public final class Constants { + + private Constants() { } + public static final String UFT_PRINT_TEST_PARAMS = "UFT_PRINT_TEST_PARAMS"; + public static final String UFT_RUN_AS_USER_NAME = "UFT_RUN_AS_USER_NAME"; + public static final String UFT_RUN_AS_USER_ENCODED_PWD = "UFT_RUN_AS_USER_ENCODED_PASSWORD"; + public static final String UFT_RUN_AS_USER_PWD = "UFT_RUN_AS_USER_PASSWORD"; + public static final String KEY_VALUE_FORMAT = "%s = %s"; +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftMasterToSlave.java b/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftMasterToSlave.java new file mode 100644 index 0000000000..7fa6a65e3c --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftMasterToSlave.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.utils; + +import hudson.remoting.VirtualChannel; +import jenkins.MasterToSlaveFileCallable; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +public class UftMasterToSlave extends MasterToSlaveFileCallable> { + + private String path; + + public UftMasterToSlave(String path) { + this.path = path; + } + + @Override + public List invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { + return UftToolUtils.getTests(path); + } +} diff --git a/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftToolUtils.java b/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftToolUtils.java new file mode 100644 index 0000000000..e6d560dcf3 --- /dev/null +++ b/src/main/java/com/microfocus/application/automation/tools/uft/utils/UftToolUtils.java @@ -0,0 +1,443 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.uft.utils; + +import com.microfocus.application.automation.tools.uft.model.UftRunAsUser; +import com.microfocus.application.automation.tools.results.projectparser.performance.XmlParserUtil; +import com.microfocus.application.automation.tools.uft.model.RerunSettingsModel; +import hudson.FilePath; +import hudson.model.*; +import hudson.util.FormValidation; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.annotation.Nonnull; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.logging.Logger; + +import static com.microfocus.application.automation.tools.uft.utils.Constants.*; + +public class UftToolUtils { + + private static final Logger logger = Logger.getLogger(UftToolUtils.class.getName()); + private static final String ACTION_TAG = "Action"; + private static final String ACTIONS_XML_TAG = "Actions.xml"; + + private UftToolUtils() { + } + + /** + * Update rerun settings list + * + * @param fsTestPath the build tests path + * @param rerunSettingsModels the rerun settings models to update + * @return + */ + public static List updateRerunSettings(String nodeName, String fsTestPath, List rerunSettingsModels) { + List buildTests = getBuildTests(nodeName, fsTestPath); + + if(buildTests != null && !buildTests.isEmpty()) { + List testPaths = getTests(buildTests, rerunSettingsModels); + for (String testPath : testPaths) { + if (!listContainsTest(rerunSettingsModels, testPath)) { + rerunSettingsModels.add(new RerunSettingsModel(testPath, false, 0, "")); + } + } + } + + return rerunSettingsModels; + } + + public static boolean isMtbxContent(String testContent) { + return testContent != null && testContent.toLowerCase().contains(""); + } + public static boolean isMtbxFile(String testContent) { + return testContent != null && testContent.toLowerCase().endsWith(".mtbx"); + } + + + /** + * Retrieves the build tests + * + * @return an mtbx file with tests, a single test or a list of tests from test folder + */ + public static List getBuildTests(String nodeName, String fsTestPath) { + if (fsTestPath == null) return new ArrayList<>(); + List buildTests; + Node node = Jenkins.get().getNode(nodeName); + String rawTestString = fsTestPath.replace("\\", "/").trim(); + + if (Jenkins.get().getNodes().isEmpty() || (node == null)) {//run tests on master + buildTests = getTests(rawTestString); + } else {//run tests on selected node + buildTests = getTestsFromNode(nodeName, rawTestString); + } + + return buildTests; + } + + public static List getTests(String rawTestString) { + List buildTests = new ArrayList<>(); + if (isMtbxContent(rawTestString)) {//mtbx content in the test path + buildTests = extractTestPathsFromMtbxContent(rawTestString); + } else if (isMtbxFile(rawTestString)) {//mtbx file in the test path + try { + String fileContent = new String(Files.readAllBytes(Paths.get(rawTestString))); + return getTests(fileContent); + } catch (IOException e) { + logger.info(String.format("Failed to get tests from mtbx file %s : %s", rawTestString, e.getMessage())); + } + } else if (rawTestString != null) { + List tests = Arrays.asList(rawTestString.split("\\r?\\n")); + + String paramFilteredTestPath = filterParamFromPath(rawTestString); + + File testFolder = new File(paramFilteredTestPath); + + if (tests.size() == 1 && (testFolder.isDirectory())) {//single test, folder or mtbx file + if(testFolder.exists()){ + buildTests = listFilesForFolder(new File(paramFilteredTestPath)); + } + } else {//list of tests/folders + for (String test : tests) { + File testFile = new File(filterParamFromPath(test).trim()); + if(testFile.exists()) { + buildTests = getBuildTests(testFile); + } + } + } + } + + return buildTests; + } + + private static String filterParamFromPath(String testPath) { + int firstIndexOfParam = testPath.indexOf(" \""); + return firstIndexOfParam == -1 ? testPath : testPath.substring(0, firstIndexOfParam); + } + + public static List extractTestPathsFromMtbxContent(String mtbxContent) { + List tests = new ArrayList<>(); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new ByteArrayInputStream(mtbxContent.getBytes())); + document.getDocumentElement().normalize(); + Element root = document.getDocumentElement(); + NodeList childNodes = root.getChildNodes(); + for (int x = 0; x < childNodes.getLength(); x++) { + org.w3c.dom.Node data = childNodes.item(x); + if (data.getNodeName().equalsIgnoreCase("Test")) { + tests.add(XmlParserUtil.getNodeAttr("path", data)); + } + } + } catch (IOException | SAXException | ParserConfigurationException e) { + logger.warning("Failed to extractTestPathsFromMtbxContent : " + e.getMessage()); + } + + return tests; + } + + private static List getTestsFromNode(String nodeName, String path) { + Node node = Jenkins.get().getNode(nodeName); + FilePath filePath = new FilePath(node.getChannel(), path); + UftMasterToSlave uftMasterToSlave = new UftMasterToSlave(path); + List tests = new ArrayList<>(); + try { + tests = filePath.act(uftMasterToSlave);// + } catch (IOException e) { + logger.info(String.format("File path not found %s", e.getMessage())); + } catch (InterruptedException e) { + logger.info(String.format("Remote operation failed %s", e.getMessage())); + } + + return tests; + } + + public static void deleteReportFoldersFromNode(String nodeName, String testPath, TaskListener listener) { + FilePath filePath = getFilePath(nodeName, testPath); + try { + List entries = filePath.list(); + boolean isDeleted = false; + for (FilePath entry : entries) { + try { + if (entry.getName().startsWith("Report")) { + entry.deleteRecursive(); + listener.getLogger().println(String.format("Folder %s is deleted", entry)); + isDeleted = true; + } + } catch (Exception e) { + listener.error(String.format("Failed to delete folder %s : %s", entry.getName(), e.getMessage())); + } + try { + if (entry.getName().startsWith("StRes")) { + entry.deleteRecursive(); + listener.getLogger().println(String.format("Folder %s is deleted", entry)); + } + } catch (Exception e) { + listener.error(String.format("Failed to delete folder %s : %s", entry.getName(), e.getMessage())); + } + } + + if (!isDeleted) { + listener.getLogger().println(String.format("No report folder was deleted")); + } + } catch (IOException | InterruptedException e) { + listener.error("Failure in clearing report folders for " + testPath + " : " + e.getMessage()); + } + } + + public static FilePath getFilePath(String nodeName, String testPath){ + Node node = Jenkins.get().getNode(nodeName); + FilePath filePath; + if (Jenkins.get().getNodes().isEmpty() || (node == null)) {//tests are running on master + filePath = new FilePath(new File(testPath)); + } else {//tests are running on node + filePath = new FilePath(node.getChannel(), testPath); + } + + return filePath; + } + + /** + * Retrieves the mtbx path, a test path or the list of tests inside a folder + * + * @param folder the test path setup in the configuration (can be the an mtbx file, a single test or a folder containing other tests) + * @return a list of tests + */ + private static List listFilesForFolder(final File folder) { + List buildTests = new ArrayList<>(); + + if (!folder.isDirectory() && folder.getName().contains("mtbx")) { + buildTests.add(folder.getPath().trim()); + return buildTests; + } + + if(folder.isDirectory() && !folder.getName().contains("mtbx") && folder.getName().contains(ACTION_TAG)){//single test + buildTests.add(folder.getPath().trim()); + } + + buildTests = getBuildTests(folder); + + return buildTests; + } + + /** + * Get the list of build tests + * @param folder + * @return either a single test or a set of tests + */ + private static List getBuildTests(final File folder){ + List buildTests = new ArrayList<>(); + File[] files = folder.listFiles(); + if (files == null) { + return Collections.emptyList(); + } + for (final File fileEntry : files) { + if (fileEntry.isDirectory()) { + if(!fileEntry.getName().contains(ACTION_TAG)){ + buildTests.add(fileEntry.getPath().trim()); + continue; + } + buildTests.add(folder.getPath().trim());//single test + break; + } else if (fileEntry.isFile() && fileEntry.getName().endsWith(ACTIONS_XML_TAG)) { + buildTests.add(folder.getPath().trim()); // it is an api test, which contains Actions.xml, which contains all the test Actions + break; + } + } + + return buildTests; + } + + /** + * Checks if a list of tests contains another test + * + * @param rerunSettingModels the list of tests + * @param test the verified test + * @return true if the list already contains the test, false otherwise + */ + private static Boolean listContainsTest(List rerunSettingModels, String test) { + for (RerunSettingsModel settings : rerunSettingModels) { + if (settings.getTest().trim().equals(test.trim())) { + return true; + } + } + + return false; + } + + /** + * Updates the list of current tests based on the updated list of build tests + * + * @param buildTests the list of build tests setup in the configuration + * @param rerunSettingModels the list of current tests + * @return the updated list of tests to rerun + */ + private static List getTests(List buildTests, List rerunSettingModels) { + List rerunTests = new ArrayList<>(); + if (buildTests == null || rerunSettingModels == null) { + return rerunTests; + } + + for (RerunSettingsModel rerun : rerunSettingModels) { + rerunTests.add(rerun.getTest().trim()); + } + + for (String test : buildTests) { + if (!rerunTests.contains(test)) { + rerunTests.add(test.trim()); + } + } + + for (Iterator it = rerunSettingModels.iterator(); it.hasNext(); ) { + RerunSettingsModel rerunSettingsModel1 = it.next(); + if (!buildTests.contains(rerunSettingsModel1.getTest().trim())) { + rerunTests.remove(rerunSettingsModel1.getTest()); + it.remove(); + } + } + + return rerunTests; + } + + public static FormValidation doCheckNumberOfReruns(final String value) { + + String errorMessage = "You must enter a positive integer number."; + + try { + int number = Integer.parseInt(value); + + if (StringUtils.isBlank(value.trim()) || number < 0) { + return FormValidation.error(errorMessage); + } + } catch (NumberFormatException e) { + return FormValidation.error(errorMessage); + } + + return FormValidation.ok(); + } + + public static List getNodesList() { + List nodeList = Jenkins.get().getNodes(); + List nodes = new ArrayList<>(); + nodes.add("master"); + for (Node node : nodeList) { + nodes.add(node.getDisplayName()); + } + + return nodes; + } + public static boolean isPrintTestParams(@Nonnull Run build, @Nonnull TaskListener listener) { + ParametersAction parameterAction = build.getAction(ParametersAction.class); + String msg = "NOTE : The test parameters and their values are printed by default in both Console Output and Results###.xml. You can disable this behavior by defining a job-level parameter UFT_PRINT_TEST_PARAMS as boolean and set it to false."; + boolean isUftPrintTestParams = true; + if (parameterAction == null) { + listener.getLogger().println(msg); + } else { + ParameterValue uftPrintTestParams = parameterAction.getParameter(UFT_PRINT_TEST_PARAMS); + if (uftPrintTestParams == null) { + listener.getLogger().println(msg); + } else { + isUftPrintTestParams = (boolean) uftPrintTestParams.getValue(); + listener.getLogger().println(String.format(KEY_VALUE_FORMAT, UFT_PRINT_TEST_PARAMS, isUftPrintTestParams ? "Yes" : "No")) ; + } + } + return isUftPrintTestParams; + } + + public static UftRunAsUser getRunAsUser(@Nonnull Run build, @Nonnull TaskListener listener) throws IllegalArgumentException { + ParametersAction paramAction = build.getAction(ParametersAction.class); + UftRunAsUser uftRunAsUser = null; + if (paramAction != null) { + ParameterValue paramValuePair = paramAction.getParameter(UFT_RUN_AS_USER_NAME); + if (paramValuePair != null) { + String username = (String) paramValuePair.getValue(); + if (StringUtils.isNotBlank(username)) { + listener.getLogger().println(String.format(KEY_VALUE_FORMAT, UFT_RUN_AS_USER_NAME, username)); + paramValuePair = paramAction.getParameter(UFT_RUN_AS_USER_ENCODED_PWD); + if (paramValuePair == null) { + uftRunAsUser = getRunAsUserWithPassword(paramAction, username); + } else { + Secret encodedPwd = (Secret) paramValuePair.getValue(); + if (encodedPwd == null || StringUtils.isBlank(encodedPwd.getPlainText())) { + uftRunAsUser = getRunAsUserWithPassword(paramAction, username); + } else { + paramValuePair = paramAction.getParameter(UFT_RUN_AS_USER_PWD); + if (paramValuePair != null) { + Secret pwd = (Secret) paramValuePair.getValue(); + if (pwd != null && StringUtils.isNotBlank(pwd.getPlainText())) { + throw new IllegalArgumentException(String.format("Please provide either %s or %s, but not both.", UFT_RUN_AS_USER_PWD, UFT_RUN_AS_USER_ENCODED_PWD)); + } + } + uftRunAsUser = new UftRunAsUser(username, encodedPwd.getPlainText()); + } + } + } + } + } + return uftRunAsUser; + } + + private static UftRunAsUser getRunAsUserWithPassword(ParametersAction paramAction, String username) throws IllegalArgumentException { + Secret pwd = getRunAsUserPassword(paramAction); + if (pwd == null || StringUtils.isBlank(pwd.getPlainText())) { + throw new IllegalArgumentException(String.format("Either %s or %s is required.", UFT_RUN_AS_USER_PWD, UFT_RUN_AS_USER_ENCODED_PWD)); + } + return new UftRunAsUser(username, pwd); + } + private static Secret getRunAsUserPassword(ParametersAction paramAction) { + Secret pwd = null; + if (paramAction != null) { + ParameterValue paramValuePair = paramAction.getParameter(UFT_RUN_AS_USER_PWD); + if (paramValuePair != null) { + pwd = (Secret) paramValuePair.getValue(); + } + } + return pwd; + } +} diff --git a/src/main/resources/LR_SCRIPT_REPORT.css b/src/main/resources/LR_SCRIPT_REPORT.css new file mode 100644 index 0000000000..4ed87af43f --- /dev/null +++ b/src/main/resources/LR_SCRIPT_REPORT.css @@ -0,0 +1,218 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +.hl_qt { color: white; font-size: 24pt; font-family: Metric; background-color: #666; text-align: center; padding: 0px 3px 3px } +.hl0 +{ color: #999; font-weight: bold; font-size: 18pt; font-family: Metric; text-align: center; padding: 2px 3px; border-bottom: 3px dotted #999 } +.hl0_name { color: #999; font-weight: normal; font-size: 18pt; font-family: Metric; text-align: center; padding: 2px 3px; border-bottom: 3px dotted #999 } +.hl1 +{ + COLOR: #669; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: bold +} +.hl2 +{ + COLOR: #669; + FONT-FAMILY: Metric; + FONT-SIZE: 13pt; + FONT-WEIGHT: bold +} +.hl3 { color: #666; font-weight: bold; font-size: 10pt; font-family: Metric; height: 28px } +.hl1name +{ + COLOR: #669; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: normal +} +.bg_yellow +{ + BACKGROUND-COLOR: #fc0 +} +.bg_gray_eee +{ + BACKGROUND-COLOR: #eee +} +.bg_gray_ccc { background-color: #ccc } +.bg_gray_999 { background-color: #999 } +.bg_midblue +{ + BACKGROUND-COLOR: #99c +} +.bg_ligtblue +{ + BACKGROUND-COLOR: #ccf +} +.bg_darkblue +{ + BACKGROUND-COLOR: #669 +} +.text +{ font-size: 10pt; font-family: Metric } +.text_small +{ + FONT-FAMILY: Metric; + FONT-SIZE: 8pt +} +.text_pitzi +{ + FONT-FAMILY: Metric; + FONT-SIZE: 6.5pt +} +.text_bold +{ + FONT-FAMILY: Metric; + FONT-WEIGHT: bold +} + + +.Failed +{ + COLOR: #f03; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +.FailedLow +{ + COLOR: #f03; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; +} + +.FailedHigh +{ + COLOR: #f03; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: bold +} +.Passed +{ + COLOR: #096; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +.PassedHigh +{ + COLOR: #096; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: bold +} + +.Done +{ + COLOR: #999; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +.DoneHigh +{ color: #999; font-weight: bold; font-size: 16pt; font-family: Metric } +.Information +{ + COLOR: #999; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +.InformationHigh +{ + COLOR: #999; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: bold +} +.Warning +{ + COLOR: #f96; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +.WarningHigh +{ + COLOR: #f96; + FONT-FAMILY: Metric; + FONT-SIZE: 16pt; + FONT-WEIGHT: bold +} +.tablehl +{ + BACKGROUND-COLOR: #eee; + COLOR: #669; + FONT-FAMILY: Metric; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold; + LINE-HEIGHT: 14pt +} +A +{ + COLOR: #33f; + FONT-FAMILY: Metric +} +A:hover +{ + COLOR: #f03; + FONT-FAMILY: Metric; + FONT-WEIGHT: bold +} +.Condition +{ + COLOR: #333399; + FONT-FAMILY: Metric, sans-serif; + FONT-SIZE: 10pt; + FONT-WEIGHT: bold +} +body { + font-family: Metric, monospace } + + +.tooltiptitle{COLOR: #FFFFFF; TEXT-DECORATION: none; CURSOR: Default; font-family: arial; font-weight: bold; font-size: 8pt} +.tooltipcontent{COLOR: #000000; TEXT-DECORATION: none; CURSOR: Default; font-family: arial; font-size: 8pt} + +#ToolTip{position:absolute; width: 100px; top: 0px; left: 0px; z-index:4; visibility:hidden;} +.brake { font-size: 1px; font-family: Metric; background-color: #366; border-top: 15px solid white; border-bottom: 15px solid white; width: 100%; height: 35px } +.iteration_border { padding-top: 5px; padding-bottom: 5px; padding-left: 10px; border-top: 3px solid #999; border-bottom: 3px solid #999; border-left: 3px solid #999 } +.iteration_head { color: white; font-weight: bold; font-size: 12px; font-family: Metric; background-color: #999; text-align: center; padding: 3px 3px 1px } +.action_border { padding-top: 5px; padding-bottom: 5px; padding-left: 10px; border-top: 3px solid #ccc; border-bottom: 3px solid #ccc; border-left: 3px solid #ccc } +.action_head { color: black; font-weight: bold; font-size: 12px; font-family: Metric; background-color: #ccc; text-align: center; padding: 3px 3px 1px } +.table_frame { padding: 3px; border: solid 1px #669 } +.table_hl { color: #669; font-weight: bold; font-size: 10pt; line-height: 14pt; font-family: Metric; padding-right: 2px; padding-left: 2px; border-top: 1px solid #669; border-bottom: 1px solid #669 } +.table_cell { vertical-align: top; padding: 3px; border-bottom: 1px solid #eee; overflow: visible } +p { font-size: 8pt; font-family: Metric } +td { font-size: 8pt; font-family: Metric } +ul { font-size: 8pt; font-family: Metric } diff --git a/src/main/resources/META-INF/hudson.remoting.ClassFilter b/src/main/resources/META-INF/hudson.remoting.ClassFilter new file mode 100644 index 0000000000..00246cf8fb --- /dev/null +++ b/src/main/resources/META-INF/hudson.remoting.ClassFilter @@ -0,0 +1,37 @@ +# TimeslotDuration class from com.microfocus.adm.performancecenter.plugins.common.pcentities package is safe to be used. +com.microfocus.adm.performancecenter.plugins.common.pcentities.TimeslotDuration +# SimpleDateFormat, DecimalFormat, DateFormatSymbols and DecimalFormatSymbols are native and safe. +java.text.SimpleDateFormat +java.text.DecimalFormat +java.text.DateFormatSymbols +java.text.DecimalFormatSymbols +# com.hp.octane.integrations.uft.items.* are safe to be used , The items are taken from Octane sdk for ci servers. +com.hp.octane.integrations.uft.items.UftTestDiscoveryResult +com.hp.octane.integrations.uft.items.AutomatedTest +com.hp.octane.integrations.uft.items.UftTestAction +com.hp.octane.integrations.uft.items.UftTestParameter +com.hp.octane.integrations.uft.items.ScmResourceFile +# com.hp.octane.integrations.dto.scm.* are safe to be used , The items are taken from Octane sdk for ci servers. +com.hp.octane.integrations.dto.scm.impl.LineRange +com.hp.octane.integrations.dto.scm.impl.RevisionsMap +com.hp.octane.integrations.dto.scm.impl.SCMChangeImpl +com.hp.octane.integrations.dto.scm.impl.SCMCommitImpl +com.hp.octane.integrations.dto.scm.impl.SCMDataImpl +com.hp.octane.integrations.dto.scm.impl.SCMFileBlameImpl +com.hp.octane.integrations.dto.scm.impl.SCMRepositoryImpl +com.hp.octane.integrations.dto.scm.impl.PullRequestImpl +com.hp.octane.integrations.dto.scm.impl.BranchImpl +com.hp.octane.integrations.services.pullrequestsandbranches.BranchSyncResult +com.hp.octane.integrations.executor.converters.MbtTest +com.hp.octane.integrations.executor.converters.MbtUftTest +com.hp.octane.integrations.executor.converters.MbtCodelessTest +com.hp.octane.integrations.executor.converters.MbtCodelessUnit +com.hp.octane.integrations.dto.general.impl.MbtDataTableImpl +com.hp.octane.integrations.dto.general.impl.MbtUnitParameterImpl +com.hp.octane.integrations.executor.TestsToRunConverterResult +com.hp.octane.integrations.executor.TestToRunData +com.hp.octane.integrations.executor.TestsToRunFramework +com.hp.octane.integrations.executor.TestsToRunConverter +com.hp.octane.integrations.uft.ufttestresults.schema.UftResultIterationData +com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepData +com.hp.octane.integrations.uft.ufttestresults.schema.UftResultStepParameter diff --git a/src/main/resources/PDetails.xsl b/src/main/resources/PDetails.xsl new file mode 100644 index 0000000000..0be7b8822e --- /dev/null +++ b/src/main/resources/PDetails.xsl @@ -0,0 +1,970 @@ + + + + + + + +Business Process Test: +Business Component: +Test: +Input Parameters +Value +Output Parameters +Step Name: +Object +Details +Result +Time + Results Summary +Action: +Run started: +Run ended: +Result: +Status +Times +Passed +Failed +Warning +Done +Warnings +Iteration +Object +Details +Result +Time +Results name : +Time Zone: +Test version: +Test set: +Test instance: +Iteration # +Results + Report +Test Iteration +Name +End: +Business Component +Step +Product name: + Summary: + + + + + + + <xsl:value-of select="Report/General/@productName"/><xsl:copy-of select="$IDS_REPORT"/> + + + +
+ + + + + + + +
+
+
+ + +

+
+ +

+
+ +

+
+
+
+
+ + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + High + + + +
+

+ + + + +
+ + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ +
+
+
+ + + + +
+
+
+
+
+
+ + + + +
+ + + + +
+ + + +
+
+ +
+
+
+ + + + + +
+ + + + + + + + + + + + +
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + + +
+

+
+

+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+

+ +

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
+ + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + +
+

+


+

+

+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+ + + + + +
+
+ + + + + + + + + + + + +
+ (Iteration ) +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + +

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+
+ +

+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +


+ + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+
+ +

+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
+ + + + + +
+ + + + + + + + + + + +
+
+ +
+ diff --git a/src/main/resources/com/hp/application/automation/tools/model/AutEnvironmentModel/config.jelly b/src/main/resources/com/hp/application/automation/tools/model/AutEnvironmentModel/config.jelly deleted file mode 100644 index f2ab0474a8..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/model/AutEnvironmentModel/config.jelly +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - -
- ${%AlmServersAreNotDefined} -
- - - -
- - - -
- ${%AutEnvironmentConfigurationDescription} -
- - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - -
- - - - - - - - - - - - - -
diff --git a/src/main/resources/com/hp/application/automation/tools/octane/configuration/ConfigurationAction/index.properties b/src/main/resources/com/hp/application/automation/tools/octane/configuration/ConfigurationAction/index.properties deleted file mode 100644 index c58970c4c8..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/octane/configuration/ConfigurationAction/index.properties +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright 2017 Hewlett-Packard Development Company, L.P. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. -# -# - -mqm.configuration.title=HPE ALM Octane Pipelines \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly deleted file mode 100644 index 9ba6a5c82b..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties deleted file mode 100644 index 4120a7a12c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties +++ /dev/null @@ -1,3 +0,0 @@ -DontForgetThePublisher=Make sure to enable the Publish HP \ - tests result option in the Post-build \ - Actions section. This allows the tests results to be published. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html deleted file mode 100644 index b1cc1dd440..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html +++ /dev/null @@ -1,8 +0,0 @@ -
-To view the run results, do one of the following:
-1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
-2) From the Build Artifacts:
-• Open the run_results.html to view the run results.
-• Download the zipped report to your desired location and unzip it. In the HP Run Results Viewer, select the Results.xml file found inside the unzipped folder.
-Note that this option is valid only when using the “Execute HP test from file system” build step. -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html deleted file mode 100644 index a8a458b9c4..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Polling interval for checking the scenario status, in seconds. The default is 30 seconds. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html deleted file mode 100644 index 79957d5a2a..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html +++ /dev/null @@ -1,3 +0,0 @@ -
-List of tests or folders that contain tests, to run. Each line should contain a single test, folder, or MTB file. -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html deleted file mode 100644 index 1c75aa980d..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Timeout value in seconds. If left empty, there is no timeout. -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html deleted file mode 100644 index 26aa824b24..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Ignore errors during the scenario run containing any of the strings listed below. For example: "Error: CPU usage for this load generator has exceeded 80%" -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html deleted file mode 100644 index f4939d5fbc..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The maximum time allotted for scenario execution, in minutes. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly deleted file mode 100644 index d9e6014ea3..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - -
- ${%AlmServersAreNotDefined} -
- - - -
- - - - -
- ${%ServerSideTests} -
- - - - - - -
- ${%DontForgetThePublisher} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties deleted file mode 100644 index c1d0f841fa..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties +++ /dev/null @@ -1,7 +0,0 @@ -DontForgetThePublisher=Don''t forget to enable the Publish HP \ - tests result option in the Post-build \ - Actions section so that the tests results are published. - -AlmServersAreNotDefined=HP ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server - -ServerSideTests=Use this build step to run ALM server-side functional test sets and Build Verification Suites. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html deleted file mode 100644 index b1cc1dd440..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html +++ /dev/null @@ -1,8 +0,0 @@ -
-To view the run results, do one of the following:
-1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
-2) From the Build Artifacts:
-• Open the run_results.html to view the run results.
-• Download the zipped report to your desired location and unzip it. In the HP Run Results Viewer, select the Results.xml file found inside the unzipped folder.
-Note that this option is valid only when using the “Execute HP test from file system” build step. -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html deleted file mode 100644 index 81369fbdbf..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html +++ /dev/null @@ -1,3 +0,0 @@ -
-To find the ID of your environment configuration, right-click the entity, copy the URL, and paste it to a text editor. Use the number associated with the EntityID at the end of the URL. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly deleted file mode 100644 index c1c1648d2f..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties deleted file mode 100644 index 4120a7a12c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties +++ /dev/null @@ -1,3 +0,0 @@ -DontForgetThePublisher=Make sure to enable the Publish HP \ - tests result option in the Post-build \ - Actions section. This allows the tests results to be published. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html deleted file mode 100644 index b1cc1dd440..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html +++ /dev/null @@ -1,8 +0,0 @@ -
-To view the run results, do one of the following:
-1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
-2) From the Build Artifacts:
-• Open the run_results.html to view the run results.
-• Download the zipped report to your desired location and unzip it. In the HP Run Results Viewer, select the Results.xml file found inside the unzipped folder.
-Note that this option is valid only when using the “Execute HP test from file system” build step. -
diff --git a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html b/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html deleted file mode 100644 index 79957d5a2a..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html +++ /dev/null @@ -1,3 +0,0 @@ -
-List of tests or folders that contain tests, to run. Each line should contain a single test, folder, or MTB file. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/DetailReport/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/DetailReport/index.jelly deleted file mode 100644 index febb67cafd..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/DetailReport/index.jelly +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - -

LoadRunner Performance Result

-

${it.name}

- -
-
-
- - diff --git a/src/main/resources/com/hp/application/automation/tools/results/HtmlBuildReportAction/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/HtmlBuildReportAction/index.jelly deleted file mode 100644 index a8bdfcdf58..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/HtmlBuildReportAction/index.jelly +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - -

UFT Report

-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeReport nameTimestampStatusFolder
Html_report${s.disPlayName}RRV_report${s.disPlayName}${s.dateTime}PassedFailedOpen
-

-
- -
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/PerformanceJobReportAction/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/PerformanceJobReportAction/index.jelly deleted file mode 100644 index 2a388ae35c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/PerformanceJobReportAction/index.jelly +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -

Job Performance Result

- -
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/PerformanceProjectAction/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/PerformanceProjectAction/index.jelly deleted file mode 100644 index 3567f984ec..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/PerformanceProjectAction/index.jelly +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- PERFORMANCE TESTS SUMMARY REPORT - -
-
- -
-
-
- - -
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/PerformanceReportAction/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/PerformanceReportAction/index.jelly deleted file mode 100644 index b4261d6134..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/PerformanceReportAction/index.jelly +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -

LoadRunner Performance Result

- - - - - - - - - - - - - - - ${c.printFourCoverageColumns()} - - -
NameDurationPassFail
- ${c.getName()} - - ${c.getDuration()} - - ${c.getPass()} - - ${c.getFail()} -
- - -
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/config.jelly b/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/config.jelly deleted file mode 100644 index ffa465c323..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/config.jelly +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - diff --git a/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html b/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html deleted file mode 100644 index b1cc1dd440..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html +++ /dev/null @@ -1,8 +0,0 @@ -
-To view the run results, do one of the following:
-1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
-2) From the Build Artifacts:
-• Open the run_results.html to view the run results.
-• Download the zipped report to your desired location and unzip it. In the HP Run Results Viewer, select the Results.xml file found inside the unzipped folder.
-Note that this option is valid only when using the “Execute HP test from file system” build step. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/SummaryReport/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/SummaryReport/index.jelly deleted file mode 100644 index d74e036231..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/SummaryReport/index.jelly +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -

Transaction Summary

-

${it.name}

- -
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.jelly b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.jelly deleted file mode 100644 index 3053884a9c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.jelly +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - -
- ${%AlmServersAreNotDefined} -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.properties b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.properties deleted file mode 100644 index 446a560a52..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/config.properties +++ /dev/null @@ -1,3 +0,0 @@ - - -AlmServersAreNotDefined=HP ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html deleted file mode 100644 index 453ae79ea3..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The Domain of the project to be used. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html deleted file mode 100644 index 0c39d54640..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The password for the user to login. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almProject.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almProject.html deleted file mode 100644 index ab3aca1929..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almProject.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The project to be used. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html deleted file mode 100644 index 7aff86d155..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The name of the ALM Server. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html deleted file mode 100644 index 73790e7d60..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html +++ /dev/null @@ -1,5 +0,0 @@ -
-The path of the test folder that will contain the uploaded test. The path doesn't include the Root test folder (Subject).
-For example, sampletestfolder\subfolder means, the tests will be uploaded to test folder named 'subfolder', which is under the test folder named 'sampletestfolder',
-and 'sampletestfolder' is under the root test folder 'Subject'. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html deleted file mode 100644 index e80af12f0c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html +++ /dev/null @@ -1,5 +0,0 @@ -
-The path of the testset folder that will contain the uploaded testset. The path doesn't include the Root testset folder.
-For example, sampletestsetfolder\subfolder means, the testsets will be uploaded to testset folder named 'subfolder', which is under the testset folder named 'sampletestsetfolder',
-and 'sampletestsetfolder' is under the root testset folder 'Root'. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html deleted file mode 100644 index c06ddb4f4d..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Number of seconds before timeout. If left empty timeout is unlimited. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html deleted file mode 100644 index 6dbb8f782d..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The user name to login. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html deleted file mode 100644 index cdf7c7b2ea..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The HTTP URL of the Jenkins Server, form example, http://myjenkinsserver.test.com:8080 . -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html deleted file mode 100644 index 48c18a63ac..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The testing framework that is used when generate the testing result file. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html deleted file mode 100644 index 1da46d44ae..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The condition to find the testing result file, start from the root path of the job. For example, **/junitResult.xml to find testing result file for Junit Plugin, **/testng-results.xml to find testing result file for TestNG plugin. -
diff --git a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html b/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html deleted file mode 100644 index 5e6326937e..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html +++ /dev/null @@ -1,3 +0,0 @@ -
-The testing tool that is used when generate the testing result file. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/results/TransactionSummaryAction/index.jelly b/src/main/resources/com/hp/application/automation/tools/results/TransactionSummaryAction/index.jelly deleted file mode 100644 index fa3e1be6af..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/results/TransactionSummaryAction/index.jelly +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -

Transaction Summary

- - - - - - - - - - - - - - - ${c.printFourCoverageColumns()} - - -
NameDurationPassFail
- ${c.getName()} - - ${c.getDuration()} - - ${c.getPass()} - - ${c.getFail()} -
- - -
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.jelly b/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.jelly deleted file mode 100644 index 84cec299e3..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.jelly +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.properties b/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.properties deleted file mode 100644 index a2ddef04e7..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/config.properties +++ /dev/null @@ -1,3 +0,0 @@ -AlmServersAreNotDefined=HP ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server - -AutEnvironmentConfigurationDescription=Use this build step to assign values to AUT Environment Configuration in ALM. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html b/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html deleted file mode 100644 index 81369fbdbf..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html +++ /dev/null @@ -1,3 +0,0 @@ -
-To find the ID of your environment configuration, right-click the entity, copy the URL, and paste it to a text editor. Use the number associated with the EntityID at the end of the URL. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.jelly b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.jelly deleted file mode 100644 index e9211d4684..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.jelly +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - - - - - -
- ${%DontForgetThePublisher} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - -
- - -
- -
- - - - -
- - - - - - - - - - - - - - - - - -
- Timeslot Duration - - Hours  - - - - - -   Minutes  - - - - - - (Minimum: 30 minutes) -
- - - -
-
-
- - - -
-
- - - -
diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.properties b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.properties deleted file mode 100644 index fe6b5092a7..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/config.properties +++ /dev/null @@ -1,3 +0,0 @@ -DontForgetThePublisher=Don''t forget to enable the Publish HP \ - tests result option in the Post-build \ - Actions section so that the tests results are published. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-pcServerName.html b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-pcServerName.html deleted file mode 100644 index 921e0a4456..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-pcServerName.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Hostname or IP address -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-statusBySLA.html b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-statusBySLA.html deleted file mode 100644 index 059a8bf3d9..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-statusBySLA.html +++ /dev/null @@ -1,4 +0,0 @@ -
-Check this option in order to set the build-step status according to a pre-defined SLA (Service Level Agreement) configured within your performance test. -Unless checked, the build-step will be labeled as Passed as long as no failures occurred. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-testInstanceId.html b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-testInstanceId.html deleted file mode 100644 index 74b5101553..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-testInstanceId.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Represents an instance of a performance test within an ALM Test Set. In order to find the test instance id go to: PC Web UI > Test Lab perspective > Performance Test Set table and look for the ID column -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-vudsMode.html b/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-vudsMode.html deleted file mode 100644 index 8200fae602..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/PcBuilder/help-vudsMode.html +++ /dev/null @@ -1,4 +0,0 @@ -
-A Virtual User Day (VUD) license provides you with a specified number of Vusers (VUDs) that you can run an unlimited number of times within a 24 hour period. -Before using this option, make sure that VUDs licenses are applied in your HP Performance Center environment. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.jelly b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.jelly deleted file mode 100644 index 816c52ce9c..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.jelly +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - -
- ${%AlmServersAreNotDefined} -
- - - -
- - - - -
- ${%DontForgetThePublisher} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.properties b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.properties deleted file mode 100644 index da813a9bdd..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/config.properties +++ /dev/null @@ -1,5 +0,0 @@ -DontForgetThePublisher=Don''t forget to enable the Publish HP \ - tests result option in the Post-build \ - Actions section so that the tests results are published. - -AlmServersAreNotDefined=HP ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunHost.html b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunHost.html deleted file mode 100644 index 7c3782d972..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunHost.html +++ /dev/null @@ -1,3 +0,0 @@ -
-If the Run mode field is set to Run remotely, use this field to specify the name of the host that runs the test set. -
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunMode.html b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunMode.html deleted file mode 100644 index b4bffb4ff7..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmRunMode.html +++ /dev/null @@ -1,8 +0,0 @@ -
-Defines how the test set is executed: -
    -
  • Run locally: The test set is run on the machine that performs the build.
  • -
  • Run remotely: The test set is run on the host defined in the Testing Tool host field.
  • -
  • Run on planned host: The test set is run on the host defined in ALM.
  • -
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTestSets.html b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTestSets.html deleted file mode 100644 index c447b8c757..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTestSets.html +++ /dev/null @@ -1,4 +0,0 @@ -
-List of test sets to run. Each line contains a path to a test set or a test set folder.
-For example: Root\subFolder1\subFolder2\testSetToRun -
diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTimeout.html b/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTimeout.html deleted file mode 100644 index c06ddb4f4d..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromAlmBuilder/help-AlmTimeout.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Number of seconds before timeout. If left empty timeout is unlimited. -
diff --git a/src/main/resources/com/hp/application/automation/tools/run/RunFromFileBuilder/config.jelly b/src/main/resources/com/hp/application/automation/tools/run/RunFromFileBuilder/config.jelly deleted file mode 100644 index 9e217d3f42..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/RunFromFileBuilder/config.jelly +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - -
- ${%DontForgetThePublisher} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/run/UploadAppBuilder/config.properties b/src/main/resources/com/hp/application/automation/tools/run/UploadAppBuilder/config.properties deleted file mode 100644 index 948e7777e2..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/run/UploadAppBuilder/config.properties +++ /dev/null @@ -1 +0,0 @@ -McServersAreNotDefined=HP MC servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Mobile Center->Add MC server \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/global.jelly b/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/global.jelly deleted file mode 100644 index 0a642c13d0..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/global.jelly +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
- - - diff --git a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerName.html b/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerName.html deleted file mode 100644 index ffb2288c6d..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerName.html +++ /dev/null @@ -1,3 +0,0 @@ -
- The name of the ALM Server. This will be used in the "Execute HP functional test from ALM" build step configuration. -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerUrl.html b/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerUrl.html deleted file mode 100644 index 709f70945e..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerUrl.html +++ /dev/null @@ -1,3 +0,0 @@ -
- The name of the URL of the ALM Server: http://myalmserver:8080/qcbin -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerVersion.html b/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerVersion.html deleted file mode 100644 index af27a5a3d6..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/AlmServerSettingsBuilder/help-almServerVersion.html +++ /dev/null @@ -1,3 +0,0 @@ -
- The version of the ALM server:10.0, 11.0, 11.5 -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/global.jelly b/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/global.jelly deleted file mode 100644 index c8382c47a2..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/global.jelly +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
- - - diff --git a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerName.html b/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerName.html deleted file mode 100644 index 9140170424..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerName.html +++ /dev/null @@ -1,3 +0,0 @@ -
- The name of the MC Server. -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerUrl.html b/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerUrl.html deleted file mode 100644 index b7f686435e..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/MCServerSettingsBuilder/help-mcServerUrl.html +++ /dev/null @@ -1,3 +0,0 @@ -
- The Mobile Center host. i.e: http://mcserver:8080 -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.jelly b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.jelly deleted file mode 100644 index 4640bf2385..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.jelly +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.properties b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.properties deleted file mode 100644 index db84c07ff0..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/global.properties +++ /dev/null @@ -1,20 +0,0 @@ -global.config.description=HPE ALM Octane CI Plugin -global.config.server.title=HPE ALM Octane Server Configuration -global.config.location.title=Location -global.config.location.description=Location of the HPE ALM Octane application -global.config.domain.title=Domain -global.config.domain.description=Domain name -global.config.project.title=Project -global.config.project.description=Project name -global.config.username.title=Client ID -global.config.username.description=Client ID used for logging into the ALM Octane server -global.config.password.title=Client secret -global.config.password.description=Client secret used for logging into the ALM Octane server -global.config.test.connection=Test Connection -global.config.test.connection.progress=Connecting the ALM Octane server... -global.config.impersonatedUser.title=Jenkins user -global.config.impersonatedUser.description=The user to impersonate (Jobs will be executed on behalf of this user) - -global.config.dynamic.instanceId.title=Show plugin instance id -global.config.instanceId.title=Instance id -global.config.instanceId.description=An ID to uniquely identify this instance of the plugin. \ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-identity.html b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-identity.html deleted file mode 100644 index 5db67cbd3e..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-identity.html +++ /dev/null @@ -1,9 +0,0 @@ -
- In ALM Octane, a pipeline’s unique identification includes this ID.
- When should I change this value?
-
    -
  • When you install the HP Application Automation Tools plugin instead of the HPE ALM Octane CI plugin. To enable this plugin to work with existing pipelines, change the instance ID to the one used by your pipelines in ALM Octane (Settings > DevOps > CI servers, “Instance ID” column).
  • -
    -
  • If you duplicate your Jenkins installation. Change the instance ID (in any way) to prevent results reported from the new copy of the plugin from being mixed in ALM Octane with results reported from the original one.
    To separately collect information from the new copy, create new pipelines.
  • -
-
\ No newline at end of file diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-impersonatedUser.html b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-impersonatedUser.html deleted file mode 100644 index 852b3ae2c7..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-impersonatedUser.html +++ /dev/null @@ -1,15 +0,0 @@ -
-The Jenkins user's account is used to run jobs that ALM Octane runs.

- Notes: -
    -
  • - Make sure the user exists in Jenkins. -
  • -
  • - We strongly recommend specifying a Jenkins user for ALM Octane. Set this user's permissions to the minimum required for this integration: Job Build permissions. -
  • -
  • - If you do not specify a Jenkins user, ALM Octane uses the Anonymous user, and is limited to Anonymous's user permissions. -
  • -
-
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-uiLocation.html b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-uiLocation.html deleted file mode 100644 index bbb0799742..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-uiLocation.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Login into the ALM Octane application and copy & paste the location from your browser. -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-username.html b/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-username.html deleted file mode 100644 index cf2a1ee0ed..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/OctaneServerSettingsBuilder/help-username.html +++ /dev/null @@ -1,3 +0,0 @@ -
-Obtain a Client ID and Client secret from ALM Octane configuration. -
diff --git a/src/main/resources/com/hp/application/automation/tools/settings/SvServerSettingsBuilder/global.jelly b/src/main/resources/com/hp/application/automation/tools/settings/SvServerSettingsBuilder/global.jelly deleted file mode 100644 index baf6d21579..0000000000 --- a/src/main/resources/com/hp/application/automation/tools/settings/SvServerSettingsBuilder/global.jelly +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
- - - diff --git a/src/main/resources/com/microfocus/application/automation/tools/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/Messages.properties new file mode 100644 index 0000000000..9d596f4d0e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/Messages.properties @@ -0,0 +1,39 @@ +# +# 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. +# ___________________________________________________________________ +# + +CompanyName=OpenText +RunFromAlmBuilderStepName=Execute {0} functional tests from {0} ALM +SseBuilderStepName=Execute {0} tests using {0} ALM Lab Management +AutEnvironmentBuilderStepName=Execute AUT Environment preparation using {0} ALM Lab Management +RunFromFileBuilderStepName=Execute {0} tests from file system +RunFromCodelessBuilderStepName=Execute {0} codeless tests +CommonResultUploadBuilderName=Upload test result to ALM using field mapping \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/common/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/common/Messages.properties new file mode 100644 index 0000000000..70df074050 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/common/Messages.properties @@ -0,0 +1,43 @@ +# +# 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. +# ___________________________________________________________________ +# + +HealthAnalyzerBuilder.displayName={0} Health Analyzer +HealthAnalyzerCommon.productNameValueMustBeNotNull=The product name value cannot be null. +HealthAnalyzerCommon.registryValueMustBeNotNull=The registry value cannot be null. +HealthAnalyzerCommon.urlMustBeNotNull=The URL cannot be null. +HealthAnalyzerCommon.notInstalled={0} is not installed. Please install it first. +HealthAnalyzerCommon.registryWorksOnlyOnWindows=Registry existence is only supported on Windows. +HealthAnalyzerCommon.serverUrlNotExist=The server URL, {0} does not exist. +HealthAnalyzerCommon.malformedUrl=The URL {0} is malformed. Either no legal protocol was found in the specified string or the string could not be parsed. +HealthAnalyzerCommon.isDirectory={0} is a directory and not a file. +HealthAnalyzerCommon.fileNotExist=The file in the path {0} does not exist. +HealthAnalyzerCommon.operatingSystemIncorrect=Your operating system is not {0}. \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/common/model/VariableWrapper/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/common/model/VariableWrapper/config.jelly new file mode 100644 index 0000000000..7ae3fefd5d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/common/model/VariableWrapper/config.jelly @@ -0,0 +1,45 @@ + + + + + + + + + +
+ + +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.jelly new file mode 100644 index 0000000000..a38fb52e97 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.jelly @@ -0,0 +1,43 @@ + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.properties new file mode 100644 index 0000000000..25ea045c8b --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/config.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +addCaption=Add new product diff --git a/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/help-products.html b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/help-products.html new file mode 100644 index 0000000000..6f9715a319 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/common/run/HealthAnalyzerBuilder/help-products.html @@ -0,0 +1,36 @@ + + + +
+ Choose the products that you would like to test that correspond to the relevant build step. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.jelly new file mode 100644 index 0000000000..16171ac1f8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.jelly @@ -0,0 +1,99 @@ + + + + + + + + + +
+ ${%AlmServersAreNotDefined} +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.properties new file mode 100644 index 0000000000..3c670aebcd --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/config.properties @@ -0,0 +1,35 @@ +# +# 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. +# ___________________________________________________________________ +# + + + +AlmServersAreNotDefined=ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almDomain.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almDomain.html new file mode 100644 index 0000000000..965d25029c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almDomain.html @@ -0,0 +1,35 @@ + + +
+The Domain of the project to be used. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almPassword.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almPassword.html new file mode 100644 index 0000000000..56ab5dbc69 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almPassword.html @@ -0,0 +1,35 @@ + + +
+The password for the user to login. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almProject.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almProject.html new file mode 100644 index 0000000000..ee281117a5 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almProject.html @@ -0,0 +1,35 @@ + + +
+The project to be used. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almServerName.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almServerName.html new file mode 100644 index 0000000000..c9456578a0 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almServerName.html @@ -0,0 +1,35 @@ + + +
+The name of the ALM Server. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestFolder.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestFolder.html new file mode 100644 index 0000000000..f489fb7a07 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestFolder.html @@ -0,0 +1,37 @@ + + +
+The path of the test folder that will contain the uploaded test. The path doesn't include the Root test folder (Subject).
+For example, sampletestfolder\subfolder means, the tests will be uploaded to test folder named 'subfolder', which is under the test folder named 'sampletestfolder',
+and 'sampletestfolder' is under the root test folder 'Subject'. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestSetFolder.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestSetFolder.html new file mode 100644 index 0000000000..709818fe4f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almTestSetFolder.html @@ -0,0 +1,37 @@ + + +
+The path of the testset folder that will contain the uploaded testset. The path doesn't include the Root testset folder.
+For example, sampletestsetfolder\subfolder means, the testsets will be uploaded to testset folder named 'subfolder', which is under the testset folder named 'sampletestsetfolder',
+and 'sampletestsetfolder' is under the root testset folder 'Root'. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almUserName.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almUserName.html new file mode 100644 index 0000000000..259346170d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-almUserName.html @@ -0,0 +1,35 @@ + + +
+The user name to login. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-clientType.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-clientType.html new file mode 100644 index 0000000000..ba5e43e9a8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-clientType.html @@ -0,0 +1,35 @@ + + +
+Client type is required for some ALM above 12.60 in authentication. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-createNewTest.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-createNewTest.html new file mode 100644 index 0000000000..67388a1f7f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-createNewTest.html @@ -0,0 +1,37 @@ + + +
+ Check: Create tests and related test-instances and runs when no test is found by the specified fields(name by default or can be specified as id). +
Uncheck: Don't create test and related test-instances and runs when no test is found by the specified fields. +
Note: Tests will not be updated when they're found by the specified fields. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-fieldMapping.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-fieldMapping.html new file mode 100644 index 0000000000..50d273002e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-fieldMapping.html @@ -0,0 +1,89 @@ + + +
+

Field mapping content is a yaml format configuration. Three sections are required. They are 'testset', 'test' and 'run'. + Each section should has a 'root' property indicates the root node of the testset or test or run. Please note that test's root is based on testset's root. Run's root is based on test's root.

+

Beside root, you can define any field you want to upload as an ALM entity. Yaml key represents the entity's field name. Yaml value represents the entity's field value.

+

If you want to upload a value to a User defined field, you could use a key starts with 'udf|' follows by the UDF label. Such as 'udf-duration' would upload value to a UDF field which has label as 'duration'.

+

For the yaml value part, there're two types of value. Value starts with 'x:' means the following value represents the xpath in the test result file. Value starts with 'v:' means the following value is a string value which would be applied to every entity.

+

You can use '|' in yame value for combining several parts together.

+ + Sample test result: + <?xml version='1.0' encoding='UTF-8'?> + <result> + <suites> + <suite> + <file>Changes file</file> + <name>Changes Test Set 1</name> + <duration>2.293</duration> + <cases> + <case> + <duration>8.293</duration> + <className>ChangesManagement</className> + <testName>test1</testName> + <testVersion>4.0</testVersion> + <skipped>false</skipped> + <failedSince>0</failedSince> + </case> + <case> + <duration>8.293</duration> + <className>ChangesManagement</className> + <testName>List changes 2</testName> + <testVersion>4.0</testVersion> + <skipped>false</skipped> + <failedSince>0</failedSince> + </case> + </cases> + </suite> + <duration>0.576</duration> + </result> + + Sample field mapping: + +testset: + root: "x:/result/suites/suite" + name: "x:file|v:_|x:name" + udf|duration: "x:duration" + subtype-id: "v:hp.qc.test-set.external" +test: + root: "x:cases/case" + name: "x:testName" + subtype-id: "v:EXTERNAL-TEST" + udf|duration: "x:duration" + udf|test version: "x:testVersion" +run: + root: "x:." + duration: "x:duration" + status: "x:failedSince" + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-runStatusMapping.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-runStatusMapping.html new file mode 100644 index 0000000000..fa8e5bb164 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-runStatusMapping.html @@ -0,0 +1,88 @@ + + +
+

Run status mapping field is for mapping the test result's status values to ALM run status value. + Yaml key represents the ALM run status values. Only one of the following status can be set here:
+ Passed
+ Failed
+ Yaml value represents the condition that sustains the status. Ten kinds of conditions can be set here:
+ ==StringValue
+ !=StringValue
+ + ==0 (Or any numeric value)
+ !=0 (Or any numeric value)
+ + >>0 (Or any numeric value)
+ <<0 (Or any numeric value)
+ + <=0 (Or any numeric value)
+ >=0 (Or any numeric value)
+ + ==NULL
+ !=NULL
+ + You should first set the status field in field mapping.
+

+ + +Take following test result as example: +<test-case name="ExampleTestOfNUnit.TestMultiplicationFail" executed="True" result="Failure" success="False" time="0.122" asserts="1"> + + +Sample field mapping: +run: + status: "x: success" + +Sample status mapping: +status: + Passed: "==true" + + + +Take following test result as example: +<case> + <duration>0.041</duration> + <className>SomeClass</className> + <testName>SomeTest-1</testName> + <skipped>false</skipped> + <failedSince>0</failedSince> +</case> + + Sample field mapping: + run: + status: "x: failedSince" + Sample status mapping: + status: + Failed: ">=0" + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-testingResultFile.html b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-testingResultFile.html new file mode 100644 index 0000000000..1ffb897856 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/commonResultUpload/CommonResultUploadBuilder/help-testingResultFile.html @@ -0,0 +1,35 @@ + + +
+setting that specifies the generated raw XML report files, such as **/junitResult.xml. Basedir of the fileset is the root path of current job and workspace. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/lr/Messages.properties new file mode 100644 index 0000000000..4d9f9d899d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/Messages.properties @@ -0,0 +1,37 @@ +# +# 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. +# ___________________________________________________________________ +# + +ProductName=LoadRunner +SummaryDataLogModel=Summary Data Log Model +ScriptRTSSetModel=Script RTS Set Model +ScriptRTSModel=Script RTS Model +AdditionalAttributeModel=Additional Attribute Model \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.jelly new file mode 100644 index 0000000000..d4a6392ee9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.jelly @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.properties b/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.properties new file mode 100644 index 0000000000..cd1dfe26b6 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/AdditionalAttributeModel/config.properties @@ -0,0 +1,34 @@ +# +# 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. +# ___________________________________________________________________ +# +Name=Name +Value=Value +Description=Description (Optional) \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.jelly new file mode 100644 index 0000000000..77c04e5083 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.jelly @@ -0,0 +1,43 @@ + + + + +

Script

+ + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.properties b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.properties new file mode 100644 index 0000000000..fbe6523c8b --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/config.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +ScriptName=Script Name diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/help-scriptName.html b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/help-scriptName.html new file mode 100644 index 0000000000..6dada88a20 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSModel/help-scriptName.html @@ -0,0 +1,35 @@ + + +
+ The script name is found in Controller's Script Information dialog (Percentage Mode scenario) or Group Information dialog (Vuser Group Mode scenario). +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel/config.jelly new file mode 100644 index 0000000000..1d1f08f1ca --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/ScriptRTSSetModel/config.jelly @@ -0,0 +1,37 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.jelly new file mode 100644 index 0000000000..8486110a50 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.jelly @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.properties b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.properties new file mode 100644 index 0000000000..89b9fcfdd2 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/config.properties @@ -0,0 +1,36 @@ +# +# 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. +# ___________________________________________________________________ +# + +PollingInterval=Polling Interval +LogVusersStates=Log Vusers States +LogErrorCount=Log Error Count +LogTransactionStatistics=Log Transaction Statistics \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logErrorCount.html b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logErrorCount.html new file mode 100644 index 0000000000..cb80ba77ab --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logErrorCount.html @@ -0,0 +1,35 @@ + + +
+ Display the number of controller errors. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logTransactionStatistics.html b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logTransactionStatistics.html new file mode 100644 index 0000000000..b47328b1a6 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logTransactionStatistics.html @@ -0,0 +1,35 @@ + + +
+ Display the number of passed transactions, failed transactions and hits per second. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logVusersStates.html b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logVusersStates.html new file mode 100644 index 0000000000..0cb644c58c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-logVusersStates.html @@ -0,0 +1,35 @@ + + +
+ Display the number of virtual users in each state. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-pollingInterval.html b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-pollingInterval.html new file mode 100644 index 0000000000..d7d54aa5e8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/model/SummaryDataLogModel/help-pollingInterval.html @@ -0,0 +1,35 @@ + + +
+ The rate at which the messages are displayed (in seconds). Default value is 10 seconds. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.jelly new file mode 100644 index 0000000000..44d834eec6 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.jelly @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.properties b/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.properties new file mode 100644 index 0000000000..2b52c58368 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/lr/run/HealthAnalyzerLrStep/config.properties @@ -0,0 +1,35 @@ +# +# 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. +# ___________________________________________________________________ +# + +checkIfLrInstalled=Check if LoadRunner is installed +checkIfSlaveIsWindows=Check if the slave is a Windows machine +checkIfScenarioFilesExist=Check if scenario files exist \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/mc/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/mc/Messages.properties new file mode 100644 index 0000000000..3b1d572ae5 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/mc/Messages.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +ProductName=Digital Lab diff --git a/src/main/resources/com/microfocus/application/automation/tools/model/AutEnvironmentModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/model/AutEnvironmentModel/config.jelly new file mode 100644 index 0000000000..164c4a9ab7 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/model/AutEnvironmentModel/config.jelly @@ -0,0 +1,161 @@ + + + + + + + + + +
+ ${%AlmServersAreNotDefined} +
+ + + +
+ + + +
+ ${%AutEnvironmentConfigurationDescription} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction/index.properties b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction/index.properties new file mode 100644 index 0000000000..50e8e4a9db --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationAction/index.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +mqm.configuration.title=ALM Octane Pipelines \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.jelly new file mode 100644 index 0000000000..d0d8de0705 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.jelly @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + +
+ + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.properties b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.properties new file mode 100644 index 0000000000..f5ba7cb979 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionMultibranch/index.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +mqm.configuration.multibranch.title=ALM Octane Pipelines \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/config.jelly new file mode 100644 index 0000000000..da8a7f8b2f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/config.jelly @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/help.html b/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/help.html new file mode 100644 index 0000000000..0ea878925d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/octaneExecution/ExecuteTestsInOctaneBuilder/help.html @@ -0,0 +1,73 @@ + + +
+ This build step is intended to support execution of automated tests from ALM Octane.
+ There are several modes of execution : + + + + + + + + + + + + + + + + + + + + +
ModeExplanation
Execute suite runs in ALM OctaneExecute suites according to specified suite IDs. New suite runs will be created and executed in ALM Octane. + Jenkins job is finished after triggering the suite runs. The job does not wait + until the suite runs are finished. This method is useful if you want to schedule suite execution in ALM + Octane. +
+ By default, newly created suite runs will have name of suite and will be assigned to default release. + In order to override this default behaviour, add following parameters (one or more) to job with your desired values: +
    +
  • octane_release_id
  • +
  • octane_new_suite_run_name
  • +
+
Get tests from suites and trigger execution jobsGet tests from suites and trigger execution jobs : Get tests from specified suite IDs. (This method + assumes that tests are assigned to test runner jobs from the current Jenkins.) Tests are send to + execution by their assigned test runner jobs. The main job is finished after the test runner jobs are + finished. + This method is useful if you intend to add your job to the ALM Octane Pipeline module. +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction/index.jelly new file mode 100644 index 0000000000..c16714c20d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestBuildAction/index.jelly @@ -0,0 +1,129 @@ + + + + + + + + + +

+

ALM Octane Pull Request Report

+

+
+
+
+
repositoryUrl : ${it.repositoryUrl}
+
minUpdateDate : ${it.minUpdateTime} - ${it.getFormattedDate(it.minUpdateTime)}
+
sourceBranchFilter : ${it.sourceBranchFilter}
+
targetBranchFilter : ${it.targetBranchFilter}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pull requests
IdTitleStateIsMergedAuthorUpdated TimeSourceTarget#Commits
${s.id}${s.title}${s.state}${s.merged}${s.authorName}${it.getFormattedDate(s.updatedTime)}${s.sourceRepository.url} : ${s.sourceRepository.branch}${s.targetRepository.url} : ${s.targetRepository.branch}${s.commits.size()}
+ +
+ +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/config.jelly new file mode 100644 index 0000000000..3f23074775 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/config.jelly @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help-useSSHFormat.html b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help-useSSHFormat.html new file mode 100644 index 0000000000..a85322383c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help-useSSHFormat.html @@ -0,0 +1,38 @@ + + +
+ Select this if all other jobs that use this repository and are connected to ALM Octane pipelines use SSH format. + It is important to be consistent with other jobs that use this repository. +
+ This will ensure that ALM Octane correctly identifies the SCM repository associated with commits, branches and pull requests. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help.html b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help.html new file mode 100644 index 0000000000..dfddc07cbe --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/pullrequests/PullRequestPublisher/help.html @@ -0,0 +1,91 @@ + + +
+ This step is responsible for collecting pull requests from the SCM tool and injecting them to ALM Octane. + See help information in ALM Octane Help Center. +
+
+ In addition, this step is used to define the scm repositories templates that are used by ALM Octane to link to your repository viewer. To configure templates in ALM Octane, access Settings > Spaces. Select a workspace and click DevOps > SCM Repositories. Follow the on-screen instructions. +
+
+ Every time pull requests are sent to ALM Octane the last update time is saved. The next time, only pull requests and commits that were updated after this time will be sent to ALM Octane. + +
+
+ Supported version of ALM Octane: 15.0.49 and later. + + +
+
+ You can change the behaviour of this step by adding the following parameters to the job: +
    +
  • pullrequests_min_update_time: Use this parameter to override the last update time that is updated after each successful injection to ALM Octane.

  • +
  • pullrequests_max_pr_to_collect: Max number of pull requests to collect. Default is 100.

  • +
  • pullrequests_max_commits_to_collect: Max number of commits to collect for each pull request. Default is 100.

  • +
+ +
+
+ + Supported SCM Tools: +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
SCM ToolSupported types of authenticationHow to create PAT (Personal access token)
Bitbucket ServerUser/password and PATClick on your profile icon -> Manage account -> Personal access tokens -> Create a token (Assign Read permissions for both Projects and Repositories)
Github CloudPAT onlyClick on your profile icon -> Settings -> Developer settings -> Personal access tokens -> Generate new token (Uncheck all scopes to grants read-only access)
Github ServerUser/password and PAT
+
+ Note : To create PAT credentials in Jenkins , use "Secret text" kind of credentials in "Add Credentials" dialog + +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/config.jelly new file mode 100644 index 0000000000..6241b56f93 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/config.jelly @@ -0,0 +1,188 @@ + + + + + + + + +
+ + + + + + + + +
+
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-format.html b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-format.html new file mode 100644 index 0000000000..0d13dad780 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-format.html @@ -0,0 +1,121 @@ + +
+ In the 'Custom conversion format' field, enter json that describes how to convert tests from raw format to the format of your testing framework. + After conversion, the result is injected to the "testsToRunConverted" parameter. + +

+ Note: Click "Validate" to check the correctness of the inserted configuration. +

+ + The following are the components that you can use in the "Custom conversion format" : +
    +
  • testPattern - describes the pattern for converting single test. All parameters that needs to be replaced be real test data, should start with $, for example $package, $class, $testName, $externalRunId, $myCustomParam. All other characters in the pattern will appear in the final result as is.
  • +
  • testDelimiter - the delimiter used to separate different tests.
  • +
  • prefix - a prefix for the whole conversion result.
  • +
  • suffix - a suffix for the whole conversion result.
  • +
  • allowDuplication - indicate whether duplications are allowed in final result. Default is true.
  • +
  • testsToRunConvertedParameter - the parameter name that will contain the conversion result. Default value is "testsToRunConverted".
  • +
  • replacements - the array of replace methods.
  • + +
+ + The minimal configuration is: +

+
+{
+    "testPattern": "$package.$class#$testName",
+    "testDelimiter": ","
+}
+    
+ +
For example:

+ The testsToRun parameter received 2 tests separated by a semicolon: v1:myPackage1|myClass1|myTest1;myPackage2|myClass2|myTest2
+ The defined testPattern is: $package.$class#$testName
+ The defined testDelimiter is: , +
    +
  • $package variable will get a value of myPackage1 for the first test and myPackage2 for the second test.
  • +
  • $class variable will get a value of myClass1 for the first test and myClass2 for the second test.
  • +
  • $testName variable will get a value of myTest1 for the first test and myTest2 for the second test.
  • +
+
The testsToRunConverted parameter will be equal: myPackage1.myClass1#myTest1,myPackage2.myClass2#myTest2 + +
+
+ Optional: +
+ There is a possibility to alter values received from ALM Octane, for example to set lowercase to the testName, replace spaces by '_', and so on. +
+ Here are examples of available replace methods. Each replace method contains "target" property that define what parts of the test pattern are affected by replace method, + available values are $package,$class,$testName. Its possible to put several values separated by '|'. The replacements are executed in the order they appear in the 'Custom conversion format' json. +
+"replacements": [
+{
+    "type": "replaceRegex",
+    "target": "$package|$class|$testName",
+    "regex": "aaa",
+    "replacement": "bbb",
+    "description": "Replaces all the sequence of characters matching the regex with a replacement string."
+},{
+    "type": "replaceRegexFirst",
+    "target": "$package|$class|$testName",
+    "regex": "aaa",
+    "replacement": "bbb",
+    "description": "Replaces the first substring that matches the given regex with the given replacement. For example, given regex '@(.*)@.*' , replacement '$1', and test name '@myTag@ my test name' - will replace test name by the content located between @, that is - 'myTag'."
+},{
+    "type": "replaceString",
+    "target": "$package|$class|$testName",
+    "string": "xxx",
+    "replacement": "yyy",
+    "description": "Replaces all occurrences of ‘string’ with ‘replacement’."
+},{
+    "type": "joinString",
+    "target": "$package|$class|$testName",
+    "prefix": "xxx",
+    "suffix": "yyy",
+    "description": "Add prefix and suffix to the test template."
+},{
+    "type": "toLowerCase",
+    "target": "$package|$class|$testName",
+    "description": "Convert test template to lower case."
+},{
+    "type": "toUpperCase",
+    "target": "$package|$class|$testName",
+    "description": "Convert test template to upper  case."
+},{
+    "type": "notLatinAndDigitToOctal",
+    "target": "$package|$class|$testName",
+    "description": "Replaces all non-latin characters and digits ^[a-zA-Z0-9] to their ASCII octal value."
+}]
+
+ +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-framework.html b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-framework.html new file mode 100644 index 0000000000..d9131d71b3 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help-framework.html @@ -0,0 +1,34 @@ + +
+ Select the testing framework whose format you want to convert to. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help.html b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help.html new file mode 100644 index 0000000000..c50823b062 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/octane/testrunner/TestsToRunConverterBuilder/help.html @@ -0,0 +1,180 @@ + + +
+ This build step is intended to support execution of automated tests from ALM Octane.
+ The builder searches for the "testsToRun" parameter which is sent from ALM Octane as part of the execution + framework.
+ Once it is found, its value is converted to the format of the selected testing framework, and injected to the + "testsToRunConverted" environment parameter.
+ Later, the new parameter can be used in the appropriate execution builder. +
    +
  • To use in parameter textboxes, use the following syntax: ${testsToRunConverted}
  • +
    +
  • To use in the scripts, use the following syntax: +
      +
    • Linux shell: $testsToRunConverted
    • +
    • Windows batch command: %testsToRunConverted%
    • +
    • Pipeline script (workflow job): "${params.testsToRunConverted}"
    • +
    + +
    + See examples in the tables below: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FrameworkLinux shell
    Maven Surefiremvn clean -Dtest=$testsToRunConverted test
    Maven Failsafemvn clean -Dit.test=$testsToRunConverted verify
    Gradlegradle test $testsToRunConverted
    Protractorprotractor conf.js --grep="$testsToRunConverted"
    Cucumber-JVM over Maven/
    BDD Scenario
    mvn clean -Dcucumber.options="$testsToRunConverted" test
    JBehave over Mavenmvn clean -Dfeatures="$testsToRunConverted" test
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FrameworkWindows batch command
    Maven Surefiremvn clean -Dtest=%testsToRunConverted% test
    Maven Failsafemvn clean -Dit.test=%testsToRunConverted% verify
    Gradlegradle test %testsToRunConverted%
    Protractorprotractor conf.js --grep="%testsToRunConverted%"
    Cucumber-JVM over Maven/
    BDD Scenario
    mvn clean -Dcucumber.options="%testsToRunConverted%" test
    JBehave over Mavenmvn clean -Dfeatures="%testsToRunConverted%" test
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FrameworkPipeline script
    Maven Surefirebat 'mvn clean -Dtest=${params.testsToRunConverted} test'
    Maven Failsafebat 'mvn clean -Dit.test=${params.testsToRunConverted} verify'
    Gradlebat 'gradle test ${params.testsToRunConverted}'
    Protractorbat(/protractor conf.js --grep="${params.testsToRunConverted}"/)
    Cucumber-JVM over Maven/
    BDD Scenario
    bat(/mvn clean -Dcucumber.options="${params.testsToRunConverted}" test/)
    JBehave over Mavenbat(/mvn clean -Dfeatures="${testsToRunConverted}" test/)
    +
    +
  • +
+ + +
+ Notes/Limitations : +
+
    +
  • UFT: In order to build a UFT MTBX file, this builder needs to know the test check-out directory. By + default this is the job workspace directory. If tests are checked out in another directory, define in the job a String parameter "testsToRunCheckoutDirectory" + with the correct directory.
  • +
  • JUnit/TestNG: Supported for JUnit 4.7+, Surefire Plugin 2.19+, Failsafe Plugin 2.12.1+.
  • +
  • Cucumber-JVM over Maven: If your project contains several run classes, specify a run class that will + be used, otherwise all run classes will be executed by Cucumber. You can specify test runner by adding: + '-Dtest=[runner class name]' to the Maven command +
  • +
  • JBehave over Maven: read more about integration with JBehave here +
  • +
+ +
+
+ See more help information in ALM Octane Help Center +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pc/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/pc/Messages.properties new file mode 100644 index 0000000000..86b552a517 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pc/Messages.properties @@ -0,0 +1,93 @@ +# +# 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. +# ___________________________________________________________________ +# + +# PcClient section - start +UsingProxy=Using proxy +UsingProxyCredentialsBuildParameters=Using proxy credentials of the following user as specified in build parameters: +UsingProxyCredentialsConfiguration=Using proxy credentials of following user as specified in configuration: +UsingPCCredentialsBuildParameters=Using LoadRunner Enterprise credentials supplied in build parameters +UsingPCCredentialsConfiguration=Using LoadRunner Enterprise credentials supplied in configuration +TryingToLogin=Trying to login +LoginSucceeded=Login succeeded +LoginFailed=Login failed +ExecutingLoadTest=Executing Load Test: +Domain=Domain +Project=Project +TestID=Test ID +TestInstanceID=Test Instance ID +TimeslotDuration=Timeslot Duration +PostRunAction=Post Run Action +UseVUDS=Use VUDS +RunStarted=Run started +StartRunRetryFailed=StartRun retry failed +AttemptingStartAgainSoon=Attempting to start again soon +Minutes=minutes +AttemptsRemaining=Attempts remaining +RetrievingIDFailed=Retrieving ID failed +SearchingTestInstance=Searching for available test instance +FoundTestInstanceID=Found test instance ID +NotFoundTestInstanceID=Could not find existing test instanceID. Creating a new test instance. +SearchingAvailableTestSet=Searching for available TestSet +TestInstanceCreatedSuccessfully=Test Instance has been created successfully. Test Instance ID +CreatingNewTestInstance=Creating new Test Instance +NoTestSetAvailable=There is no TestSet available in the project. Please create a testset from LoadRunner Enterprise UI. +NoTrendReportAssociated=No trend report ID is associated with the test. +PleaseTurnAutomaticTrendOn=Please turn Automatic Trending on for the test through LoadRunner Enterprise UI. +PleaseTurnAutomaticTrendOnAlternative=Alternatively you can check 'Add run to trend report with ID' on Jenkins job configuration. +StoppingMonitoringOnRun=Stopping monitoring on Run +StoppedFromPC=Stopped from LoadRunner Enterprise side with state +PublishingAnalysisReport=Publishing analysis report +FailedToGetRunReport=Failed to get run report +LogoutSucceeded=Logout succeeded +LogoutFailed=Logout failed +StoppingRun=Stopping run +StopRunSucceeded=Stop run succeeded +StopRunFailed=Stop run failed +PublishingRun=Publishing run +OnTrendReport=on trend report +FailedToAddRunToTrendReport=Failed to add run to trend report +ProblemConnectingToPCServer=Problem connecting to LoadRunner Enterprise Server +PublishingStatus=publishing status +PublishingEndTimeout=Publishing did not end after 30 minutes, aborting... +PublishingStartTimeout=Publishing did not start after 15 minutes, aborting... +DownloadingTrendReport=Downloading trend report +InPDFFormat=in PDF format +TrendReport=Trend report +SuccessfullyDownloaded=successfully downloaded +FailedToDownloadTrendReport=Failed to download trend report +ViewTrendReport=View trend report +Error=Error +Failure=Failure +StartRunFailed=startRun failed +WaitingForTrendReportToStart=Waiting for trend report to start being generated (an idle Data Processor host must be available) +MinutesUntilTimeout = Minutes until timeout +# PcClient section - ended \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep/config.jelly new file mode 100644 index 0000000000..0c3c21b49d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerScriptStep/config.jelly @@ -0,0 +1,38 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly new file mode 100644 index 0000000000..d631014b14 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.jelly @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties new file mode 100644 index 0000000000..efd6e6918d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/config.properties @@ -0,0 +1,37 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher=Make sure to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section. This allows the tests results to be published. +SummaryDataLog=Summary Data Log +RuntimeSettings=Runtime Settings diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-analysisTemplate.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-analysisTemplate.html new file mode 100644 index 0000000000..283ac76521 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-analysisTemplate.html @@ -0,0 +1,35 @@ + + +
+ Apply a template for the build (path to a .tem file). Leave blank in order to use the default template. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html new file mode 100644 index 0000000000..890429355d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-archiveTestResultsMode.html @@ -0,0 +1,40 @@ + + +
+To view the run results, do one of the following:
+1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
+2) From the Build Artifacts:
+• Open the run_results.html to view the run results.
+• Download the zipped report to your desired location and unzip it. In the Run Results Viewer, select the Results.xml file found inside the unzipped folder.
+Note that this option is valid only when using the “Execute test from file system” build step. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html new file mode 100644 index 0000000000..1704496c63 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-controllerPollingInterval.html @@ -0,0 +1,35 @@ + + +
+Polling interval for checking the scenario status, in seconds. The default is 30 seconds. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-displayController.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-displayController.html new file mode 100644 index 0000000000..11fbca9ec7 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-displayController.html @@ -0,0 +1,35 @@ + + +
+Display the controller while the scenario is running. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html new file mode 100644 index 0000000000..b41fc45060 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTests.html @@ -0,0 +1,35 @@ + + +
+List of tests or folders that contain tests, to run. Each line should contain a single test, folder, or MTB file. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html new file mode 100644 index 0000000000..4767c3cceb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-fsTimeout.html @@ -0,0 +1,35 @@ + + +
+ Timeout value in seconds. If left empty, there is no timeout. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html new file mode 100644 index 0000000000..be33325975 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-ignoreErrorStrings.html @@ -0,0 +1,35 @@ + + +
+Ignore errors during the scenario run containing any of the strings listed below. For example: "Error: CPU usage for this load generator has exceeded 80%" +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html new file mode 100644 index 0000000000..903a9286fb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/LoadRunnerTestStep/help-perScenarioTimeOut.html @@ -0,0 +1,35 @@ + + +
+The maximum time allotted for scenario execution, in minutes. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly new file mode 100644 index 0000000000..6735dfdf65 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.jelly @@ -0,0 +1,150 @@ + + + + + + + + +
+ ${%AlmServersAreNotDefined} +
+ + + +
+ + + + +
+ ${%ServerSideTests} +
+ + + + + + +
+ ${%DontForgetThePublisher} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties new file mode 100644 index 0000000000..81201ca75e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/config.properties @@ -0,0 +1,39 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher=Don''t forget to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section so that the tests results are published. + +AlmServersAreNotDefined=OpenText ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server + +ServerSideTests=Use this build step to run ALM server-side functional test sets and Build Verification Suites. \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html new file mode 100644 index 0000000000..890429355d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-archiveTestResultsMode.html @@ -0,0 +1,40 @@ + + +
+To view the run results, do one of the following:
+1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
+2) From the Build Artifacts:
+• Open the run_results.html to view the run results.
+• Download the zipped report to your desired location and unzip it. In the Run Results Viewer, select the Results.xml file found inside the unzipped folder.
+Note that this option is valid only when using the “Execute test from file system” build step. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-clientType.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-clientType.html new file mode 100644 index 0000000000..ba5e43e9a8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-clientType.html @@ -0,0 +1,35 @@ + + +
+Client type is required for some ALM above 12.60 in authentication. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html new file mode 100644 index 0000000000..3ab88eb49c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/SseBuildAndPublishStep/help-environmentConfigurationId.html @@ -0,0 +1,35 @@ + + +
+To find the ID of your environment configuration, right-click the entity, copy the URL, and paste it to a text editor. Use the number associated with the EntityID at the end of the URL. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly new file mode 100644 index 0000000000..43ef2ece5f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.jelly @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties new file mode 100644 index 0000000000..cfd7e53678 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/config.properties @@ -0,0 +1,35 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher=Make sure to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section. This allows the tests results to be published. \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html new file mode 100644 index 0000000000..890429355d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-archiveTestResultsMode.html @@ -0,0 +1,40 @@ + + +
+To view the run results, do one of the following:
+1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
+2) From the Build Artifacts:
+• Open the run_results.html to view the run results.
+• Download the zipped report to your desired location and unzip it. In the Run Results Viewer, select the Results.xml file found inside the unzipped folder.
+Note that this option is valid only when using the “Execute test from file system” build step. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html new file mode 100644 index 0000000000..b41fc45060 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/pipelineSteps/UftScenarioLoadStep/help-fsTests.html @@ -0,0 +1,35 @@ + + +
+List of tests or folders that contain tests, to run. Each line should contain a single test, folder, or MTB file. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/DetailReport/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/DetailReport/index.jelly new file mode 100644 index 0000000000..02c562cc01 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/DetailReport/index.jelly @@ -0,0 +1,44 @@ + + + + + + +

LoadRunner Performance Result

+

${it.name}

+ +
+
+
+ + diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/HtmlBuildReportAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/HtmlBuildReportAction/index.jelly new file mode 100644 index 0000000000..34f2d609a3 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/HtmlBuildReportAction/index.jelly @@ -0,0 +1,163 @@ + + + + + + + + + +

UFT Report

+
+ +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeReport nameTimestampStatusFolderArchive
+ Html_parallel_report + ${s.disPlayName} + Html_report + ${s.disPlayName}RRV_report${s.disPlayName}${s.getFormattedDateTime()}PassedWarningFailedOpen + + + Download + + + Download + + +
+
+

+
+ +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceJobReportAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceJobReportAction/index.jelly new file mode 100644 index 0000000000..387cf850cb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceJobReportAction/index.jelly @@ -0,0 +1,42 @@ + + + + + + +

Job Performance Result

+ +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceProjectAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceProjectAction/index.jelly new file mode 100644 index 0000000000..162cf217a1 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceProjectAction/index.jelly @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ PERFORMANCE TESTS SUMMARY REPORT + +
+
+ +
+
+
+ + +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceReportAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceReportAction/index.jelly new file mode 100644 index 0000000000..d218270941 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/PerformanceReportAction/index.jelly @@ -0,0 +1,70 @@ + + + + + + +

LoadRunner Performance Result

+ + + + + + + + + + + + + + + ${c.printFourCoverageColumns()} + + +
NameDurationPassFail
+ ${c.getName()} + + ${c.getDuration()} + + ${c.getPass()} + + ${c.getFail()} +
+ + +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/RichReportAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/RichReportAction/index.jelly new file mode 100644 index 0000000000..9fe0d9e5ae --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/RichReportAction/index.jelly @@ -0,0 +1,70 @@ + + + + + + +

LoadRunner Rich Report

+ + + + + + + + + + + + + + + ${c.printFourCoverageColumns()} + + +
NameDurationPassFail
+ ${c.getName()} + + ${c.getDuration()} + + ${c.getPass()} + + ${c.getFail()} +
+ + +
+
+
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/config.jelly new file mode 100644 index 0000000000..4e6f75f47a --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/config.jelly @@ -0,0 +1,45 @@ + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html b/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html new file mode 100644 index 0000000000..890429355d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/RunResultRecorder/help-archiveTestResultsMode.html @@ -0,0 +1,40 @@ + + +
+To view the run results, do one of the following:
+1) In the left pane, click the Report and Summary link to display the report link and the link to the report folder. From this link, you can open the run results directly in your browser or open the artifacts
+2) From the Build Artifacts:
+• Open the run_results.html to view the run results.
+• Download the zipped report to your desired location and unzip it. In the Run Results Viewer, select the Results.xml file found inside the unzipped folder.
+Note that this option is valid only when using the “Execute test from file system” build step. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/SummaryReport/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/SummaryReport/index.jelly new file mode 100644 index 0000000000..2e78c3c665 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/SummaryReport/index.jelly @@ -0,0 +1,42 @@ + + + + + + +

Transaction Summary

+

${it.name}

+ +
+
+
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.jelly new file mode 100644 index 0000000000..3387a3f0d5 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.jelly @@ -0,0 +1,112 @@ + + + + + + + + + +
+ ${%AlmServersAreNotDefined} +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.properties b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.properties new file mode 100644 index 0000000000..3c670aebcd --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/config.properties @@ -0,0 +1,35 @@ +# +# 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. +# ___________________________________________________________________ +# + + + +AlmServersAreNotDefined=ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html new file mode 100644 index 0000000000..965d25029c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almDomain.html @@ -0,0 +1,35 @@ + + +
+The Domain of the project to be used. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html new file mode 100644 index 0000000000..56ab5dbc69 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almPassword.html @@ -0,0 +1,35 @@ + + +
+The password for the user to login. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almProject.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almProject.html new file mode 100644 index 0000000000..ee281117a5 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almProject.html @@ -0,0 +1,35 @@ + + +
+The project to be used. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html new file mode 100644 index 0000000000..c9456578a0 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almServerName.html @@ -0,0 +1,35 @@ + + +
+The name of the ALM Server. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html new file mode 100644 index 0000000000..f489fb7a07 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestFolder.html @@ -0,0 +1,37 @@ + + +
+The path of the test folder that will contain the uploaded test. The path doesn't include the Root test folder (Subject).
+For example, sampletestfolder\subfolder means, the tests will be uploaded to test folder named 'subfolder', which is under the test folder named 'sampletestfolder',
+and 'sampletestfolder' is under the root test folder 'Subject'. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html new file mode 100644 index 0000000000..709818fe4f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTestSetFolder.html @@ -0,0 +1,37 @@ + + +
+The path of the testset folder that will contain the uploaded testset. The path doesn't include the Root testset folder.
+For example, sampletestsetfolder\subfolder means, the testsets will be uploaded to testset folder named 'subfolder', which is under the testset folder named 'sampletestsetfolder',
+and 'sampletestsetfolder' is under the root testset folder 'Root'. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html new file mode 100644 index 0000000000..6a08f06797 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almTimeout.html @@ -0,0 +1,35 @@ + + +
+ Number of seconds before timeout. If left empty timeout is unlimited. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html new file mode 100644 index 0000000000..259346170d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-almUserName.html @@ -0,0 +1,35 @@ + + +
+The user name to login. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-clientType.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-clientType.html new file mode 100644 index 0000000000..ba5e43e9a8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-clientType.html @@ -0,0 +1,35 @@ + + +
+Client type is required for some ALM above 12.60 in authentication. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html new file mode 100644 index 0000000000..992f7411cf --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-jenkinsServerUrl.html @@ -0,0 +1,35 @@ + + +
+The HTTP URL of the Jenkins Server, form example, http://myjenkinsserver.test.com:8080 . +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html new file mode 100644 index 0000000000..9d88e89460 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingFramework.html @@ -0,0 +1,35 @@ + + +
+The testing framework that is used when generate the testing result file. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html new file mode 100644 index 0000000000..3720485dce --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingResultFile.html @@ -0,0 +1,35 @@ + + +
+The condition to find the testing result file, start from the root path of the job. For example, **/junitResult.xml to find testing result file for Junit Plugin, **/testng-results.xml to find testing result file for TestNG plugin. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html new file mode 100644 index 0000000000..33dcdb65fc --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TestResultToALMUploader/help-testingTool.html @@ -0,0 +1,35 @@ + + +
+The testing tool that is used when generate the testing result file. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/TransactionSummaryAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/TransactionSummaryAction/index.jelly new file mode 100644 index 0000000000..ed8e1bf4bd --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/TransactionSummaryAction/index.jelly @@ -0,0 +1,70 @@ + + + + + + +

Transaction Summary

+ + + + + + + + + + + + + + + ${c.printFourCoverageColumns()} + + +
NameDurationPassFail
+ ${c.getName()} + + ${c.getDuration()} + + ${c.getPass()} + + ${c.getFail()} +
+ + +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction/index.jelly b/src/main/resources/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction/index.jelly new file mode 100644 index 0000000000..d99002ccbb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/lrscriptresultparser/LrScriptHtmlReportAction/index.jelly @@ -0,0 +1,99 @@ + + + + + + + + + +

LoadRunner Vugen Script Reports

+
+ +

+ + + + + + + + + + + + + + + +
TypeReport nameFolder
Html_report${s.scriptName} + Open ${s.scriptName} result +
+

+
+ +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/results/parser/nunit3/nunit-to-junit.xsl b/src/main/resources/com/microfocus/application/automation/tools/results/parser/nunit3/nunit-to-junit.xsl new file mode 100644 index 0000000000..dd55f1ebc9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/results/parser/nunit3/nunit-to-junit.xsl @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MESSAGE: + ++++++++++++++++++++ +STACK TRACE: + + + +MESSAGE: + ++++++++++++++++++++ +STACK TRACE: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.jelly new file mode 100644 index 0000000000..d0c568c104 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.jelly @@ -0,0 +1,74 @@ + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.properties new file mode 100644 index 0000000000..6c5742be34 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/config.properties @@ -0,0 +1,35 @@ +# +# 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. +# ___________________________________________________________________ +# + +AlmServersAreNotDefined=OpenText ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server + +AutEnvironmentConfigurationDescription=Use this build step to assign values to AUT Environment Configuration in ALM. \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html new file mode 100644 index 0000000000..3ab88eb49c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/AutEnvironmentBuilder/help-environmentConfigurationId.html @@ -0,0 +1,35 @@ + + +
+To find the ID of your environment configuration, right-click the entity, copy the URL, and paste it to a text editor. Use the number associated with the EntityID at the end of the URL. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/JobConfigRebrander/JobConfigRebrander/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/JobConfigRebrander/JobConfigRebrander/config.jelly new file mode 100644 index 0000000000..73df6ac359 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/JobConfigRebrander/JobConfigRebrander/config.jelly @@ -0,0 +1,36 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/Messages.properties b/src/main/resources/com/microfocus/application/automation/tools/run/Messages.properties new file mode 100644 index 0000000000..8c34d80b4f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/Messages.properties @@ -0,0 +1,73 @@ +# +# 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. +# ___________________________________________________________________ +# + +# PCBuilder Section - start +DisplayName=Execute performance test using LoadRunner Enterprise +CannotFindCredentials=Cannot find credentials with the credentialsId +BuildParameterNotConsidered=Build parameters will not be taken in consideration +ArtifactId=hp-application-automation-tools-plugin +FailedToObtainInstance=failed to obtain Jenkins instance +PluginVersionIs=plugin version is +TestDescription=Test description +Error=Error +StartRunFailed=startRun failed +TestNameIs=test name is +ValidatingParametersBeforeRun=Validating parameters before run +ParameterIsMissing=Parameter Is Missing +TrendReportIDIsMissing=trend report ID is missing +IllegalParameter=Illegal Parameter: trend report ID is not a number +UpdatingCsvFilesForTrendingCharts=Updating csv files for Trending Charts +TrendingCharts=Trending Charts +YouCanViewTrendCharts=You can view Trending Charts directly from Jenkins using Plot Plugin, see more details on the +PerformanceCenter1255AndLater=Performance Center 12.55 and Later +Documentation=documentation +Failure=Failure +ViewAnalysisReportOfRun=View analysis report of run +LoadTestRunID=Load Test Run ID +ViewAnalysisReport=View analysis report +DownloadReport=Download Report +ResultStatus=Result Status +EmptyResults=Empty Results +FailedToCreateRunResults=Failed to create run results +Exception=Exception +ErrorSavingFile=Error saving file +ToWorkspacePath=to workspace path +WorkspacePathIsUnavailable=Workspace path is unavailable +RunMeasurementsNotReachSLACriteria=Run measurements did not reach SLA criteria. Run SLA Status +CannotFindAnyCredentials=Cannot find any credentials with id +MustBeSet=must be set +MustBeHigherThan=must be higher than +MustBeAtLeast=must be at least +MustBeAWholeNumberOrAParameter=must be a whole number or a parameter +ForExample=for example +SetEnvironmentVariable=Set Environment Variable +# PCBuilder Section - end diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.jelly new file mode 100644 index 0000000000..550fa37d18 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.jelly @@ -0,0 +1,443 @@ + + + + + + + + + + + + +
+ ${%DontForgetThePublisher} +
+
+ ${%ParametrizationMessage} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Browse to find the Test ID + + +   + Test Instance ID + + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + + + + + +
+
+ +   + Trending + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ Timeslot Duration + + Hours  + + + + + +   Minutes  + + + + + + (Minimum: 30 minutes) +
+ + + +
+
+
+ + + +
+
+ + +
+
+ + + +
+
+   + On Timeslot creation failure + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.properties new file mode 100644 index 0000000000..c190cc6c59 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/config.properties @@ -0,0 +1,39 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher=Don''t forget to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section so that the tests results are published. +ParametrizationMessage=The following fields can be parametrized: ''LRE Server'', ''LRE Credentials'', \ + ''Domain'', ''Project'', ''Test ID'', ''Test Instance ID'', \ + ''Trend report ID'', ''Local Proxy'', ''Proxy Credentials'' \ + and ''Timeslot Duration'' (in two separate parameters: ''Hours'' and ''Minutes''). \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-authenticateWithToken.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-authenticateWithToken.html new file mode 100644 index 0000000000..f64b9faeb9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-authenticateWithToken.html @@ -0,0 +1,39 @@ + + +
+
From LRE 2021 R1, you can use a token associated with your user for authentication.
+
If LRE is defined to use SSO, this will be the only way for this plugin to authenticate to LRE.
+
To use it, have a token issued to your user in LRE.
+
In Jenkins, create new Jenkins credentials based on the LRE token you received: use the ClientIdKey in the Username and the ClientSecretKey key in the password.
+
Then use the new Jenkins credentials with this checkbox switched on.
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-credentialsId.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-credentialsId.html new file mode 100644 index 0000000000..4f9efd9aad --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-credentialsId.html @@ -0,0 +1,35 @@ + + +
+ LoadRunner Enterprise User / Token's Credentials or parameter pointing to such credentials. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-pcServerName.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-pcServerName.html new file mode 100644 index 0000000000..b0df331e93 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-pcServerName.html @@ -0,0 +1,43 @@ + + +
+ Hostname or IP address + The LoadRunner Enterprise Hostname or IP address. If the port of the LRE server is different than the default one, mention it by adding a collon (:) and then the port number
+ Example: mypcserver.mycompany.net or 182.138.255.1 or mypcserver.mycompany.net:81
+
+ If the LRE server requires to be accessed via a tenant, you can specify it by adding the tenant details to the LRE Server field.
+ Example: mypcserver.mycompany.net/?tenant=fa128c06-5436-413d-9cfa-9f04bb738df3 or 182.138.255.1/?tenant=fa128c06-5436-413d-9cfa-9f04bb738df3 or mypcserver.mycompany.net:81/?tenant=fa128c06-5436-413d-9cfa-9f04bb738df3
+
+ Important: Do not use the full URL of LoadRunner Enterprise server.
+ For example, using https://mypcserver/LoadTest will fail. Instead, just specify 'mypcserver' value in 'LRE Server' field and switch on the 'Use HTTPS Protocol' if secured protocol is required. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-proxyOutURL.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-proxyOutURL.html new file mode 100644 index 0000000000..a666a6de44 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-proxyOutURL.html @@ -0,0 +1,40 @@ + + +
+ Add your local proxy as following: http(s)://host:port
or + Leave empty if not using a local proxy. The following proxy configurations are not supported: +
    +
  • PAC (proxy auto-config).
  • +
  • Automatic configuration script.
  • +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-statusBySLA.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-statusBySLA.html new file mode 100644 index 0000000000..687a445171 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-statusBySLA.html @@ -0,0 +1,36 @@ + + +
+Check this option in order to set the build-step status according to a pre-defined SLA (Service Level Agreement) configured within your performance test. +Unless checked, the build-step will be labeled as Passed as long as no failures occurred. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-testInstanceId.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-testInstanceId.html new file mode 100644 index 0000000000..94a21ea744 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-testInstanceId.html @@ -0,0 +1,35 @@ + + +
+Represents an instance of a performance test within an ALM Test Set. In order to find the test instance id go to: LRE Web UI > Testing > Select the relevant test > Test Details tab > Assigned Test Set drop down list > Edit the Test Set and look for the Test Instance ID column +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-vudsMode.html b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-vudsMode.html new file mode 100644 index 0000000000..0f690cd743 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/PcBuilder/help-vudsMode.html @@ -0,0 +1,36 @@ + + +
+A Virtual User Day (VUD) license provides you with a specified number of Vusers (VUDs) that you can run an unlimited number of times within a 24 hour period. +Before using this option, make sure that VUDs licenses are applied in your Micro Focus LoadRunner Enterprise environment. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.jelly new file mode 100644 index 0000000000..738b4120f7 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.jelly @@ -0,0 +1,269 @@ + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.properties new file mode 100644 index 0000000000..0853a0dd13 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/config.properties @@ -0,0 +1,37 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher=Don''t forget to enable the Publish \ + tests result option in the Post-build \ + Actions section so that the tests results are published. + +AlmServersAreNotDefined=ALM servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Application Lifecycle Management->Add ALM server \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almCredentialsScope.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almCredentialsScope.html new file mode 100644 index 0000000000..7f30a5c4b4 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almCredentialsScope.html @@ -0,0 +1,39 @@ + + +
+ Select the scope of the credentials used for connecting to the specified ALM Server: +
    +
  • Job (local) credentials: This option requires to provide the credentials right here at job level.
  • +
  • System (global) credentials: This option allows the selection of UserName or ClientID from a dropdown list with global credentials.
  • +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunHost.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunHost.html new file mode 100644 index 0000000000..1e7443dd17 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunHost.html @@ -0,0 +1,35 @@ + + +
+If the Run mode field is set to Run remotely, use this field to specify the name of the host that runs the test set. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunMode.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunMode.html new file mode 100644 index 0000000000..659d45f440 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almRunMode.html @@ -0,0 +1,40 @@ + + +
+Defines how the test set is executed: +
    +
  • Run locally: The test set is run on the machine that performs the build.
  • +
  • Run remotely: The test set is run on the host defined in the Testing Tool host field.
  • +
  • Run on planned host: The test set is run on the host defined in ALM.
  • +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTestSets.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTestSets.html new file mode 100644 index 0000000000..b59b74170d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTestSets.html @@ -0,0 +1,42 @@ + + +
+List of test sets to run. Each line contains a path to a test set or a test set folder.
+ For example: Root\subFolder1\subFolder2\testSetToRun . +
+In case you want to parameterize the tests please specify the parameters and their values like:
+ Root\subFolder1\subFolder2\testSetToRun "Parameter1":"<stringvalue>",..., "ParameterN":<numbervalue> + +
+ Also, for better specification of parameters you may use the "Specify test parameters" section below. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTimeout.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTimeout.html new file mode 100644 index 0000000000..6a08f06797 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-almTimeout.html @@ -0,0 +1,35 @@ + + +
+ Number of seconds before timeout. If left empty timeout is unlimited. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-filterTests.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-filterTests.html new file mode 100644 index 0000000000..71d18b911a --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-filterTests.html @@ -0,0 +1,35 @@ + + +
+ If the filter is selected then the build will execute all tests which contain the word from the "Tests names contain" field in the name and all tests with the selected status. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-isSSOEnabled.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-isSSOEnabled.html new file mode 100644 index 0000000000..f5fdb109fc --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromAlmBuilder/help-isSSOEnabled.html @@ -0,0 +1,35 @@ + + +
+ Obtain the Client ID and API key secret from your ALM site administrator. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.jelly new file mode 100644 index 0000000000..8c3511ba2e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.jelly @@ -0,0 +1,103 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.properties new file mode 100644 index 0000000000..6f78090a7c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromCodelessBuilder/config.properties @@ -0,0 +1,37 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisherFreestyle=Make sure to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section. This allows the tests results to be published. +DontForgetThePublisherPipeline=We suggest adding a Publish OpenText \ + tests result step in the pipeline job. This allows the tests results to be published. diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.jelly new file mode 100644 index 0000000000..9289c66cb9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.jelly @@ -0,0 +1,422 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.properties new file mode 100644 index 0000000000..e79e567de9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/config.properties @@ -0,0 +1,39 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisherFreestyle=Make sure to enable the Publish OpenText \ + tests result option in the Post-build \ + Actions section. This allows the tests results to be published. +DontForgetThePublisherPipeline=We suggest adding a Publish OpenText \ + tests result step in the pipeline job. This allows the tests results to be published. +SummaryDataLog=Summary Data Log +RuntimeSettings=Runtime Settings \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-analysisTemplate.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-analysisTemplate.html new file mode 100644 index 0000000000..283ac76521 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-analysisTemplate.html @@ -0,0 +1,35 @@ + + +
+ Apply a template for the build (path to a .tem file). Leave blank in order to use the default template. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-controllerPollingInterval.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-controllerPollingInterval.html new file mode 100644 index 0000000000..1704496c63 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-controllerPollingInterval.html @@ -0,0 +1,35 @@ + + +
+Polling interval for checking the scenario status, in seconds. The default is 30 seconds. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-displayController.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-displayController.html new file mode 100644 index 0000000000..457fd4cca7 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-displayController.html @@ -0,0 +1,35 @@ + + +
+ Display the controller while the scenario is running. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppParamName.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppParamName.html new file mode 100644 index 0000000000..49da1d30ac --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppParamName.html @@ -0,0 +1,35 @@ + + +
+ The parameter name of object identifier, as defined in the UFT script. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppPath.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppPath.html new file mode 100644 index 0000000000..61e51fe803 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsAppPath.html @@ -0,0 +1,35 @@ + + +
+ The path of the application to upload to Digital Lab, on the Jenkins master machine. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsPassword.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsPassword.html new file mode 100644 index 0000000000..07473fe4c4 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsPassword.html @@ -0,0 +1,35 @@ + + +
+ The password for Digital Lab. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsProxyAddress.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsProxyAddress.html new file mode 100644 index 0000000000..5b78cfcc27 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsProxyAddress.html @@ -0,0 +1,35 @@ + + +
+ Example: 16.54.185.180:8080 +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsReportPath.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsReportPath.html new file mode 100644 index 0000000000..8109c0edfb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsReportPath.html @@ -0,0 +1,35 @@ + + +
+The directory where the test results will be saved. If this is left empty the default directory will be used. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTests.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTests.html new file mode 100644 index 0000000000..18e14f9252 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTests.html @@ -0,0 +1,41 @@ + + +
+List of tests or folders that contain tests, to run. Each line should contain a single test, folder, or MTB file. +
+In case you want to parameterize the tests please specify the parameters and their values like:
+ <TestPath> "Parameter1":"<stringvalue>",..., "ParameterN":<numbervalue> + +
+ Also, for better specification of parameters you may use the "Specify test parameters" section below. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTimeout.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTimeout.html new file mode 100644 index 0000000000..d20c7febca --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsTimeout.html @@ -0,0 +1,34 @@ + +
+ Timeout value in seconds. If left empty, there is no timeout. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsUserName.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsUserName.html new file mode 100644 index 0000000000..a978540d86 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-fsUserName.html @@ -0,0 +1,35 @@ + + +
+ The user name for Digital Lab. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-ignoreErrorStrings.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-ignoreErrorStrings.html new file mode 100644 index 0000000000..be33325975 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-ignoreErrorStrings.html @@ -0,0 +1,35 @@ + + +
+Ignore errors during the scenario run containing any of the strings listed below. For example: "Error: CPU usage for this load generator has exceeded 80%" +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-isParallelRunnerEnabled.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-isParallelRunnerEnabled.html new file mode 100644 index 0000000000..c38663581c --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-isParallelRunnerEnabled.html @@ -0,0 +1,37 @@ + + +
+ Note: This mode is for UFT GUI test only.With it enabled, you can define multiple tests and the environments to run with.

+ UFT will run on those environments in parallel(at most 4 environments simultaneously) for each test.

+ Disabling this option will switch back to the normal view with the tests kept. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcServerName.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcServerName.html new file mode 100644 index 0000000000..4579562927 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcServerName.html @@ -0,0 +1,34 @@ + +
+ Select the Digital Lab server. To add a server, go to Manage Jenkins > Configure System > Digital Lab. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcTenantId.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcTenantId.html new file mode 100644 index 0000000000..c8b87522b2 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-mcTenantId.html @@ -0,0 +1,34 @@ + +
+ Tenant Id should only be specified for workspace-enabled (MSP) servers, otherwise should be left empty. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-outEncoding.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-outEncoding.html new file mode 100644 index 0000000000..f28a1affae --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-outEncoding.html @@ -0,0 +1,36 @@ + +
+ The encoding charset to be used when printing the text in the Console Output. + The field is optional and the default value is UTF-8. + The type UTF-16 is equivalent to Unicode. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-perScenarioTimeOut.html b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-perScenarioTimeOut.html new file mode 100644 index 0000000000..903a9286fb --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromFileBuilder/help-perScenarioTimeOut.html @@ -0,0 +1,35 @@ + + +
+The maximum time allotted for scenario execution, in minutes. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunFromSrfBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromSrfBuilder/config.properties new file mode 100644 index 0000000000..ea74706c04 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunFromSrfBuilder/config.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +DontForgetThePublisher= \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/RunLoadRunnerScript/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/RunLoadRunnerScript/config.jelly new file mode 100644 index 0000000000..128dc7b578 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/RunLoadRunnerScript/config.jelly @@ -0,0 +1,38 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/config.jelly new file mode 100644 index 0000000000..bd96089a2b --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/config.jelly @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help-skipWebhookCreation.html b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help-skipWebhookCreation.html new file mode 100644 index 0000000000..317a07e4ff --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help-skipWebhookCreation.html @@ -0,0 +1,50 @@ + +
+ + The integration with SonarQube works by using Sonar’s webhook mechanism, and contains several phases: +
    +
  1. The plugin automatically configures a webhook in Sonar before the job runs (this requires an access token + with global 'Administer' permission). +
  2. +
  3. When the Sonar analysis is ready, the SonarQube server calls the configured webhook.
  4. +
  5. Results are then submitted to ALM Octane for further analysis (this requires an access token with 'Read' + permissions). +
  6. +
+ + If you cannot assign global 'Administer' permissions to the Sonar token (for the first phase), select "Skip webhook + creation", and define a webhook manually in the Sonar server (either at the global level or project level) to the + following URL: {jenkins_url}/webhooks/notify + + +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help.html b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help.html new file mode 100644 index 0000000000..b1754fde07 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/SonarOctaneListener/help.html @@ -0,0 +1,35 @@ + + +
+ See help information in ALM Octane Help Center +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/SseBuilder/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/run/SseBuilder/config.jelly new file mode 100644 index 0000000000..529b8a87b2 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/SseBuilder/config.jelly @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/config.properties b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/config.properties new file mode 100644 index 0000000000..0fb068010d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/config.properties @@ -0,0 +1,33 @@ +# +# 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. +# ___________________________________________________________________ +# + +McServersAreNotDefined=Digital Lab servers are not defined. To use this build step, goto Manage Jenkins->Configure System->Digital Lab->Add Digital Lab server \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcServerName.html b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcServerName.html new file mode 100644 index 0000000000..4579562927 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcServerName.html @@ -0,0 +1,34 @@ + +
+ Select the Digital Lab server. To add a server, go to Manage Jenkins > Configure System > Digital Lab. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcTenantId.html b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcTenantId.html new file mode 100644 index 0000000000..c8b87522b2 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/run/UploadAppBuilder/help-mcTenantId.html @@ -0,0 +1,34 @@ + +
+ Tenant Id should only be specified for workspace-enabled (MSP) servers, otherwise should be left empty. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..6de0560e89 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/config.jelly @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + + + + + + + + + + +
+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+ +
+
+
+ + + + + + + + + + + +
+ +
+
+
+
+
+
+
+ + + +
+ +
+
+
+
+ +
+
+
+ + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerName.html b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerName.html new file mode 100644 index 0000000000..a45f7b9e45 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerName.html @@ -0,0 +1,35 @@ + + +
+ The name of the ALM Server. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerUrl.html b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerUrl.html new file mode 100644 index 0000000000..000674444f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerUrl.html @@ -0,0 +1,35 @@ + + +
+ The name of the URL of the ALM Server: http://myalmserver:8080/qcbin +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerVersion.html b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerVersion.html new file mode 100644 index 0000000000..1f031b587a --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/AlmServerSettingsGlobalConfiguration/help-almServerVersion.html @@ -0,0 +1,35 @@ + + +
+ The version of the ALM server:10.0, 11.0, 11.5 +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..c2b50bcd9e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/config.jelly @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+ + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerName.html b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerName.html new file mode 100644 index 0000000000..fdfed901a9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerName.html @@ -0,0 +1,35 @@ + + +
+ The name of the Digital Lab Server. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerUrl.html b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerUrl.html new file mode 100644 index 0000000000..cceeb1d161 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/MCServerSettingsGlobalConfiguration/help-mcServerUrl.html @@ -0,0 +1,35 @@ + + +
+ The Digital Lab server host. i.e: http://dlserver:8080 +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..fbdf2a8dee --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.jelly @@ -0,0 +1,117 @@ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
+
+ + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.properties b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.properties new file mode 100644 index 0000000000..dcad14c6f3 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/config.properties @@ -0,0 +1,61 @@ +# +# 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. +# ___________________________________________________________________ +# + +global.config.description=ALM Octane CI Plugin +global.config.server.title=ALM Octane Server Configuration +global.config.location.title=Location +global.config.location.description=Location of the ALM Octane application +global.config.domain.title=Domain +global.config.domain.description=Domain name +global.config.project.title=Project +global.config.project.description=Project name +global.config.username.title=Client ID +global.config.username.description=Client ID used for logging into the ALM Octane server +global.config.password.title=Client secret +global.config.password.description=Client secret used for logging into the ALM Octane server +global.config.test.connection=Test Connection +global.config.test.connection.progress=Connecting the ALM Octane server... +global.config.impersonatedUser.title=Jenkins user +global.config.impersonatedUser.description=The user to impersonate (Jobs will be executed on behalf of this user) + +global.config.dynamic.instanceId.title=Show plugin instance ID + +global.config.suspend.title=Suspend Octane events +global.config.instanceId.title=Instance id +global.config.instanceId.description=An ID to uniquely identify this instance of the plugin. +delete_identity_btn=Delete ALM Octane server + +global.config.workspaceConf.title=Jenkins user for
specific workspaces +global.config.workspaceConf.description=Jenkins user for creating new pipelines in specific workspaces + +global.config.parameters.title=Parameters +global.config.parameters.description=Additional parameters \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-identity.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-identity.html new file mode 100644 index 0000000000..5eb17108e0 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-identity.html @@ -0,0 +1,41 @@ + + +
+ In ALM Octane, a pipeline’s unique identification includes this ID.
+ When should I change this value?
+
    +
  • When you install the OpenText Application Automation Tools plugin instead of the ALM Octane CI plugin, you need to make a change if you want to enable this plugin to work with existing pipelines: Change the instance ID to the one used by your pipelines in ALM Octane (Settings > DevOps > CI servers, “Instance ID” column).
  • +
    +
  • If you duplicate your Jenkins installation. Change the instance ID (in any way) to prevent results reported from the new copy of the plugin from being mixed in ALM Octane with results reported from the original one.
    To separately collect information from the new copy, create new pipelines.
  • +
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-impersonatedUser.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-impersonatedUser.html new file mode 100644 index 0000000000..5359682ac9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-impersonatedUser.html @@ -0,0 +1,47 @@ + + +
+The Jenkins user's account is used to run jobs that ALM Octane runs.

+ Notes: +
    +
  • + Make sure the user can log in to Jenkin and has the minimum permission required for this integration: Job Build permissions. +
  • +
  • + We strongly recommend specifying a Jenkins user for ALM Octane. +
  • +
  • + If you do not specify a Jenkins user, ALM Octane uses the Anonymous user, and is limited to Anonymous's user permissions. +
  • +
+
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-parameters.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-parameters.html new file mode 100644 index 0000000000..e5c349267d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-parameters.html @@ -0,0 +1,117 @@ + + +
+ Define additional parameters +
+ Format: param_name:param_value +
+ Use a separate line for each parameter. Any line that starts with '#' is defined as a comment and is not parsed. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Param nameValueDescription
ENCODE_CI_JOB_BASE64true/falseALM Octane includes a built-in Jetty web server, but there is a possibility to add an external web server such as Apache HTTP server or similar. + This is usually done to add one more security layer. Some such servers might not allow receiving requests with encoded slashes (%2F). + As a job name might contain a slash, this parameter allows base64 encoding for job IDs during sending test results, build logs, coverage and vulnerabilities data to ALM Octane. +
+ Default is false. Supported ALM Octane version 15.1.20 and above.
FORTIFY_SSC_TOKENauthentication token + Token for integration with Fortify Software Security Center (SSC). + See help information in ALM Octane Help Center. +
JOB_LIST_CACHE_ALLOWEDtrue/false + Allow to cache the list of Jenkins jobs that is used to show available jobs when creating pipelines or test runners in ALM Octane. Use this option only if it takes more than 1 minute to show existing jobs. +
+ The cache is updated only if required by ALM Octane, and the previous cache was updated more than one hour ago. The cache is not updated when adding/removing/renaming jobs. +
+ For manual update of cache, call to the following URL: <jenkins_url>/nga/api/v1/clear-job-list-cache +
+ The cache cannot be used with the feature "Jenkins user for specific workspaces". +
+ Default is false. +
SCM_REST_APItrue/falseThe plugin uses a dedicated REST API in order to send data on SCM commits to ALM Octane. This parameter allows to use the events mechanism instead of REST API. +
+ Default is true (Rest API). Supported ALM Octane version 15.1.21 and above.
UFT_TEST_RUNNER_FOLDERfolder pathALM Octane allows generation of discovery and execution jobs for UFT test runner. By default, those jobs are created in Jenkins root. This parameter allow to define the folder + in which those jobs will be created.
For example : my_team_folder/uft
UFT_TEST_CONNECTION_DISABLEDtrue/falseAllow to disable "Test Connection" validation that is done during creation of UFT test runner. Default is false.
ADD_GLOBAL_PARAMETERS_TO_TESTStrue/falseUsed for UFT test runners. Use this parameter if you need to pass ALM Octane details to UFT tests. These will then be used in future updates of ALM Octane entities by UFT tests (for example updating UDF fields). +
The MTBX format will contain additional parameters, as follows: + runId, suiteRunId, suiteId, octaneWorkspaceId, octaneSpaceId, octaneRunByUsername, octaneUrl, octaneConfigId. In addition, if your job contains other parameters that contains "octane"(case insensitive) in the name of parameter - they will be added. + +
+ Note that this parameter can also be set as a job parameter. +
+ Default is false.
+
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-sscBaseToken.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-sscBaseToken.html new file mode 100644 index 0000000000..e017be22d8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-sscBaseToken.html @@ -0,0 +1,35 @@ + + +
+ See help information in ALM Octane Help Center +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-uiLocation.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-uiLocation.html new file mode 100644 index 0000000000..f66b351dd4 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-uiLocation.html @@ -0,0 +1,45 @@ + + +
+ + The URL of the ALM Octane server, using its fully qualified domain name (FQDN). +
+ Use the following format (port number is optional): http://ALM_Octane_Host_Name / IP_address {:port number}/ui/?p=sharedSpaceID +
+
+ Example: http://myServer.myCompany.com:8081/ui/?p=1002 +
+
+ Tip: You can copy the URL from the address bar of the browser in which you opened ALM Octane. + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-username.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-username.html new file mode 100644 index 0000000000..a7198c607e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-username.html @@ -0,0 +1,35 @@ + + +
+Obtain a Client ID and Client secret from ALM Octane configuration. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-workspace2ImpersonatedUserConf.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-workspace2ImpersonatedUserConf.html new file mode 100644 index 0000000000..ee37b614e0 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OctaneServerSettingsGlobalConfiguration/help-workspace2ImpersonatedUserConf.html @@ -0,0 +1,51 @@ + + +
+ Define one or more Jenkins users for specific workspaces in ALM Octane (relevant for v15.0.60 and later). +
+ This user will be used to get jobs to ALM Octane when creating new pipelines in that specific workspace. +
+ For all other actions, the general Jenkins user defined in the basic plugin configuration is used. +

+ Important: The workspace-specific Jenkins user must have access to a subset of the jobs that are available to the general Jenkins user. You cannot have jobs that are available to the workspace-specific Jenkins user but not to the general Jenkins user. + +

+ The field is optional and does not need to include all workspaces. If a workspace does not contain a workspace-specific user, the general Jenkins user will be used. +
+ Format: 'Workspace ID: 'Jenkins user name', for example 1000:userForOctane. +

+ Use a separate line for each workspace. Any line that starts with '#' is defined as a comment and is not parsed. +
+ If the configuration is defined correctly, test connection will show an icon next to "Connection successful" with all available workspaces. If a workspace has a workspace-specific Jenkins user, the user name will appear, for example 2001 - workspace name (userForOctane). + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/config.jelly new file mode 100644 index 0000000000..9fdac3b595 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/config.jelly @@ -0,0 +1,38 @@ + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/help-outputEnvironmentParameters.html b/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/help-outputEnvironmentParameters.html new file mode 100644 index 0000000000..065fee51a4 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/OutputEnvironmentVariablesBuildWrapper/help-outputEnvironmentParameters.html @@ -0,0 +1,37 @@ + + +
+ Define a list of environment variables to store in ValueEdge / ALM Octane. + After the job is completed, Jenkins sends values of specified environment variables to ValueEdge / ALM Octane. + Delimit names of environment variables with a space or end of line (EOL). +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..6cf992081a --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/config.jelly @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-dateFormat.html b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-dateFormat.html new file mode 100644 index 0000000000..b7d603869b --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-dateFormat.html @@ -0,0 +1,38 @@ + + +
+ To display the timestamp on the UFT Report page in the desired format specify a SimpleDateFormat string. Consult the Oracle docs for examples. +
+ To fallback to the default pattern empty the field. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-defaultBranches.html b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-defaultBranches.html new file mode 100644 index 0000000000..32a94d8c4e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-defaultBranches.html @@ -0,0 +1,37 @@ + + +
+ To indicate default branch in multi-branch pipelines for getting parameters. +
+ Please use space as separator for default branches. For example, "main master trunk". +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-outputEnvironmentParameters.html b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-outputEnvironmentParameters.html new file mode 100644 index 0000000000..3b02b3b183 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/RunnerMiscSettingsGlobalConfiguration/help-outputEnvironmentParameters.html @@ -0,0 +1,39 @@ + + +
+ Define a global list of environment variables to store in ValueEdge / ALM Octane. This setting applies to all jobs. + After the job is completed, Jenkins sends values of specified environment variables to ValueEdge / ALM Octane. + Delimit names of environment variables with a space or end of line (EOL). +
+ To define job-specific list of environment variables to store, go to the Build Environment tab of that job. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..6f8a61bcc9 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/SvServerSettingsGlobalConfiguration/config.jelly @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+ + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration/config.jelly new file mode 100644 index 0000000000..05d9f80c3d --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/settings/UFTEncryptionGlobalConfiguration/config.jelly @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/FilterTestsModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/uft/model/FilterTestsModel/config.jelly new file mode 100644 index 0000000000..f89ed9904f --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/FilterTestsModel/config.jelly @@ -0,0 +1,68 @@ + + + + + + + + +
Run tests with names containing:
+ +
+ + +
Run tests with status:
+
+ + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel/config.jelly new file mode 100644 index 0000000000..5a1f5e8595 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/RerunSettingsModel/config.jelly @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/config.jelly new file mode 100644 index 0000000000..6f7f5992a8 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/config.jelly @@ -0,0 +1,128 @@ + + + + + + + +
    +
  • +

    # of test

    +

    Test name

    +

    Parameter name

    +

    Value

    +

    Type

    + +
  • +
+ + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/help-__emptyForHelp.html b/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/help-__emptyForHelp.html new file mode 100644 index 0000000000..c195d0c1be --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/SpecifyParametersModel/help-__emptyForHelp.html @@ -0,0 +1,33 @@ + + +
Select to which test in the test input field the parameter should be applied, counted from top to bottom and then specify all of its properties.
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/config.jelly b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/config.jelly new file mode 100644 index 0000000000..73be3a006b --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/config.jelly @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Select one test or more from the list bellow in order to apply the relevant options
+
+ + + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-cleanupTest.html b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-cleanupTest.html new file mode 100644 index 0000000000..14de417e45 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-cleanupTest.html @@ -0,0 +1,35 @@ + + +
+ Test executed before the re-run process of the failed tests. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-fsTestType.html b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-fsTestType.html new file mode 100644 index 0000000000..59df0fe816 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-fsTestType.html @@ -0,0 +1,36 @@ + + +
+ Select which test category will run again when build fails. The user can rerun the entire set of tests or only the failed tests from the suite. + If just certain tests fail, then only the selected tests will rerun. +
\ No newline at end of file diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-numberOfReruns.html b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-numberOfReruns.html new file mode 100644 index 0000000000..1c26c4fc50 --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-numberOfReruns.html @@ -0,0 +1,35 @@ + + +
+ Defines the maximum amount of test set reruns. +
diff --git a/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-selectedNode.html b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-selectedNode.html new file mode 100644 index 0000000000..11c710a90e --- /dev/null +++ b/src/main/resources/com/microfocus/application/automation/tools/uft/model/UftSettingsModel/help-selectedNode.html @@ -0,0 +1,35 @@ + + +
+ Please select the corresponding slave machine setup in the main job configuration. +
diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly index 150ce3f3f0..95703227e5 100644 --- a/src/main/resources/index.jelly +++ b/src/main/resources/index.jelly @@ -1,7 +1,39 @@ + +
- This plugin enables integration with HPE products, such as: ALM, ALM Octane, Unified Functional Testing, LoadRunner, and Performance Center. + This plugin enables integration with ALM, ALM Octane, Unified Functional Testing, LoadRunner, and LoadRunner Enterprise.
diff --git a/src/main/resources/lib/custom/customEntry.jelly b/src/main/resources/lib/custom/customEntry.jelly new file mode 100644 index 0000000000..ecb76fe951 --- /dev/null +++ b/src/main/resources/lib/custom/customEntry.jelly @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/lib/custom/customOptionalBlock.jelly b/src/main/resources/lib/custom/customOptionalBlock.jelly new file mode 100644 index 0000000000..4a0cb3ddcb --- /dev/null +++ b/src/main/resources/lib/custom/customOptionalBlock.jelly @@ -0,0 +1,101 @@ + + + + + + Foldable block that can be expanded to show more controls by checking the checkbox. + + + Name of the checkbox. Can be used by the server to determine + if the block is collapsed or expanded at the time of submission. + + Note that when the block is collapsed, none of its child controls will send + the values to the server (unlike <f:advanced>) + + + Human readable text that follows the checkbox. + + If this field is null, the checkbox degrades to a <f:rowSet>, which provides + a grouping at JSON level but on the UI there's no checkbox (and you always see + the body of it.) + + + Used for databinding. TBD. Either this or @name/@title combo is required. + + + initial checkbox status. true/false. + + + If present, the (?) icon will be rendered on the right to show inline help. + See @help for <f:entry>. + + + if present, the foldable section expands when the checkbox is unchecked. + + + if present, the foldable section will not be grouped into a separate JSON object upon submission + + + + + + + + + + + + + + + + + + + + + +
+ +
+
${header}
+ + + + +
+ + +
+ +
${header}
+ +
+
+ + + + + +
+
${header}
+ +
+
+
+ +
+ + + + + + + + + + + + +
+ diff --git a/src/main/resources/lib/custom/customRepeatableProperty.jelly b/src/main/resources/lib/custom/customRepeatableProperty.jelly new file mode 100644 index 0000000000..b2583c0472 --- /dev/null +++ b/src/main/resources/lib/custom/customRepeatableProperty.jelly @@ -0,0 +1,40 @@ + + + + + + + + +
+
+ +
diff --git a/src/main/resources/lib/custom/taglib b/src/main/resources/lib/custom/taglib new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/resources/lib/healthanalyzer/customEntry.jelly b/src/main/resources/lib/healthanalyzer/customEntry.jelly new file mode 100644 index 0000000000..c09add42a4 --- /dev/null +++ b/src/main/resources/lib/healthanalyzer/customEntry.jelly @@ -0,0 +1,97 @@ + + + + + + + + An entry of the <f:form>, which is one logical row (that consists of + several <TR> tags. + + One entry normally host one control. + + + Name of the entry. Think of this like a label for the control. + + This content is HTML (unless the boolean variable escapeEntryTitleAndDescription is set). Use h.escape if necessary. + + + Used for the databinding. TBD. When this attribute + is specified, @help is inferred, and nested input controls don't need + the @field nor @name. + + + If it's not obvious to the user as to what the control expects, + specify some description text (which currently gets rendered as + small text under the control, but that may change.) + + This text shouldn't get too long, and in recent Hudson, this feature + is somewhat de-emphasized, in favor of the inline foldable help page + specified via @help. + + This content is HTML (unless the boolean variable escapeEntryTitleAndDescription is set). Use h.escape if necessary. + + + URL to the HTML page. When this attribute is specified, the entry gets + a (?) icon on the right, and if the user clicks it, the contents of the + given URL is rendered as a box below the entry. + + The URL should return an HTML document wrapped in a <div> tag. + The URL is interpreted to be rooted at the context path of Hudson, + so it's normally something like "/plugin/foobar/help/abc.html". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/lib/healthanalyzer/customOptionalBlock.jelly b/src/main/resources/lib/healthanalyzer/customOptionalBlock.jelly new file mode 100644 index 0000000000..6429753bc8 --- /dev/null +++ b/src/main/resources/lib/healthanalyzer/customOptionalBlock.jelly @@ -0,0 +1,100 @@ + + + + + + + + Foldable block that can be expanded to show more controls by checking the checkbox. + + + Name of the checkbox. Can be used by the server to determine + if the block is collapsed or expanded at the time of submission. + + Note that when the block is collapsed, none of its child controls will send + the values to the server (unlike <f:advanced>) + + + Human readable text that follows the checkbox. + + If this field is null, the checkbox degrades to a <f:rowSet>, which provides + a grouping at JSON level but on the UI there's no checkbox (and you always see + the body of it.) + + + Used for databinding. TBD. Either this or @name/@title combo is required. + + + initial checkbox status. true/false. + + + If present, the (?) icon will be rendered on the right to show inline help. + See @help for <f:entry>. + + + if present, the foldable section expands when the checkbox is unchecked. + + + if present, the foldable section will not be grouped into a separate JSON object upon submission + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/lib/healthanalyzer/optionalDropDownList.jelly b/src/main/resources/lib/healthanalyzer/optionalDropDownList.jelly new file mode 100644 index 0000000000..f1d95570ab --- /dev/null +++ b/src/main/resources/lib/healthanalyzer/optionalDropDownList.jelly @@ -0,0 +1,65 @@ + + + + + + + Optional block with checkbox that opens a ListBoxModel. + + The title of the optional block + + + The field the holds the selected list needs to be wrapped in a class. + For example see: RepeatableField class + + + Checks if the checkbox is toggled by checking if the field is not null + + + The title that is next to the drop down list + + + The inner class field. + It's name should be the same as it is declared in the class. + For example: in RepeatableField class the field that holds the value called "field", and it has a getter + named "getField" inside the drop down list class. + + + + + + + + + + diff --git a/src/main/resources/lib/healthanalyzer/optionalRepeatableText.jelly b/src/main/resources/lib/healthanalyzer/optionalRepeatableText.jelly new file mode 100644 index 0000000000..27cf299fe4 --- /dev/null +++ b/src/main/resources/lib/healthanalyzer/optionalRepeatableText.jelly @@ -0,0 +1,65 @@ + + + + + + Optional block with repeatable text field. + + The method name that asserts if the list is toggled or not, mostly if the instance is + initialized and contains elements + + + The outer class name of the instance which holds the list + + + The title next to the checkbox + + + The title next to the text field + + + The inner field in the class which holds the list of the repeatable item of the type "RepeatableField.java" + That exposes a method to the inner field list + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/lib/healthanalyzer/taglib b/src/main/resources/lib/healthanalyzer/taglib new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidth.jelly b/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidth.jelly new file mode 100644 index 0000000000..07203595fa --- /dev/null +++ b/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidth.jelly @@ -0,0 +1,44 @@ + + + + + + + +
+ +
+
+ + + +
+
+
+
\ No newline at end of file diff --git a/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidthId.jelly b/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidthId.jelly new file mode 100644 index 0000000000..95e8605971 --- /dev/null +++ b/src/main/resources/lib/hp-application-automation-tools/blockWrapperTableWidthId.jelly @@ -0,0 +1,44 @@ + + + + + + + +
+ +
+
+ + + +
+
+
+
\ No newline at end of file diff --git a/src/main/resources/lib/hp-application-automation-tools/taglib b/src/main/resources/lib/hp-application-automation-tools/taglib new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/resources/lib/octane/configure.js b/src/main/resources/lib/octane/configure.js index 08aa2d4a71..02632cc866 100644 --- a/src/main/resources/lib/octane/configure.js +++ b/src/main/resources/lib/octane/configure.js @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + function octane_job_configuration(target, progress, proxy) { if (typeof jQuery === 'undefined') { @@ -19,19 +51,52 @@ function octane_job_configuration(target, progress, proxy) { return left.toLowerCase() === right.toLowerCase(); } - function configure() { + function loadJobConfigurationFromServer(sharedspace) { progressFunc("Retrieving configuration from server"); - proxy.loadJobConfigurationFromServer(function (t) { + + proxy.loadJobConfigurationFromServer(sharedspace.id, function (t) { progressFunc(); var response = t.responseObject(); if (response.errors) { response.errors.forEach(renderError); } else { - renderConfiguration(response); + renderConfiguration(response, undefined, sharedspace.id); } }); } + function configure() { + proxy.searchSharedSpaces("", (function (sharedspaces) { + if(sharedspaces.responseJSON.results.length===1){ + loadJobConfigurationFromServer(sharedspaces.responseJSON.results[0]); + }else{ + var sharedspaceDiv = $("
"); + $(target).append(sharedspaceDiv); + $("#sharedspaceSelect").select2({ + placeholder: 'Select a configuration', + ajax: { + dataType: 'json', + delay: 250, + transport: function (params, success, failure) { + var term = ""; + if (params.data.hasOwnProperty("q") && params.data.q !== undefined) {term = params.data.q;} + proxy.searchSharedSpaces(term, (function (data) { + queryToMqmCallback(data, success, failure) + })); + }, + cache: true + }, + templateResult: formatSelect2Option + }); + $("#sharedspaceSelect").on("select2:select", function(e) { + loadJobConfigurationFromServer(e.params.data); + }); + } + })); + + + } + function renderError(error) { var errorDiv = $("
"); errorDiv.find("b").text(error.message); @@ -55,7 +120,7 @@ function octane_job_configuration(target, progress, proxy) { } } - function renderConfiguration(jobConfiguration, pipelineId) { + function renderConfiguration(jobConfiguration, pipelineId, instanceId) { var result = $(target); result.empty(); @@ -76,6 +141,8 @@ function octane_job_configuration(target, progress, proxy) { var apply = []; var dirtyFlag; + var selectedReleaseId; + function initialize() { validators.length = 0; apply.length = 0; @@ -132,6 +199,12 @@ function octane_job_configuration(target, progress, proxy) { function renderPipelineMetadata(pipeline, pipelineSelector) { var table = $("
"); pipelineDiv.append(table); + + var releaseMilestoneAlertMessage = "
Note: When you change a milestone or release, a new set of runs is created on ALM Octane, " + + "with a new run history.
"; + + pipelineDiv.append(releaseMilestoneAlertMessage); + var tbody = table.find("tbody"); var tr = tbody.find("tr"); @@ -176,7 +249,7 @@ function octane_job_configuration(target, progress, proxy) { // NAME if (pipeline.isRoot) { - var tdPipelineInput = $("
"); + var tdPipelineInput = $("
"); tr.append(tdPipelineInput); var input = tdPipelineInput.find("input"); @@ -227,21 +300,60 @@ function octane_job_configuration(target, progress, proxy) { var tdReleaseSelect = $(""); trRelease.append(tdReleaseSelect); - var select = $(""); + releaseSelect.append($("
"); var workspaceSelect = selectWorkspaceDiv.find("select"); //sort workspaces by name to show in UI @@ -771,6 +887,14 @@ function octane_job_configuration(target, progress, proxy) { } } + function isMilestoneSpecified(pipeline) { + if (pipeline.hasOwnProperty("milestoneId") && pipeline.milestoneId !== -1) { + return true; + } else { + return false; + } + } + function makeDirty() { dirtyFlag = true; } @@ -883,7 +1007,7 @@ function octane_job_configuration(target, progress, proxy) { }; } - function newTagTypeValidation(tagTypeInput, workspaceId, callback) { + function newTagTypeValidation(tagTypeInput, instanceId, workspaceId, callback) { return function () { var error = undefined; @@ -918,7 +1042,7 @@ function octane_job_configuration(target, progress, proxy) { if (!tagTypeInput.val()) { return "Environment type must be specified"; } - proxy.searchTaxonomies(tagTypeInput.val(), workspaceId, [], searchTaxCallback); + proxy.searchTaxonomies(tagTypeInput.val(), instanceId, workspaceId, [], searchTaxCallback); }; } @@ -1003,7 +1127,7 @@ function octane_job_configuration(target, progress, proxy) { var term = ""; if (params.data.hasOwnProperty("q") && params.data.q !== undefined) {term = params.data.q;} var listId = 0; - proxy.searchListItems(selector.logicalListName, term, pipeline.workspaceId, selector.multiValue, selector.extensible, (function (data) { + proxy.searchListItems(selector.logicalListName, term, pipeline.instanceId, pipeline.workspaceId, selector.multiValue, selector.extensible, (function (data) { queryToMqmCallback(data, success, failure) })); }, @@ -1021,7 +1145,7 @@ function octane_job_configuration(target, progress, proxy) { transport: function (params, success, failure) { var term = ""; if (params.data.hasOwnProperty("q") && params.data.q !== undefined) {term = params.data.q;} - proxy.searchTaxonomies(term, pipeline.workspaceId, pipeline.taxonomyTags, (function (data) { + proxy.searchTaxonomies(term, pipeline.instanceId, pipeline.workspaceId, pipeline.taxonomyTags, (function (data) { queryToMqmCallback(data, success, failure) })); }, @@ -1053,7 +1177,30 @@ function octane_job_configuration(target, progress, proxy) { } else { tmpWorkspaceId = pipeline.workspaceId; } - proxy.searchReleases(term, tmpWorkspaceId, (function (data) { + proxy.searchReleases(term, pipeline.instanceId, tmpWorkspaceId, (function (data) { + queryToMqmCallback(data, success, failure) + })); + }, + cache: true + }, + templateResult: formatSelect2Option + }); + + $("#milestoneSelect").select2({ + ajax: { + dataType: 'json', + delay: 250, + transport: function (params, success, failure) { + var term = ""; + var tmpWorkspaceId; + if (params.data.hasOwnProperty("q") && params.data.q !== undefined) {term = params.data.q;} + if (!pipeline.id) { + tmpWorkspaceId = selectedWorkspaceId; + } else { + tmpWorkspaceId = pipeline.workspaceId; + } + + proxy.searchMilestones(term, pipeline.instanceId, tmpWorkspaceId, selectedReleaseId, (function (data) { queryToMqmCallback(data, success, failure) })); }, @@ -1070,7 +1217,8 @@ function octane_job_configuration(target, progress, proxy) { transport: function (params, success, failure) { var term = ""; if (params.data.hasOwnProperty("q") && params.data.q !== undefined) {term = params.data.q;} - proxy.searchWorkspaces(term, (function (data) { + var instanceId = jobConfiguration.currentPipeline.instanceId; + proxy.searchWorkspaces(term, instanceId, (function (data) { queryToMqmCallback(data, success, failure) })); }, @@ -1078,7 +1226,6 @@ function octane_job_configuration(target, progress, proxy) { }, templateResult: formatSelect2Option }); - fieldSelectors.forEach(createFieldsSelect2); }); } diff --git a/src/main/resources/lib/octane/ui.css b/src/main/resources/lib/octane/ui.css index 37e4b66977..c2b80e1ee9 100644 --- a/src/main/resources/lib/octane/ui.css +++ b/src/main/resources/lib/octane/ui.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + body * { box-sizing: border-box; } @@ -239,5 +271,17 @@ body { .rpos { position: absolute; - right: 20px; + right: 50px; +} + +.config-label { + text-decoration: none; + font-size: 12px; + border: 1px solid transparent; + border-radius: 3px; + line-height: 26px; + height: 26px; + vertical-align: middle; + display: inline-block; + padding: 0 10px; } diff --git a/src/main/resources/lib/select2/select2-min.js b/src/main/resources/lib/select2/select2-min.js index 49a988c7ab..367ced608e 100644 --- a/src/main/resources/lib/select2/select2-min.js +++ b/src/main/resources/lib/select2/select2-min.js @@ -1,2 +1,24 @@ +/* + * + * Certain versions of software and/or documents (“Material”) accessible here may contain branding from + * Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, + * the Material is now offered by Micro Focus, a separately owned and operated company. 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-2019 Micro Focus or one of its affiliates.. + * + * The only warranties for products and services of Micro Focus and its affiliates + * and licensors (“Micro Focus”) are set forth in the express warranty statements + * accompanying such products and services. Nothing herein should be construed as + * constituting an additional warranty. Micro Focus shall not be liable for technical + * or editorial errors or omissions contained herein. + * The information contained herein is subject to change without notice. + * ___________________________________________________________________ + * + */ + /*! Select2 4.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){return n.apply(b,v.call(arguments,0).concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;hc;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
    ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('
  • '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),this.$results.append(d)},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")});var f=e.filter("[aria-selected=true]");f.length>0?f.first().trigger("mouseenter"):e.first().trigger("mouseenter")})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";{a(h)}this.template(b,h);for(var i=[],j=0;j",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b){var c=this,d=b.id+"-results";this.$results.attr("id",d),b.on("results:all",function(a){c.clear(),c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("results:append",function(a){c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("query",function(a){c.showLoading(a)}),b.on("select",function(){b.isOpen()&&c.setClasses()}),b.on("unselect",function(){b.isOpen()&&c.setClasses()}),b.on("open",function(){c.$results.attr("aria-expanded","true"),c.$results.attr("aria-hidden","false"),c.setClasses(),c.ensureHighlightVisible()}),b.on("close",function(){c.$results.attr("aria-expanded","false"),c.$results.attr("aria-hidden","true"),c.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=c.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=c.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?c.trigger("close"):c.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a);if(0!==d){var e=d-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top,h=f.offset().top,i=c.$results.scrollTop()+(h-g);0===e?c.$results.scrollTop(0):0>h-g&&c.$results.scrollTop(i)}}),b.on("results:next",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a),e=d+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top+c.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=c.$results.scrollTop()+h-g;0===e?c.$results.scrollTop(0):h>g&&c.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){c.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=c.$results.scrollTop(),d=c.$results.get(0).scrollHeight-c.$results.scrollTop()+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&d<=c.$results.height();e?(c.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(c.$results.scrollTop(c.$results.get(0).scrollHeight-c.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var d=a(this),e=d.data("data");return"true"===d.attr("aria-selected")?void(c.options.get("multiple")?c.trigger("unselect",{originalEvent:b,data:e}):c.trigger("close")):void c.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var b=a(this).data("data");c.getHighlightedResults().removeClass("select2-results__option--highlighted"),c.trigger("results:focus",{data:b,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a){var b=this,d=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){b.trigger("focus",a)}),this.$selection.on("blur",function(a){b.trigger("blur",a)}),this.$selection.on("keydown",function(a){b.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){b.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){b.update(a.data)}),a.on("open",function(){b.$selection.attr("aria-expanded","true"),b.$selection.attr("aria-owns",d),b._attachCloseHandler(a)}),a.on("close",function(){b.$selection.attr("aria-expanded","false"),b.$selection.removeAttr("aria-activedescendant"),b.$selection.removeAttr("aria-owns"),b.$selection.focus(),b._detachCloseHandler(a)}),a.on("enable",function(){b.$selection.attr("tabindex",b._tabindex)}),a.on("disable",function(){b.$selection.attr("tabindex","-1")})},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},d.prototype.bind=function(a){var b=this;d.__super__.bind.apply(this,arguments);var c=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",c),this.$selection.attr("aria-labelledby",c),this.$selection.on("mousedown",function(a){1===a.which&&b.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),a.on("selection:update",function(a){b.update(a.data)})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){return a("")},d.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.display(b),d=this.$selection.find(".select2-selection__rendered");d.empty().append(c),d.prop("title",b.title||b.text)},d}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
      '),a},d.prototype.bind=function(){var b=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){b.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(c){var d=a(this),e=d.parent(),f=e.data("data");b.trigger("unselect",{originalEvent:c,data:f})})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){var b=a('
    • ×
    • ');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},a}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus()}),b.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.focus()}),b.on("enable",function(){e.$search.prop("disabled",!1)}),b.on("disable",function(){e.$search.prop("disabled",!0)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e.trigger("blur",a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}}),this.$selection.on("input",".select2-search--inline",function(){e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input",".select2-search--inline",function(a){e.handleSearch(a)})},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.trigger("open"),this.$search.val(b.text+" ")},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=(c.extend(!0,{},l,j),this.option(l));k.replaceWith(m)}else{var n=this.option(j);if(j.children){var o=this.convertToOptions(j.children);b.appendMany(n,o)}h.push(n)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(b,c){this.ajaxOptions=this._applyDefaults(c.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),a.__super__.constructor.call(this,b,c)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return{q:a.term}},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url(a)),"function"==typeof f.data&&(f.data=f.data(a)),this.ajaxOptions.delay&&""!==a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");if(void 0!==f&&(this.createTag=f),b.call(this,c,d),a.isArray(e))for(var g=0;g0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.position=function(){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a){function b(){}return b.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},b.prototype.handleSearch=function(){if(!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},b.prototype.showSearch=function(){return!0},b}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
    • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(a,b,c){this.$dropdownParent=c.get("dropdownParent")||document.body,a.call(this,b,c)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c){var d=this,e="scroll.select2."+c.id,f="resize.select2."+c.id,g="orientationchange.select2."+c.id,h=this.$container.parents().filter(b.hasScroll);h.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),h.on(e,function(){var b=a(this).data("select2-scroll-position");a(this).scrollTop(b.y)}),a(window).on(e+" "+f+" "+g,function(){d._positionDropdown(),d._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c){var d="scroll.select2."+c.id,e="resize.select2."+c.id,f="orientationchange.select2."+c.id,g=this.$container.parents().filter(b.hasScroll);g.off(d),a(window).off(d+" "+e+" "+f)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=(this.$container.position(),this.$container.offset());f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom};c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){this.$dropdownContainer.width();var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.selectionAdapter=l.multiple?e:d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(this.options.dir=a.prop("dir")?a.prop("dir"):a.closest("[dir]").prop("dir")?a.closest("[dir]").prop("dir"):"ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this._sync=c.bind(this._syncAttributes,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._sync);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._sync)}),this._observer.observe(this.$element[0],{attributes:!0,subtree:!1})):this.$element[0].addEventListener&&this.$element[0].addEventListener("DOMAttrModified",b._sync,!1)},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("focus",function(){a.$container.addClass("select2-container--focus")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open"),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ENTER?(a.trigger("results:select"),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle"),b.preventDefault()):c===d.UP?(a.trigger("results:previous"),b.preventDefault()):c===d.DOWN?(a.trigger("results:next"),b.preventDefault()):(c===d.ESC||c===d.TAB)&&(a.close(),b.preventDefault()):(c===d.ENTER||c===d.SPACE||(c===d.DOWN||c===d.UP)&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable")):this.trigger("enable")},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||(this.trigger("query",{}),this.trigger("open"))},e.prototype.close=function(){this.isOpen()&&this.trigger("close")},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._sync),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&this.$element[0].removeEventListener("DOMAttrModified",this._sync,!1),this._sync=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery.select2",["jquery","require","./select2/core","./select2/defaults"],function(a,b,c,d){if(b("jquery.mousewheel"),null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){{var d=a.extend({},b,!0);new c(a(this),d)}}),this;if("string"==typeof b){var d=this.data("select2");null==d&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2.");var f=Array.prototype.slice.call(arguments,1),g=d[b](f);return a.inArray(b,e)>-1?this:g}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),b.define("jquery.mousewheel",["jquery"],function(a){return a}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c}); \ No newline at end of file diff --git a/src/main/webapp/ParallelRunner/icons/png/chrome.png b/src/main/webapp/ParallelRunner/icons/png/chrome.png new file mode 100644 index 0000000000..38f125e36a Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/chrome.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/chrome@2x.png b/src/main/webapp/ParallelRunner/icons/png/chrome@2x.png new file mode 100644 index 0000000000..ec0774bf89 Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/chrome@2x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/chrome@3x.png b/src/main/webapp/ParallelRunner/icons/png/chrome@3x.png new file mode 100644 index 0000000000..1559d10c52 Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/chrome@3x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/explorer.png b/src/main/webapp/ParallelRunner/icons/png/explorer.png new file mode 100644 index 0000000000..4861930752 Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/explorer.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/explorer@2x.png b/src/main/webapp/ParallelRunner/icons/png/explorer@2x.png new file mode 100644 index 0000000000..38d82b40a1 Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/explorer@2x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/explorer@3x.png b/src/main/webapp/ParallelRunner/icons/png/explorer@3x.png new file mode 100644 index 0000000000..34f07e21a1 Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/explorer@3x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/firefox.png b/src/main/webapp/ParallelRunner/icons/png/firefox.png new file mode 100644 index 0000000000..b062a2d0cf Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/firefox.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/firefox@2x.png b/src/main/webapp/ParallelRunner/icons/png/firefox@2x.png new file mode 100644 index 0000000000..d97d58bc9f Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/firefox@2x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/png/firefox@3x.png b/src/main/webapp/ParallelRunner/icons/png/firefox@3x.png new file mode 100644 index 0000000000..4a303a2a0c Binary files /dev/null and b/src/main/webapp/ParallelRunner/icons/png/firefox@3x.png differ diff --git a/src/main/webapp/ParallelRunner/icons/svg/chrome.svg b/src/main/webapp/ParallelRunner/icons/svg/chrome.svg new file mode 100644 index 0000000000..57caf0e354 --- /dev/null +++ b/src/main/webapp/ParallelRunner/icons/svg/chrome.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/ParallelRunner/icons/svg/explorer.svg b/src/main/webapp/ParallelRunner/icons/svg/explorer.svg new file mode 100644 index 0000000000..ae9c6f8789 --- /dev/null +++ b/src/main/webapp/ParallelRunner/icons/svg/explorer.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/ParallelRunner/icons/svg/firefox.svg b/src/main/webapp/ParallelRunner/icons/svg/firefox.svg new file mode 100644 index 0000000000..1583e63467 --- /dev/null +++ b/src/main/webapp/ParallelRunner/icons/svg/firefox.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/PerformanceReport/VuGen.png b/src/main/webapp/PerformanceReport/VuGen.png new file mode 100644 index 0000000000..eba5a5bfba Binary files /dev/null and b/src/main/webapp/PerformanceReport/VuGen.png differ diff --git a/src/main/webapp/autEnvironment.js b/src/main/webapp/autEnvironment.js index 1bd6955ac5..a26e4cba43 100644 --- a/src/main/webapp/autEnvironment.js +++ b/src/main/webapp/autEnvironment.js @@ -1,38 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + /** * Created by barush on 09/11/2014. */ -function checkCorrespondingCheckbox(e) { - - var parentTableNode = getAncestorByTagName(e, 'table'); - var nearestCheckbox = parentTableNode.getElementsByClassName('autEnvParameterCheckbox')[0]; - - if (e.value === 'From JSON') { - nearestCheckbox.style.display = 'inline'; - } else { - nearestCheckbox.style.display = 'none'; - } +function showOrHideCheckbox(el) { + var panel = el.parentElement.closest("div[name=autEnvironmentParameters]"); + var chk = panel.querySelector('.aut-env-param-chk-lbl'); + chk.style.display = (el.value === "From JSON"? "inline" : "none"); } function updateValuesOnLoad() { - var elementsByClassName = document.getElementsByClassName('autEnv'); + var autEnvs = document.querySelectorAll('.aut-env'); var i; - for (i = 0; elementsByClassName.length > i; i++) { - checkCorrespondingCheckbox(elementsByClassName[i]); + for (i = 0; autEnvs.length > i; i++) { + showOrHideCheckbox(autEnvs[i]); } } -function getAncestorByTagName(el, tn) { - tn = tn.toLowerCase(); - if (el.parentNode) { - if (el.parentNode.nodeType == 1 - && el.parentNode.tagName.toLowerCase() == tn - ) return el.parentNode; - return getAncestorByTagName(el.parentNode, tn); - } - return null -} - - -setTimeout(updateValuesOnLoad(), 0); - +setTimeout(updateValuesOnLoad(), 0); \ No newline at end of file diff --git a/src/main/webapp/configure.js b/src/main/webapp/configure.js index d2898bd971..5c11bd6cea 100644 --- a/src/main/webapp/configure.js +++ b/src/main/webapp/configure.js @@ -1,87 +1,388 @@ -function load(a,path){ - var buttonStatus = false; - if(buttonStatus) return; - buttonStatus = true; - var mcUserName = document.getElementsByName("runfromfs.fsUserName")[0].value; - var mcPassword = document.getElementsByName("runfromfs.fsPassword")[0].value; - var mcUrl = document.getElementsByName("runfromfs.mcServerName")[0].value; - var useProxy = document.getElementsByName("proxySettings")[0].checked; - var proxyAddress = document.getElementsByName("runfromfs.fsProxyAddress")[0].value; - var useAuthentication = document.getElementsByName("runfromfs.fsUseAuthentication")[0].checked; - var proxyUserName = document.getElementsByName("runfromfs.fsProxyUserName")[0].value; - var proxyPassword = document.getElementsByName("runfromfs.fsProxyPassword")[0].value; - var baseUrl = ""; - if(mcUserName == '' || mcPassword == ''|| (useProxy && proxyAddress == '') || (useAuthentication && (proxyUserName == '' || proxyPassword == ''))){ - document.getElementById("errorMessage").style.display = "block"; - buttonStatus = false; - return; +/* + * 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. + * ___________________________________________________________________ + */ +if (typeof RUN_FROM_FS_BUILDER_SELECTOR == "undefined") { + RUN_FROM_FS_BUILDER_SELECTOR = 'div[name="builder"][descriptorid="com.microfocus.application.automation.tools.run.RunFromFileBuilder"]'; +} +//const templates = { "regions": [ "Europe (Frankfurt)" ], "os": [ "Windows Server 2022" ], "browsers": [ { "type": "Chrome", "versions": [ { "version": "117", "tag": "117" }, { "version": "117", "tag": "latest" }, { "version": "116", "tag": "latest-1" }, { "version": "116", "tag": "116" }, { "version": "115", "tag": "latest-2" }, { "version": "115", "tag": "115" } ] }, { "type": "Edge", "versions": [ { "version": "117", "tag": "117" }, { "version": "117", "tag": "latest" }, { "version": "116", "tag": "latest-1" }, { "version": "116", "tag": "116" }, { "version": "115", "tag": "latest-2" }, { "version": "115", "tag": "115" } ] }, { "type": "Firefox", "versions": [ { "version": "117", "tag": "117" }, { "version": "117", "tag": "latest" }, { "version": "116", "tag": "latest-1" }, { "version": "116", "tag": "116" }, { "version": "115", "tag": "latest-2" }, { "version": "115", "tag": "115" } ] } ] } + +function getDigitalLab(divMain) { + const dl = divMain.querySelector("#mobileSpecificSection"); + const o = { serverName: dl.querySelector('select[name="mcServerName"]').value, + userName: "", + password: "", + tenantId: "", + execToken: "", + authType: dl.querySelector('input[name$="authModel"]:checked').value, + useProxy: dl.querySelector('input[name="proxySettings"]').checked, + proxyAddress: "", + useProxyAuth: false, + proxyUserName: "", + proxyPassword: "", + recreateJob: dl.querySelector('input[name="recreateJob"]').checked, + jobId: dl.querySelector('input[name="fsJobId"]').value, + deviceInfo: dl.querySelector(".device-info-section") + }; + if (o.authType == "base") { + o.userName = dl.querySelector('input[name="mcUserName"]').value; + o.password = dl.querySelector('input[name="mcPassword"]').value; + o.tenantId = dl.querySelector('input[name="mcTenantId"]').value; + } else { + o.execToken = dl.querySelector('input[name="mcExecToken"]').value; + } + if (o.useProxy) { + o.proxyAddress = dl.querySelector('input[name="fsProxyAddress"]').value; + o.useProxyAuth = dl.querySelector('input[name="fsUseAuthentication"]').checked; + if (o.useProxyAuth) { + o.proxyUserName = dl.querySelector('input[name="fsProxyUserName"]').value; + o.proxyPassword = dl.querySelector('input[name="fsProxyPassword"]').value; + } + } + + return o; +} + +function startLoadInfo(a, b, path) { + triggerBtnState(b, true); + setTimeout( async () => { + await loadInfo(a, b, path)}, 100); +} + +async function triggerBtnState(b, disabled) { + b.disabled = disabled; + if (b.name == "cloudBrowserLab") { + b.value = disabled ? "Loading ..." : "Browser settings"; + } else if (b.name == "digitalLabWizard") { + b.value = disabled ? "Loading ..." : "Wizard"; + } else if (b.name == "env-wizard") { + b.value = disabled ? "Loading ..." : "Environment wizard"; + } +} +async function loadInfo(a, b, path) { + let dl = {}; + try { + const divMain = b.parentElement.closest(RUN_FROM_FS_BUILDER_SELECTOR); + const err = b.parentElement.querySelector(".error-msg"); + dl = getDigitalLab(divMain); + err.style.display = "none"; + const isMcCredentialMissing = ("base" == dl.authType ? (dl.userName.trim() == "" || dl.password.trim() == "") : dl.execToken.trim() == ""); + + const isProxyAddressRequiredButMissing = dl.useProxy && dl.proxyAddress.trim() == ""; + const isProxyCredentialRequiredButMissing = dl.useProxyAuth && (dl.proxyUserName.trim() == "" || dl.proxyPassword.trim() == ""); + if (isMcCredentialMissing || isProxyAddressRequiredButMissing || isProxyCredentialRequiredButMissing) { + err.style.display = "inline-block"; + await triggerBtnState(b, false); + return; + } + + if (b.name == "cloudBrowserLab") { + await loadBrowserLabInfo(a, b, dl, path, err); + } else if (b.name == "digitalLabWizard") { + await loadMobileInfo(a, b, dl, err); + } + } catch (e) { + console.error(e); + err.style.display = "inline-block"; + await triggerBtnState(b, false); + } + } + +async function fillAndShowDDLs(b, div, dlg) { + await loadOsDDL(dlg, div.oses); + await loadBrowserAndVersionDDLs(dlg, div.browsers); + await loadRegionDDL(dlg, div.regions); + await triggerBtnState(b, false); + dlg.style.display = "block"; +} +async function loadBrowserLabInfo(a, b, o, path, err) { + const div = b.parentElement.closest("#mobileSpecificSection"); + const dlg = await generateModalDialog(path); + div.appendChild(dlg); + if (div.browsers?.length) { + await fillAndShowDDLs(b, div, dlg); + } else { + await a.getBrowserLab(o.serverName, o.execToken, o.useProxyAuth, o.proxyAddress, o.proxyUserName, o.proxyPassword, async (response) => { + try { + if (response?.responseJSON) { + const json = response.responseJSON; + div.oses = json.os; + div.browsers = json.browsers; + div.regions = json.regions; + await fillAndShowDDLs(b, div, dlg); + } else { + err.style.display = "inline-block"; + await triggerBtnState(b, false); + } + } catch (e) { + console.error(e); + await triggerBtnState(b, false); + } + }); } - a.getMcServerUrl(mcUrl, function(r){ +} + +async function loadMobileInfo(a, b, o, err) { + let baseUrl = ""; + await a.getMcServerUrl(o.serverName, async (r) => { baseUrl = r.responseObject(); - a.getJobId(baseUrl,mcUserName, mcPassword, proxyAddress, proxyUserName, proxyPassword, function (response) { - var jobResponse = response.responseObject(); - if(jobResponse == null){ - document.getElementById("errorMessage").style.display = "block"; - buttonStatus = false; + if (baseUrl) { + baseUrl = baseUrl.trim().replace(/[\/]+$/, ""); + } else { + err.style.display = "inline-block"; + await triggerBtnState(b, false); + return; + } + let prevJobId = o.recreateJob ? "" : o.jobId; + await a.getJobId(baseUrl, o.userName, o.password, o.tenantId, o.execToken, o.authType, o.useProxyAuth, o.proxyAddress, o.proxyUserName, o.proxyPassword, prevJobId, async (response) => { + let jobId = response.responseObject(); + if (jobId == null) { + err.style.display = "inline-block"; + await triggerBtnState(b, false); return; } - var openedWindow = window.open(baseUrl+path+jobResponse+'&displayUFTMode=true&appType=native','test parameters','height=820','width=1130'); - var messageCallBack = function (event) { - if (event && event.data && event.data=="mcCloseWizard") { - a.populateAppAndDevice(baseUrl,mcUserName,mcPassword,proxyAddress, proxyUserName, proxyPassword,jobResponse, function (app) { - var jobInfo = app.responseObject(); - var deviceId = ""; - var OS = ""; - var manufacturerAndModel = ""; - var targetLab = ""; - if(jobInfo['deviceJSON']){ - if(jobInfo['deviceJSON']['deviceId']){ + //hide the error message after success login + err.style.display = "none"; + let openedWindow = window.open('/', 'test parameters', 'height=820,width=1130'); + openedWindow.location.href = 'about:blank'; + openedWindow.location.href = baseUrl + "/integration/#/login?jobId=" + jobId + "&displayUFTMode=true"; + const msgCallback = async (ev) => { + if (ev?.data == "mcCloseWizard") { + await a.populateAppAndDevice(baseUrl, o.userName, o.password, o.tenantId, o.execToken, o.authType, o.useProxyAuth, o.proxyAddress, o.proxyUserName, o.proxyPassword, jobId, async (app) => { + let jobInfo = app.responseObject(); + let deviceId = "", OS = "", manufacturerAndModel = "", targetLab = ""; + if (jobInfo['deviceJSON']) { + if (jobInfo['deviceJSON']['deviceId']) { deviceId = jobInfo['deviceJSON']['deviceId']; } - if(jobInfo['deviceJSON']['OS']){ + if (jobInfo['deviceJSON']['OS']) { OS = jobInfo['deviceJSON']['OS']; } - if(jobInfo['deviceJSON']['manufacturerAndModel']){ + if (jobInfo['deviceJSON']['manufacturerAndModel']) { manufacturerAndModel = jobInfo['deviceJSON']['manufacturerAndModel']; } } - if(jobInfo['deviceCapability']){ - if(jobInfo['deviceCapability']['OS']){ + if (jobInfo['deviceCapability']) { + if (jobInfo['deviceCapability']['OS']) { OS = jobInfo['deviceCapability']['OS']; } - if(jobInfo['deviceCapability']['manufacturerAndModel']){ + if (jobInfo['deviceCapability']['manufacturerAndModel']) { manufacturerAndModel = jobInfo['deviceCapability']['manufacturerAndModel']; } - if(jobInfo['deviceCapability']['targetLab']){ + if (jobInfo['deviceCapability']['targetLab']) { targetLab = jobInfo['deviceCapability']['targetLab']; } } - document.getElementsByName("runfromfs.fsDeviceId")[0].value = deviceId; - document.getElementsByName("runfromfs.fsOs")[0].value = OS; - document.getElementsByName("runfromfs.fsManufacturerAndModel")[0].value = manufacturerAndModel; - document.getElementsByName("runfromfs.fsTargetLab")[0].value = targetLab; - document.getElementsByName("runfromfs.fsLaunchAppName")[0].value = jobInfo['definitions']['launchApplicationName']; - document.getElementsByName("runfromfs.fsInstrumented")[0].value = jobInfo['definitions']['instrumented']; - document.getElementsByName("runfromfs.fsAutActions")[0].value = jobInfo['definitions']['autActions']; - document.getElementsByName("runfromfs.fsDevicesMetrics")[0].value = jobInfo['definitions']['deviceMetrics']; - document.getElementsByName("runfromfs.fsExtraApps")[0].value = jobInfo['extraApps']; - document.getElementsByName("runfromfs.fsJobId")[0].value = jobInfo['jobUUID']; - buttonStatus = false; - document.getElementById("errorMessage").style.display = "none"; - window.removeEventListener("message",messageCallBack, false); + const div = o.deviceInfo; + div.querySelector('input[name="fsDeviceId"]').value = deviceId; + div.querySelector('input[name="fsOs"]').value = OS; + div.querySelector('input[name="fsManufacturerAndModel"]').value = manufacturerAndModel; + div.querySelector('input[name="fsTargetLab"]').value = targetLab ?? ""; + div.querySelector('input[name="fsLaunchAppName"]').value = jobInfo['definitions']['launchApplicationName'] ?? ""; + div.querySelector('input[name="fsInstrumented"]').value = jobInfo['definitions']['instrumented'] ?? ""; + div.querySelector('input[name="fsAutActions"]').value = jobInfo['definitions']['autActions'] ?? ""; + div.querySelector('input[name="fsDevicesMetrics"]').value = jobInfo['definitions']['deviceMetrics'] ?? ""; + div.querySelector('textarea[name="fsExtraApps"]').value = jobInfo['extraApps'] ?? ""; + div.querySelector('input[name="fsJobId"]').value = jobInfo['jobUUID']; + await triggerBtnState(b, false); + err.style.display = "none"; + window.removeEventListener("message", msgCallback, false); openedWindow.close(); }); } }; - window.addEventListener("message", messageCallBack ,false); + window.addEventListener("message", msgCallback, false); + function checkChild() { - if (openedWindow && openedWindow.closed) { + if (openedWindow?.closed) { clearInterval(timer); - buttonStatus = false; + triggerBtnState(b, false); } } - var timer = setInterval(checkChild, 500); + + let timer = setInterval(checkChild, 500); }); }); +} + +function hideAndMoveAdvancedBody(_id) { + const tBody = document.querySelector("#" + _id).parentNode; // initial advanced block content + const initialAdvancedBlock = tBody.previousSibling; // advanced link button block and here was hidden the initial advanced block content + initialAdvancedBlock.querySelector(".advancedBody").appendChild(tBody); // moves the initial advanced block content back to the hidden block + initialAdvancedBlock.querySelector(".advancedLink").style.display = ""; // enables once again the advanced link +} + +async function loadRegionDDL(dlg, regions) { + const ddl = dlg.querySelector('select[name="cldBrowserRegion"]'); + await loadDDL(ddl, regions.sort()); +} + +async function loadOsDDL(dlg, arr) { + const ddl = dlg.querySelector('select[name="cldBrowserOS"]'); + await loadDDL(ddl, arr); +} + +async function loadBrowserAndVersionDDLs(dlg, browsers) { + const ddlB = dlg.querySelector('select[name="cldBrowser"]'); + const ddlV = dlg.querySelector('select[name="cldBrowserVer"]'); + let mapBV = new Map(); + + browsers.forEach((obj) => { + mapBV.set(obj.type, obj.versions?.map(v => v.tag).sort()); + }); + await loadBrowsersDDL(ddlB, mapBV); + + ddlB.onchange = (e) => { + const arr = ddlB.selectedOptions[0]?.versions; + if (arr?.length) { + loadDDL(ddlV, arr); + } else { + ddlV.length = 0; + } + }; + + const arr = ddlB.selectedOptions[0]?.versions; + arr?.length && await loadDDL(ddlV, arr); +} + +async function loadBrowsersDDL(ddl, map) { + ddl.length = 0; + if (map?.size) { + let x = 0; + map.forEach((val, key) => { + let opt = new Option(key, key, 0 == x++); + opt.versions = val; + ddl[ddl.length] = opt; + }); + } +} + +async function loadDDL(ddl, arr) { + ddl.length = 0; + if (arr?.length) { + for (let i = 0; i < arr.length; ++i) { + ddl[ddl.length] = new Option(arr[i], arr[i], i == 0); + } + } +} + +function hideCloudBrowserModal(b) { + const div = b.parentElement.closest(".config-table-top-row"); + let dlg = div.querySelector('[name="cloudBrowsersModal"]'); + dlg.remove(); +} + +function onSaveCloudBrowser(b) { + try { + const div = b.parentElement.closest(".config-table-top-row"); + let dlg = div.querySelector('[name="cloudBrowsersModal"]'); + const os = div.querySelector('[name="cloudBrowserOs"]'); + os.value = dlg.querySelector('select[name="cldBrowserOS"]').value; + const type = div.querySelector('[name="cloudBrowserType"]'); + type.value = dlg.querySelector('select[name="cldBrowser"]').value; + const ver = div.querySelector('[name="cloudBrowserVersion"]'); + ver.value = dlg.querySelector('select[name="cldBrowserVer"]').value; + const reg = div.querySelector('[name="cloudBrowserRegion"]'); + reg.value = dlg.querySelector('select[name="cldBrowserRegion"]').value; + dlg.remove(); + } catch(e) { + console.error(e); + } +} + +async function loadCssIfNotAlreadyLoaded(path) { + const ss = document.styleSheets; + for (let i = 0, max = ss.length; i < max; i++) { + if (ss[i].href == path) + return; + } + let link = document.createElement("link"); + link.rel = "stylesheet"; + link.type = "text/css"; + link.href = path; + + document.head.appendChild(link); +} + +async function generateModalDialog(rootUrl) { + await loadCssIfNotAlreadyLoaded(rootUrl + "/plugin/hp-application-automation-tools-plugin/css/modal_dialog.css"); + + let browsersModal = document.createElement("div"); + browsersModal.setAttribute("name", "cloudBrowsersModal"); + browsersModal.className = "modal"; + + let content = document.createElement("div"); + content.className = "modal-content"; + + let hdr = document.createElement("div"); + hdr.className = "modal-header"; + + let xDiv = document.createElement("div"); + xDiv.innerHTML = "x"; + xDiv.className = "close"; + xDiv.setAttribute("onclick","hideCloudBrowserModal(this)"); + + let title = document.createElement("div"); + title.innerHTML = "Choose a browser"; + title.setAttribute("class","modal-title"); + + let body = document.createElement("div"); + body.setAttribute("class","modal-body"); + + addEmptySelect(body, "Operating System", "cldBrowserOS"); + addEmptySelect(body, "Browser Type", "cldBrowser"); + addEmptySelect(body, "Browser Version", "cldBrowserVer"); + addEmptySelect(body, "Location", "cldBrowserRegion"); + + let sDiv = document.createElement('div'); + sDiv.innerHTML = "SAVE"; + sDiv.setAttribute("class","save-text"); + sDiv.setAttribute("onclick",'onSaveCloudBrowser(this)'); + + let footer = document.createElement("div"); + footer.setAttribute("class","modal-footer"); + + footer.appendChild(sDiv); + hdr.appendChild(xDiv); + hdr.appendChild(title); + content.appendChild(hdr); + content.appendChild(body); + content.appendChild(footer); + browsersModal.appendChild(content); + + return browsersModal; +}; +function addEmptySelect(parent, label, name) { + let div = document.createElement("div"); + div.setAttribute("class", "modal-body-item"); + div.innerHTML = ``; + parent.appendChild(div); } \ No newline at end of file diff --git a/src/main/webapp/css/ColorPlate.css b/src/main/webapp/css/ColorPlate.css index 65d4ebca7c..341680f3d2 100644 --- a/src/main/webapp/css/ColorPlate.css +++ b/src/main/webapp/css/ColorPlate.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + .ct-legend .ct-series-1:before { background-color: #3d9d68; border-color: #3d9d68; diff --git a/src/main/webapp/css/alm.css b/src/main/webapp/css/alm.css new file mode 100644 index 0000000000..df40a37827 --- /dev/null +++ b/src/main/webapp/css/alm.css @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +#testName { + width: 300px; + margin-bottom: 10px; +} + +table tr td div.help { + margin-left: 12px; + background: none; + border: none; +} + +#cb20 { + margin-left: 35px; +} +.help { + border: none; + background: none; + background-color: transparent; +} + +table td .help { + background: none; +} + +table tr[nameref^="rowSetStart"] { + background: none; +} + +table tr[nameref^="cb20"] { + background-color: transparent; +} +.aut-env-param-chk-lbl { + white-space: nowrap; + margin-left: 5px; + display:none; +} +.aut-env-param-chk-lbl .jenkins-checkbox { + vertical-align: text-bottom; + } + \ No newline at end of file diff --git a/src/main/webapp/css/build_tasks.css b/src/main/webapp/css/build_tasks.css new file mode 100644 index 0000000000..735d2197a1 --- /dev/null +++ b/src/main/webapp/css/build_tasks.css @@ -0,0 +1,101 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +#testsTable { + border: 1px; + width: 85%; +} + +.testsDropDown { + margin-left: 20px; +} + + +#testsDropDown { + width: 85%; +} + +#clearBtn { + background-image: url("${rootURL}/plugin/hpe-application-automation-tools-plugin/icons/uft_icons/eraser.png"); + background-size: 18px; + width: 20px; + margin-left: 20px; +} + +#cleanupTestInput { + width: 250px; + margin-left: 10px; +} + +#cleanupTestList { + margin-left: 20px; +} + +#copyPasteBtn { + background-image: url("${rootURL}/plugin/hpe-application-automation-tools-plugin/icons/uft_icons/copy_paste.png"); + background-size: 45px; + width: 50px; + height: 28px; + margin-left: 10px; +} + +td.help-text { + padding-left: 15px; +} + +#cb27 { + margin-left: 35px; +} + +table tr td div.help { + margin-left: 12px; + background: none; + border: none; +} + +.help { + border: none; + background: none; + background-color: transparent; +} + +table td.help { + background: none; +} + +table tr[nameref^="rowSetStart"] { + background: none; +} + +textarea.jenkins-input, textarea.setting-input{ + resize: vertical; +} \ No newline at end of file diff --git a/src/main/webapp/css/chartist-plugin-tooltip.css b/src/main/webapp/css/chartist-plugin-tooltip.css index 5c362b6efa..5a16534fb2 100644 --- a/src/main/webapp/css/chartist-plugin-tooltip.css +++ b/src/main/webapp/css/chartist-plugin-tooltip.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + .chartist-tooltip { position: relative; display: inline-block; diff --git a/src/main/webapp/css/chartist.css b/src/main/webapp/css/chartist.css index c1c91f7ed5..fd17f5a605 100644 --- a/src/main/webapp/css/chartist.css +++ b/src/main/webapp/css/chartist.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + .ct-label { fill: rgba(0, 0, 0, 0.4); color: rgba(0, 0, 0, 0.4); diff --git a/src/main/webapp/css/chartistLegend.css b/src/main/webapp/css/chartistLegend.css index 9036b457df..45723978da 100644 --- a/src/main/webapp/css/chartistLegend.css +++ b/src/main/webapp/css/chartistLegend.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + .ct-legend { position: relative; z-index: 0; diff --git a/src/main/webapp/css/modal_dialog.css b/src/main/webapp/css/modal_dialog.css new file mode 100644 index 0000000000..4433df94c3 --- /dev/null +++ b/src/main/webapp/css/modal_dialog.css @@ -0,0 +1,147 @@ +/* + * Certain versions of software and/or documents ("Material") accessible here may contain branding from + * Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, + * the Material is now offered by Micro Focus, a separately owned and operated company. 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 + * + * (c) Copyright 2012-2023 Micro Focus or one of its affiliates. + * + * 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. + * + * ___________________________________________________________________ + */ + +.modal { + display: none; + position: fixed; + z-index: 999999; + padding-top: 100px; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(0,0,0); + background-color: rgba(0,0,0,0.4); + transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s; +} + +.modal-content { + position: relative; + background-color: #fefefe; + margin: auto; + padding: 0; + border: 1px solid #888; + width: 420px; + height: 400px; + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); + transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s; +} + +.close { + padding-top: 17px; + padding-right: 13px; + color: grey; + float: right; + font-size: 20px; + font-weight: bold; +} +.close:hover, +.close:focus {color: #000;text-decoration: none;cursor: pointer;} + +.modal-header { + padding : 0; +} + +.modal-title { + padding-top: 25px; + padding-left: 25px; + font-size: 18px; + font-weight: 600; + font-style: normal; + font-stretch: normal; + line-height: normal; + letter-spacing: normal; + color: black; +} + +.modal-body { + padding: 2px 21px; +} + +.modal-footer { + margin-top: 25px; + border-top: 1px solid #e6e6e6; + padding: 2px 16px; + color: white; +} + +.save-text { + width: 34px; + height: 16px; + font-size: 14px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: normal; + letter-spacing: 0.7px; + text-align: center; + color: #0073e7; + right: 20px; + bottom: 20px; + position: absolute; +} + +.save-text:hover, +.save-text:focus { + color: #000;text-decoration: none;cursor: pointer; +} + +.browser-item, .modal-body-item { + position: relative; + padding-top: 25px; + vertical-align: middle; +} + +.browser-item input { + display: inline-block; + vertical-align: middle; +} + +.browser-item img { + padding-left: 16px; +} + +.browser-item-child.browser-name { + padding-left: 16px; + vertical-align: middle; + display: inline-block; + font-size: 14px; + font-weight: normal; + font-style: normal; + font-stretch: normal; + line-height: normal; + letter-spacing: normal; + color: #000000; +} + +.modal-body-item select { + float: right; + vertical-align: middle; + width: 200px; +} diff --git a/src/main/webapp/css/projectReport.css b/src/main/webapp/css/projectReport.css index 21fc18831c..80162055d2 100644 --- a/src/main/webapp/css/projectReport.css +++ b/src/main/webapp/css/projectReport.css @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + .st-table { margin-top: 20px; border: 1px solid #cecece; diff --git a/src/main/webapp/help/accessKey.html b/src/main/webapp/help/accessKey.html deleted file mode 100644 index 5c68820941..0000000000 --- a/src/main/webapp/help/accessKey.html +++ /dev/null @@ -1,3 +0,0 @@ -Obtain a Client ID and Client secret from ALM Octane configuration. - - diff --git a/src/main/webapp/help/impersonatedUser.html b/src/main/webapp/help/impersonatedUser.html deleted file mode 100644 index 0262dce1b7..0000000000 --- a/src/main/webapp/help/impersonatedUser.html +++ /dev/null @@ -1,15 +0,0 @@ -The Jenkins user's account is used to run jobs that ALM Octane runs.

      -Notes: -
        -
      • - Make sure the user exists in Jenkins. -
      • -
      • - We strongly recommend specifying a Jenkins user for ALM Octane. Set this user's permissions to the minimum required for this integration: Job Build permissions. -
      • -
      • - If you do not specify a Jenkins user, ALM Octane uses the Anonymous user, and is limited to Anonymous's user permissions. -
      • -
      - - diff --git a/src/main/webapp/help/uiLocation.html b/src/main/webapp/help/uiLocation.html deleted file mode 100644 index e0ca51464a..0000000000 --- a/src/main/webapp/help/uiLocation.html +++ /dev/null @@ -1 +0,0 @@ -Login into the ALM Octane application and copy & paste the location from your browser. \ No newline at end of file diff --git a/src/main/webapp/icons/16x16/info-blue.png b/src/main/webapp/icons/16x16/info-blue.png new file mode 100644 index 0000000000..fe6ebe6d71 Binary files /dev/null and b/src/main/webapp/icons/16x16/info-blue.png differ diff --git a/src/main/webapp/icons/16x16/warning.png b/src/main/webapp/icons/16x16/warning.png new file mode 100644 index 0000000000..5989266a9b Binary files /dev/null and b/src/main/webapp/icons/16x16/warning.png differ diff --git a/src/main/webapp/icons/24x24/warning.png b/src/main/webapp/icons/24x24/warning.png new file mode 100644 index 0000000000..0d7496dc1a Binary files /dev/null and b/src/main/webapp/icons/24x24/warning.png differ diff --git a/src/main/webapp/icons/report/html_report.svg b/src/main/webapp/icons/report/html_report.svg new file mode 100644 index 0000000000..bbf920b0dd --- /dev/null +++ b/src/main/webapp/icons/report/html_report.svg @@ -0,0 +1 @@ +Artboard 8 \ No newline at end of file diff --git a/src/main/webapp/icons/report/parallel_html_report.svg b/src/main/webapp/icons/report/parallel_html_report.svg new file mode 100644 index 0000000000..aeb374b8f7 --- /dev/null +++ b/src/main/webapp/icons/report/parallel_html_report.svg @@ -0,0 +1 @@ +Artboard 7 \ No newline at end of file diff --git a/src/main/webapp/icons/uft_icons/copy_paste.png b/src/main/webapp/icons/uft_icons/copy_paste.png new file mode 100644 index 0000000000..adff473031 Binary files /dev/null and b/src/main/webapp/icons/uft_icons/copy_paste.png differ diff --git a/src/main/webapp/icons/uft_icons/eraser.png b/src/main/webapp/icons/uft_icons/eraser.png new file mode 100644 index 0000000000..c7f7cc6c5c Binary files /dev/null and b/src/main/webapp/icons/uft_icons/eraser.png differ diff --git a/src/main/webapp/js/almUtils.js b/src/main/webapp/js/almUtils.js new file mode 100644 index 0000000000..39b0ac1dc1 --- /dev/null +++ b/src/main/webapp/js/almUtils.js @@ -0,0 +1,84 @@ +if (window.NodeList && !NodeList.prototype.forEach) { + NodeList.prototype.forEach = Array.prototype.forEach; +} +if (typeof CredScope == "undefined") { + CredScope = {JOB : "JOB", SYSTEM : "SYSTEM"}; +} +if (typeof RUN_FROM_ALM_BUILDER_SELECTOR == "undefined") { + RUN_FROM_ALM_BUILDER_SELECTOR = 'div[name="builder"][descriptorid="com.microfocus.application.automation.tools.run.RunFromAlmBuilder"]'; +} +function setupAlmCredentials() { + let divMain = null; + if (document.location.href.indexOf("pipeline-syntax")>0) { // we are on pipeline-syntax page, where runFromAlmBuilder step can be selected only once, so it's ok to use document + divMain = document; + } else if (document.currentScript) { // this block is used for non-IE browsers, for the first ALM build step only, it finds very fast the parent DIV (containing all ALM controls) + divMain = document.currentScript.parentElement.closest(RUN_FROM_ALM_BUILDER_SELECTOR); + } + setTimeout( function() { + prepareTask(divMain)}, 200); +} +function prepareTask(divMain) { + if (divMain == null) { // this block is needed for IE, but also for non-IE browsers when adding more than one ALM build step + let divs = document.querySelectorAll(RUN_FROM_ALM_BUILDER_SELECTOR); + divMain = divs[divs.length-1]; + } + + const lstServerName = divMain.querySelector('select.alm-server-name'); + const lstCredentialsScope = divMain.querySelector('select[name="almCredentialsScope"]'); + const chkSsoEnabled = divMain.querySelector('input[type="checkbox"][name="runfromalm.isSSOEnabled"]'); + const divSysAlmUsername = divMain.querySelector('div.sys-alm-username'); + const divSysAlmClientId = divMain.querySelector('div.sys-alm-client-id'); + const divJobAlmUsername = divMain.querySelector('div.job-alm-username'); + const divJobAlmPwd = divMain.querySelector('div.job-alm-password'); + const divJobAlmClientId = divMain.querySelector('div.job-alm-client-id'); + const divJobAlmSecret = divMain.querySelector('div.job-alm-secret'); + + selectCredentialsType(); + if (typeof chkSsoEnabled.onclick !== "function") { + chkSsoEnabled.onclick = selectCredentialsType; + } + if (typeof lstCredentialsScope.onchange !== "function") { + lstCredentialsScope.onchange = selectCredentialsType; + } + if (typeof lstServerName.onchange !== "function") { + lstServerName.onchange = resetCredentials; + } + function selectCredentialsType() { + const isJobScope = lstCredentialsScope.value === CredScope.JOB; + const isSSO = chkSsoEnabled.checked; + + if (isJobScope) { + [divSysAlmUsername, divSysAlmClientId].forEach(function(div) { div.querySelector("select").name += "_x"; div.style.display = "none"; }); + divJobAlmUsername.querySelector("input").name = "almUserName"; + divJobAlmPwd.querySelector("input").name = "almPassword"; + divJobAlmClientId.querySelector("input").name = "almClientID"; + divJobAlmSecret.querySelector("input").name = "almApiKey"; + divJobAlmUsername.style.display = divJobAlmPwd.style.display = isSSO ? "none" : "block"; + divJobAlmClientId.style.display = divJobAlmSecret.style.display = isSSO ? "block" : "none"; + } else { + divSysAlmUsername.querySelector("select").name = "almUserName"; + divSysAlmClientId.querySelector("select").name = "almClientID"; + [divJobAlmUsername, divJobAlmPwd, divJobAlmClientId, divJobAlmSecret].forEach(function(div) { div.querySelector("input").name += "_x"; div.style.display = "none"; }); + divSysAlmUsername.style.display = isSSO ? "none" : "block"; + divSysAlmClientId.style.display = isSSO ? "block" : "none"; + } + } + function resetCredentials() { + let evt; + try { + evt = new UIEvent("change", { "view": window, "bubbles": false, "cancelable": true }); + } catch(e) { // IE does not support UIEvent constructor + evt = document.createEvent("UIEvent"); + evt.initUIEvent("change", false, true, window, 1); + } + [divJobAlmSecret, divJobAlmPwd].forEach(function(div) { + const btnUpdate = div.querySelector(".hidden-password-update-btn"); + btnUpdate && btnUpdate.click(); + }); + [divJobAlmClientId, divJobAlmUsername, divJobAlmSecret, divJobAlmPwd].forEach(function(div) { + const input = div.querySelector("input"); + input.value = ""; + input.dispatchEvent(evt); + }); + } +} diff --git a/src/main/webapp/js/dropdown.jsx b/src/main/webapp/js/dropdown.jsx index 40045fff75..6b94787acf 100644 --- a/src/main/webapp/js/dropdown.jsx +++ b/src/main/webapp/js/dropdown.jsx @@ -1,4 +1,36 @@ +/* + * 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. + * ___________________________________________________________________ + */ + class Chart extends React.Component{ componentDidMount() { diff --git a/src/main/webapp/js/fileSystemUtils.js b/src/main/webapp/js/fileSystemUtils.js new file mode 100644 index 0000000000..1389e5637a --- /dev/null +++ b/src/main/webapp/js/fileSystemUtils.js @@ -0,0 +1,168 @@ +/* + * 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. + * ___________________________________________________________________ + */ +document.addEventListener('DOMContentLoaded', function() { + + var checkbox1 = document.getElementById('checkBox1'); + + if (checkbox1.checked) { + document.getElementsByName("fsTestType")[0].disabled = false; + document.getElementsByName("selectedNode")[0].disabled = false; + + } else { + document.getElementsByName("fsTestType")[0].disabled = true; + document.getElementsByName("selectedNode")[0].disabled = true; + } + + var selectIndex = document.getElementsByName("fsTestType")[0].selectedIndex; + var selectValue = document.getElementsByName("fsTestType")[0].options[selectIndex].text; + if (selectValue === "Rerun the entire set of tests" || selectValue === "Rerun only failed tests") { + selectCleanupTest("none"); + } else { + selectCleanupTest("block"); + } +}, false); + +function enableCombobox(object) { + if (object.checked) { + document.getElementsByName("fsTestType")[0].disabled = false; + document.getElementsByName("selectedNode")[0].disabled = false; + //document.getElementById("checkBox2").disabled=false; + } else { + document.getElementsByName("fsTestType")[0].disabled = true; + document.getElementsByName("selectedNode")[0].disabled = true; + //document.getElementById("checkBox2").disabled=true; + } +} + +function fileSelected(input) { + var selectIndex = document.getElementById('testTypeSelect').selectedIndex; + var selectValue = document.getElementById('testTypeSelect').options[selectIndex].text; + if (selectValue === "Rerun the entire set of tests" || selectValue === "Rerun only failed tests") { + document.getElementsByName("uftSettingsModel.cleanupTest")[0].value = input.files[0].name; + } else { + addCleanupTest(input.files[0].name); + } +} + +function selectCleanupTest(displayStyle) { + document.getElementById('clearBtn').style.display = displayStyle; + document.getElementById('clear').style.display = displayStyle; + document.getElementById('copyPasteBtn').style.display = displayStyle; + document.getElementById('infoMessage').style.display = displayStyle; + document.getElementById('testsTable').style.display = displayStyle; +} + +function selectValueCombo(selectObj) { + + var selectIndex = selectObj.selectedIndex; + var selectValue = selectObj.options[selectIndex].text; + + if (selectValue === "Rerun the entire set of tests" || selectValue === "Rerun only failed tests") { + selectCleanupTest("none"); + } else { + selectCleanupTest("block"); + + if (selectValue === "Of any of the build's tests") { + selectCleanupTest("hidden"); + //document.getElementById("checkBox2").disabled = false; + } else { + selectCleanupTest("visible"); + // document.getElementById("checkBox2").disabled = true; + } + } +} + +function copyPasteRerunSettings() { + var checkedTests = document.getElementsByName("rerunSettingsModels.checked"); + var rerunsList = document.getElementsByName('rerunSettingsModels.numberOfReruns'); + var cleanupTestList = document.getElementsByName('rerunSettingsModels.cleanupTest'); + var index = 0; + + var cleanupTest = document.getElementsByName("uftSettingsModel.cleanupTest")[0].value; + var numberOfReruns = document.getElementsByName("numberOfReruns")[0].value; + + rerunsList.forEach(function (element) { + if (checkedTests[index].checked) { + element.value = numberOfReruns; + } + index = index + 1; + }); + + index = 0; + cleanupTestList.forEach(function (element) { + if (checkedTests[index].checked) { + element.value = cleanupTest; + } + index = index + 1; + }); +} + +function addCleanupTest(cleanupTest) { + var selectCleanupLists = document.getElementsByName("rerunSettingsModels.cleanupTests"); + + selectCleanupLists.forEach(function (element) { + var option = document.createElement("option"); + option.text = cleanupTest; + option.value = cleanupTest; + element.add(option); + }); +} + +function clearRerunSettings() { + var checkBoxes = document.getElementsByName("rerunSettingsModels.checked"); + checkBoxes.forEach(function (element) { + element.checked = false; + }); + + var numberOfRerunsFields = document.getElementsByName("rerunSettingsModels.numberOfReruns"); + numberOfRerunsFields.forEach(function (element) { + element.value = 0; + }); + + var selectCleanupLists = document.getElementsByName("rerunSettingsModels.cleanupTest"); + selectCleanupLists.forEach(function (element) { + element.value = ""; + }); +} + +function checkIfPipelineAndUpdateHelpMsg(msg) { + setTimeout(function () { + if (window.location.href.indexOf("pipeline-syntax") > 0) { + let helpText = document.getElementById("helpTextMsg"); + + // verify if the element is found, otherwise an exception will occur which blocks the page loading + if (helpText) { + helpText.innerHTML = msg; + } + } + }, 200); +} diff --git a/src/main/webapp/js/jslib.js b/src/main/webapp/js/jslib.js index 8d7f8f2540..713c0dbe0a 100644 --- a/src/main/webapp/js/jslib.js +++ b/src/main/webapp/js/jslib.js @@ -1,4 +1,36 @@ +/* + * 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. + * ___________________________________________________________________ + */ + // instance.getTotalHitsGraphData(function(t){ // var r = t.responseObject(); // var ctx = document.getElementById('TotalHits').getContext("2d"); diff --git a/src/main/webapp/js/libaries/chartist/chartist-plugin-legend.js b/src/main/webapp/js/libaries/chartist/chartist-plugin-legend.js index 9d9cc99331..0d11c7bfc7 100644 --- a/src/main/webapp/js/libaries/chartist/chartist-plugin-legend.js +++ b/src/main/webapp/js/libaries/chartist/chartist-plugin-legend.js @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. diff --git a/src/main/webapp/js/libaries/chartist/chartist-plugin-pointlabels.js b/src/main/webapp/js/libaries/chartist/chartist-plugin-pointlabels.js index 6f5b444371..5c39eed343 100644 --- a/src/main/webapp/js/libaries/chartist/chartist-plugin-pointlabels.js +++ b/src/main/webapp/js/libaries/chartist/chartist-plugin-pointlabels.js @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. diff --git a/src/main/webapp/js/libaries/chartist/chartist.js b/src/main/webapp/js/libaries/chartist/chartist.js index 6f94da4cd9..40b5b777e2 100644 --- a/src/main/webapp/js/libaries/chartist/chartist.js +++ b/src/main/webapp/js/libaries/chartist/chartist.js @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module unless amdModuleId is set diff --git a/src/main/webapp/js/libaries/react/react-dom.js b/src/main/webapp/js/libaries/react/react-dom.js index 9c8699b683..3a6097dbc4 100644 --- a/src/main/webapp/js/libaries/react/react-dom.js +++ b/src/main/webapp/js/libaries/react/react-dom.js @@ -1,13 +1,33 @@ -/** - * ReactDOM v15.3.2 +/* + * 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 2013-present, Facebook, Inc. - * All rights reserved. + * Copyright 2012-2023 Open Text * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * 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. + * ___________________________________________________________________ */ // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js ;(function(f) { diff --git a/src/main/webapp/js/specifyParametersUtils.js b/src/main/webapp/js/specifyParametersUtils.js new file mode 100644 index 0000000000..42521bdf58 --- /dev/null +++ b/src/main/webapp/js/specifyParametersUtils.js @@ -0,0 +1,382 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +// has to be declared like this, because it has to be globally accessible and multiple steps can be added in a single job, which would throw duplicate exception +// holder, which contain all the valid parameter input types +if (typeof selectableTypeList === "undefined") { + selectableTypeList = ''; +} + +if (typeof BUILDER_SELECTOR === "undefined") { + BUILDER_SELECTOR = "div[name='builder'][descriptorid*='com.microfocus.application.automation.tools.run.RunFrom']"; +} + +function setupParamSpecification() { + document.body.style.cursor = "wait"; + let main = null; + if (document.location.href.indexOf("pipeline-syntax") > 0) { + main = document; + } else if (document.currentScript) { + main = document.currentScript.parentElement.closest(BUILDER_SELECTOR); + } + + if (main == null) { + setTimeout(() => { getFSContainerAndStartListening4Params(0); }, 500); + } else { + setTimeout(() => { + try { + startListening4Params(main); + } catch(e) { + console.error(e); + } finally { + document.body.style.cursor = ""; + } + }, 200); + } +} + +function getFSContainerAndStartListening4Params(idxOfRetry) { + let divs = document.querySelectorAll(BUILDER_SELECTOR); + if (divs == null || divs.length == 0) { + if (idxOfRetry > 5) { + console.error("Failed to initialize Specific Params controls! Please retry again."); + document.body.style.cursor = ""; + } else { + console.log("Retry to initialize Specific Params controls ..."); + setTimeout(() => { getFSContainerAndStartListening4Params(++idxOfRetry); }, 500); + } + } else { + try { + startListening4Params(divs[divs.length - 1]); + } catch (e) { + console.error(e); + } finally { + document.body.style.cursor = ""; + } + } +} + +function startListening4Params(main) { + if (main == null) { + console.error("Failed to initialize Specific Params controls! Please retry or refresh the page."); + return; + } + loadParamInputs(main); + + const btnAddNewParam = main.querySelector("button[name='addNewParamBtn']"); + if (btnAddNewParam) { + btnAddNewParam.addEventListener('click', () => { + addNewParam(main); + }); + } else { + console.warn("Add parameter button is missing."); + } + + const updateMaxNumber4Spinner = (testInput) => { + const rowInputs = main.querySelectorAll(".test-param > div > .num-of-test-spinner"); + const newMax = testInput.value.split("\n").filter(row => row !== "").length; + rowInputs.forEach(rowInput => rowInput.setAttribute("max", newMax === 0 ? 1 : newMax.toString())); + } + const updateTest = (container, spinner, testInput) => { + const testLabel = spinner.parentElement.nextElementSibling.querySelector(".test-label"); + if (spinner.value === '') { + testLabel.value = ""; + return; + } + testLabel.value = testInput.value.split("\n")[parseInt(spinner.value) - 1] || "Please, specify tests first"; + } + + let testInput; + + const prepareTestInput = () => { + testInput = queryTestInput(main); + if (testInput) { + testInput.addEventListener("change", () => { + updateMaxNumber4Spinner(testInput); + + rowInputs.forEach((rowInput) => { + updateTest(main, rowInput, testInput); + }); + }); + testInput.dispatchEvent(new Event("change")); + } else { + console.warn("Test input text area is missing."); + } + } + + const rowInputs = main.querySelectorAll(".test-param > div > .num-of-test-spinner"); + prepareTestInput(); + rowInputs.forEach(rowInput => { + rowInput.addEventListener("click", () => { + updateTest(main, rowInput, testInput); + }); + rowInput.addEventListener("change", () => { + updateTest(main, rowInput, testInput); + }) + }); + + const chkAreParamsEnabled = main.querySelector("input[name='areParametersEnabled']"); + if (chkAreParamsEnabled) { + chkAreParamsEnabled.addEventListener("click", () => cleanParamInput(main)); + } + + const expandTestsFieldBtn = main.querySelector(".expanding-input__button [type='button']"); + expandTestsFieldBtn && expandTestsFieldBtn.addEventListener("click", () => { + prepareTestInput(); + }); +} + +function queryTestInput(container) { + return container.querySelector("textarea[name='fsTests'], input[name='fsTests'], textarea[name='runfromalm.almTestSets'], input[name='runfromalm.almTestSets']"); +} + +function generateAndPutJSONResult(container) { + const paramsContainer = container.querySelector("ul[name='testParams']"); + + const inputs = paramsContainer.querySelectorAll("li[name='testParam']"); + let inputJSON = []; + + const strParamRes = paramsContainer.parentElement.querySelector("input.json-params"); + + if (!strParamRes) return console.warn("Param input JSON result hidden field is missing, reload the page."); + + inputs.forEach(elem => { + let curr = {}; + const idx = elem.dataset.index; + curr.index = elem.querySelector(`#paramInputRow_${idx}`).value; + const name = curr.name = elem.querySelector(`#paramInputName_${idx}`).value; + + if (name !== "") { + curr.type = elem.querySelector(`#paramInputType_${elem.dataset.index}`).value; + + const val = elem.querySelector(`#paramInputValue_${elem.dataset.index}`); + if (curr.type === "Boolean") { + curr.value = val.checked; + } else if (curr.type === "Date" || curr.type === "DateTime") { + const date = new Date(val.value); + curr.value = `${date.getDate() < 10 ? '0' + date.getDate() : date.getDate()}/${date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth()}/${date.getFullYear()}`; + } else { + curr.value = val.value; + } + + inputJSON.push(curr); + } + }); + + strParamRes.value = normalizeJsonFormat(JSON.stringify(inputJSON)); +} + +function cleanParamInput(container) { + if (this.checked) { + loadParamInputs(container); + } else { + const strParamRes = container.querySelector("input.json-params"); + if (!strParamRes) return console.warn("Param input JSON result hidden field is missing, reload the page."); + strParamRes.value = normalizeJsonFormat(JSON.stringify([])); + } +} + +function addNewParam(container) { + const paramContainer = container.querySelector("ul[name='testParams']"); + const params = paramContainer.querySelectorAll("li[name='testParam']") || []; + const nextIdx = params.length !== 0 ? parseInt(Array.from(params).reduce((prev, curr) => { + if (parseInt(prev.dataset.index) > parseInt(curr.dataset.index)) return prev; + + return curr; + }).dataset.index) + 1 : 1; + + let maxNumOfTests = 1; + let testInput = queryTestInput(container); + if (testInput) { + maxNumOfTests = testInput.value.split("\n").filter(row => row !== "").length.toString(); + } else { + console.warn("Test input field is missing."); + } + + const elem = ` +
    • +
      + +
      +
      + +
      +
      + +
      +
      + +
      +
      + +
      + + + + + +
    • + `; + + paramContainer.insertAdjacentHTML("beforeend", elem); + + const testLabel = paramContainer.querySelector(`#paramInputTest_${nextIdx}`); + const spinner = paramContainer.querySelector(`#paramInputRow_${nextIdx}`); + + const handleSpinner = () => { + if (spinner.value === '') { + testLabel.value = ""; + return; + } + + testLabel.value = queryTestInput(container).value.split("\n")[parseInt(spinner.value) - 1] || "Please, specify tests first"; + }; + spinner.addEventListener("click", () => { + handleSpinner(); + }); + spinner.addEventListener("change", () => { + handleSpinner(); + }); + + spinner.dispatchEvent(new Event("change")); + + Array.from(paramContainer.querySelectorAll(`[name='paramInput']`)).filter(input => input.getAttribute("id").endsWith("_" + nextIdx.toString())) + .forEach(input => input.addEventListener("change", () => generateAndPutJSONResult(container))); + + const delButton = paramContainer.querySelector(`#delParamInput_${nextIdx} > span > button`); + delButton.addEventListener("click", () => deleteParam(delButton, container)); + + const typeField = paramContainer.querySelector(`#paramInputType_${nextIdx}`); + const valueField = paramContainer.querySelector(`#paramInputValue_${nextIdx}`); + typeField.addEventListener("change", () => { + valueField.value = ""; + valueField.setAttribute("type", map4TypeAssociations[typeField.value] || "text"); + }); +} + +function deleteParam(elem, container) { + elem.parentNode.parentNode.parentNode.remove(); + generateAndPutJSONResult(container); +} + +// has to be declared like this, because it has to be globally accessible and multiple steps can be added in a single job, which would throw duplicate exception +if (typeof map4TypeAssociations === "undefined") { + map4TypeAssociations = { + String: 'text', + Number: 'number', + Boolean: 'checkbox', + Password: 'password', + Date: 'date', + Any: 'text', + Float: 'number', + Double: 'number', + Decimal: 'number', + Long: 'number', + DateTime: 'date', + Int: 'number' + }; +} + +function loadParamInputs(container) { + const paramResultStr = container.querySelector("input.json-params"); + + // on some browsers the value may return with extra-quotes + let params = paramResultStr.value; + + if (params === "" || params === "[]" || params === "\"[]\"") return; + + let json; + try { + json = JSON.parse(normalizeJsonFormat(params)); + } catch (e) { + json = JSON.parse("[]"); + } + + // has to be an object to be valid JSON input, otherwise because of security policies the JSON was altered + if (typeof(json) === "string") json = JSON.parse("[]"); + + for (let i = 0; i < json.length; ++i) addNewParam(container); + + const testParams = container.querySelectorAll("li[name='testParam']"); + + for (let i = 0; i < json.length; ++i) { + const currElem = testParams[i]; + const currElemVal = json[i]; + + currElem.querySelector(`#paramInputRow_${currElem.dataset.index}`).value = currElemVal["index"] || 1; + currElem.querySelector(`#paramInputName_${currElem.dataset.index}`).value = currElemVal["name"] || ""; + const valueField = currElem.querySelector(`#paramInputValue_${currElem.dataset.index}`) + const typeField = currElem.querySelector(`#paramInputType_${currElem.dataset.index}`); + typeField.value = currElemVal["type"] || "String"; + + valueField.setAttribute("type", map4TypeAssociations[typeField.value] || "text"); + if (typeField.value === "Boolean") { + valueField.checked = currElemVal["value"] || false; + } else if (typeField.value === "Date" || typeField.value === "DateTime") { + const date = new Date(currElemVal["value"].split("/").reverse().join("-")) || Date.now(); + valueField.value = `${date.getFullYear()}-${date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)}-${date.getDate() < 10 ? '0' + date.getDate() : date.getDate()}`; + } else { + valueField.value = currElemVal["value"] || ""; + } + } +} + +function addToSelectableTypeList(type, typeListLength) { + // if there are more build steps than one, do not populate the dropdown + // if the dropdown is already populated, do not populate it again + if (selectableTypeList.split("").length - 1 >= typeListLength) return; + + selectableTypeList += ``; +} + +function addSeparatorToTypeList(group, idx, groupsLength) { + // do not populate the list again, if already populated + // happens when multiple jobs with parameters table is added to the base job + if (selectableTypeList.split("").length - 1 >= groupsLength) return; + + // special command, called with idx of -1 and group of null if separator needed + if (idx === -1 && group === null) { + selectableTypeList += ''; + return; + } + + selectableTypeList += ``; +} + +function normalizeJsonFormat(str) { + // because of certain security policies, on some servers the special characters could be escaped twice, we need to parse them twice + let ret = str; + if (str.endsWith("\"")) ret = JSON.parse(ret); + return ret; +} \ No newline at end of file diff --git a/src/main/webapp/parallelRunnerEnvironment.js b/src/main/webapp/parallelRunnerEnvironment.js new file mode 100644 index 0000000000..36dd86b16a --- /dev/null +++ b/src/main/webapp/parallelRunnerEnvironment.js @@ -0,0 +1,622 @@ +/* + * 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. + * ___________________________________________________________________ + */ +if (typeof RUN_FROM_FS_BUILDER_SELECTOR == "undefined") { + RUN_FROM_FS_BUILDER_SELECTOR = 'div[name="builder"][descriptorid="com.microfocus.application.automation.tools.run.RunFromFileBuilder"]'; +} + +/** + * Prototype that represents the modal dialog. + * @constructor + */ +function ModalDialog() {} + +/** + * Add the style sheet to the provided modal node. + * @param modalCSS the modal style sheet link + */ +ModalDialog.addStyleSheet = function(modalCSS) { + const ss = document.styleSheets; + for (let i = 0, max = ss.length; i < max; i++) { + if (ss[i].href == modalCSS) + return; + } + + var link = document.createElement("link"); + Utils.addStyleSheet(link,modalCSS); + document.head.appendChild(link); +}; + +/** + * Generate the browser item for the browsers dialog. + * @param iconSrc the icons source + * @param browserId the id of the browser + * @param labelText the label text + * @param checked true if the radio should be checked, false otherwise + * @returns {*} + */ +ModalDialog.generateBrowserItem = function(iconSrc,browserId,labelText,checked) { + var browserRadio = document.createElement("input"); + browserRadio.setAttribute("class","browser-item-child customRadio"); + browserRadio.setAttribute("type","radio"); + browserRadio.setAttribute("name","browser-radio"); + + if(checked) { + browserRadio.setAttribute("checked", "true"); + } + + browserRadio.setAttribute("id",browserId); + + var browserImage = document.createElement("img"); + browserImage.setAttribute("class","browser-item-child"); + browserImage.setAttribute("src",iconSrc); + + var browserItem = document.createElement("div"); + browserItem.setAttribute("class","browser-item"); + + var browserLabel = document.createElement("div"); + browserLabel.setAttribute("class","browser-item-child browser-name"); + browserLabel.innerHTML = labelText; + + browserItem.appendChild(browserRadio); + browserItem.appendChild(browserImage); + browserItem.appendChild(browserLabel); + + return browserItem; +}; + +ModalDialog.saveBrowserSettings = function(modalNode) { + // retrieve the button that was used to open the env wizard + const parent = ModalDialog.currentEnv; + + let radioButtons = modalNode.querySelectorAll('input[type="radio"]'); + + for(let i =0; i < radioButtons.length;i++) { + if(radioButtons[i].checked) { + ParallelRunnerEnv.setUpBrowserEnvironment(parent,radioButtons[i],modalNode); + } + } +}; + +ModalDialog.setSelectedBrowser = function(modal,browserId){ + if(ModalDialog.browsers == null) return false; + + // check if the provided browser id matches any of the available browsers + var selectedBrowser = null; + for(var i = 0; i < ModalDialog.browsers.length; i++) { + if(ModalDialog.browsers[i].toLowerCase() === browserId.toLowerCase()) { + selectedBrowser = ModalDialog.browsers[i]; + } + } + + // no match, select the default one + if(selectedBrowser == null) return false; + + var radioButton = modal.querySelector("input[id=" + selectedBrowser + "]"); + + if(radioButton == null) return false; + + // set the corresponding radio button to be checked + radioButton.checked = true; + + return true; +}; + +/** + * Hide the modal with the given modalId. + * @param modalId the modal id + * @returns {boolean} true if the modal was hidden, false otherwise + */ +ModalDialog.hide = function(modalId) { + var modal = document.getElementById(modalId); + + if(modal == null) return false; + + modal.style.display = "none"; +}; + +/** + * Generate the modal dialog + * @constructor + */ +ModalDialog.generate = function(path) { + var modalCSS = path + "plugin/hp-application-automation-tools-plugin/css/modal_dialog.css"; + + // add the css style + ModalDialog.addStyleSheet(modalCSS); + + var browsersModal = document.createElement("div"); + browsersModal.setAttribute("id","browsersModal"); + browsersModal.setAttribute("class","modal"); + + var modalContent = document.createElement("div"); + modalContent.setAttribute("class","modal-content"); + + var modalHeader = document.createElement("div"); + modalHeader.setAttribute("class","modal-header"); + + var span = document.createElement("div"); + span.innerHTML = "x"; + span.setAttribute("class","close"); + span.setAttribute("onclick","ModalDialog.hide('browsersModal')"); + + var title = document.createElement("div"); + title.innerHTML = "Choose a browser"; + title.setAttribute("class","modal-title"); + + var modalBody = document.createElement("div"); + modalBody.setAttribute("class","modal-body"); + + var iconsSRC = path + "plugin/hp-application-automation-tools-plugin/ParallelRunner/icons/"; + + var chromeBrowserItem = ModalDialog.generateBrowserItem(iconsSRC + 'svg/chrome.svg','Chrome','Chrome',true); + var firefoxBrowserItem = ModalDialog.generateBrowserItem(iconsSRC + 'svg/firefox.svg','Firefox','Firefox',false); + var firefox64BrowserItem = ModalDialog.generateBrowserItem(iconsSRC + 'svg/firefox.svg','Firefox64','Firefox 64',false); + var ieBrowserItem = ModalDialog.generateBrowserItem(iconsSRC + 'svg/explorer.svg','IE','IE',false); + var ie64BrowserItem = ModalDialog.generateBrowserItem(iconsSRC + 'svg/explorer.svg','IE64','IE 64',false); + + // retain the available browsers + ModalDialog.browsers = ["Chrome","Firefox","Firefox64","IE","IE64"]; + + // add the browser items to the modal body + modalBody.appendChild(chromeBrowserItem); + modalBody.appendChild(firefoxBrowserItem); + modalBody.appendChild(firefox64BrowserItem); + modalBody.appendChild(ieBrowserItem); + modalBody.appendChild(ie64BrowserItem); + + var saveText = document.createElement('div'); + saveText.innerHTML = "SAVE"; + saveText.setAttribute("class","save-text"); + saveText.setAttribute("onclick",'ModalDialog.saveBrowserSettings(browsersModal)'); + + var modalFooter = document.createElement("div"); + modalFooter.setAttribute("class","modal-footer"); + + modalFooter.appendChild(saveText); + modalHeader.appendChild(span); + modalHeader.appendChild(title); + modalContent.appendChild(modalHeader); + modalContent.appendChild(modalBody); + modalContent.appendChild(modalFooter); + browsersModal.appendChild(modalContent); + + return browsersModal; +}; + +/** + * Multi-purpose utils class. + * @constructor + */ +function Utils() {} + +/** + * Check if a string is empty. + * @param str the string to check + * @returns {boolean} + */ +Utils.isEmptyString = function(str) { + return (!str || str.length === 0); +}; + +Utils.addStyleSheet = function(elem,sheetHref) { + elem.setAttribute("rel","stylesheet"); + elem.setAttribute("type","text/css"); + elem.setAttribute("href",sheetHref); +}; + +/** + * Parse the information received for MobileCenter. + * @param deviceId - the deviceId string + * @param os - the os string + * @param manufacturerAndModel - the manufacturer and model string + * @returns {string} the parsed information. + */ +Utils.parseMCInformation = function(deviceId, os, manufacturerAndModel) { + var mc_params = []; + var os_types = {android : 'Android', ios: 'ios', wp : 'Windows Phone'}; + + if(!Utils.isEmptyString(deviceId)) + mc_params.push({name: 'deviceId', value: deviceId}); + else { + if (!Utils.isEmptyString(os)) { + // regex for the os string + // example: ios<=10.2.2 => we need to extract ios,<=,10.2.2 + var regex = /([a-z]+)(>=|>|<|<=)*([0-9].*[0-9])+/gi; + var match = regex.exec(os); + + if (match == null) { // string does not contain a version + mc_params.push({name: 'osType', value: os_types[os]}); + mc_params.push({name: 'osVersion', value: 'any'}); + } + else { // version was given to us + mc_params.push({name: 'osType', value: os_types[match[1]]}); + mc_params.push({name: 'osVersion', value: match[2] == null ? match[3] : match[2] + match[3]}); + } + } + } + + if(!Utils.isEmptyString(manufacturerAndModel)) + mc_params.push({name: 'manufacturerAndModel', value: manufacturerAndModel}); + + var result_str = ""; + for(var i = 0; i < mc_params.length; i++) { + result_str = result_str.concat(mc_params[i].name, " : ", mc_params[i].value, (i===mc_params.length - 1) ? "" : ","); + } + return result_str; +}; + +/** + * Set the provided jenkins element visibility. + * @param element - the jenkins element to be hidden + * @param isVisible - the visible boolean state to be aquired + */ +Utils.setJenkinsElementVisibility = function(element,isVisible) { + let parent = element.parentElement.closest(".jenkins-form-item"); + parent.style.display = isVisible ? "" : "none"; +}; + +/** + * Load the mobile center wizard. + * @param a descriptor + * @param b the environment wizard button + */ +Utils.loadMC = function(a, b, prEnv){ + b.disabled = true; + const divMain = prEnv.parentElement.closest(RUN_FROM_FS_BUILDER_SELECTOR); + const dl = divMain.querySelector("#mobileSpecificSection"); + var mcUserName = dl.querySelector('input[name="mcUserName"]')?.value; + var mcPassword = dl.querySelector('input[name="mcPassword"]')?.value; + var mcTenantId = dl.querySelector('input[name="mcTenantId"]')?.value; + var mcExecToken = dl.querySelector('input[name="mcExecToken"]')?.value; + var mcAuthType = dl.querySelector('input[name$="authModel"]:checked')?.value; + var mcUrl = dl.querySelector('select[name="mcServerName"]')?.value; + var useProxy = dl.querySelector('input[name="proxySettings"]')?.checked; + var proxyAddress = dl.querySelector('input[name="fsProxyAddress"]')?.value; + var useProxyAuth = dl.querySelector('input[name="fsUseAuthentication"]')?.checked; + var proxyUserName = dl.querySelector('input[name="fsProxyUserName"]')?.value; + var proxyPassword = dl.querySelector('input[name="fsProxyPassword"]')?.value; + var isMcCredentialMissing; + if ('base' == mcAuthType) { + isMcCredentialMissing = !mcUserName || !mcPassword || mcUserName.trim() == "" || mcPassword.trim() == ""; + } else { + isMcCredentialMissing = !mcExecToken || mcExecToken.trim() == ""; + } + + const isProxyAddressRequiredButMissing = useProxy && (proxyAddress == null || proxyAddress.trim() == ""); + const isProxyCredentialRequiredButMissing = useProxyAuth && (!proxyUserName || !proxyPassword || proxyUserName.trim() == "" || proxyPassword.trim() == ""); + if(isMcCredentialMissing || isProxyAddressRequiredButMissing || isProxyCredentialRequiredButMissing){ + ParallelRunnerEnv.setEnvironmentError(prEnv,true); + b.disabled = false; + return; + } + var previousJobId = dl.querySelector('[name="fsJobId"]')?.value; + a.getMcServerUrl(mcUrl, function(r){ + let baseUrl = r.responseObject(); + if(baseUrl){ + baseUrl = baseUrl.trim().replace(/[\/]+$/, ""); + } else { + ParallelRunnerEnv.setEnvironmentError(prEnv,true); + b.disabled = false; + return; + } + a.getJobId(baseUrl, mcUserName, mcPassword, mcTenantId, mcExecToken, mcAuthType, useProxyAuth, proxyAddress, proxyUserName, proxyPassword, previousJobId, function (response) { + var jobId = response.responseObject(); + if(jobId == null) { + ParallelRunnerEnv.setEnvironmentError(prEnv,true); + b.disabled = false; + return; + } + var openedWindow = window.open('/','test parameters','height=820,width=1130'); + openedWindow.location.href = 'about:blank'; + openedWindow.location.href = baseUrl+"/integration/#/login?jobId="+jobId+"&displayUFTMode=true&deviceOnly=true"; + var messageCallBack = function (event) { + if (event?.data=="mcCloseWizard") { + a.populateAppAndDevice(baseUrl, mcUserName, mcPassword, mcTenantId, mcExecToken, mcAuthType, useProxyAuth, proxyAddress, proxyUserName, proxyPassword, jobId, function (app) { + var jobInfo = app.responseObject(); + let deviceId = "", OS = "", manufacturerAndModel = ""; + if(jobInfo['deviceJSON']){ + if(jobInfo['deviceJSON']['deviceId']){ + deviceId = jobInfo['deviceJSON']['deviceId']; + } + if(jobInfo['deviceJSON']['OS']){ + OS = jobInfo['deviceJSON']['OS']; + } + if(jobInfo['deviceJSON']['manufacturerAndModel']){ + manufacturerAndModel = jobInfo['deviceJSON']['manufacturerAndModel']; + } + } + if(jobInfo['deviceCapability']){ + if(jobInfo['deviceCapability']['OS']){ + OS = jobInfo['deviceCapability']['OS']; + } + if(jobInfo['deviceCapability']['manufacturerAndModel']){ + manufacturerAndModel = jobInfo['deviceCapability']['manufacturerAndModel']; + } + } + console.log(deviceId); + ParallelRunnerEnv.setEnvironmentSettingsInput(prEnv,Utils.parseMCInformation(deviceId,OS,manufacturerAndModel)); + + b.disabled = false; + ParallelRunnerEnv.setEnvironmentError(prEnv,false); + window.removeEventListener("message",messageCallBack, false); + openedWindow.close(); + }); + } + }; + window.addEventListener("message", messageCallBack ,false); + function checkChild() { + if (openedWindow && openedWindow.closed) { + clearInterval(timer); + b.disabled = false; + } + } + var timer = setInterval(checkChild, 500); + }); + }); +}; + +/** + * Prototype that represents the ParallelRunner environment. + * @constructor + */ +function ParallelRunnerEnv() {} + +/** + * + * @param parent + * @returns {*} + */ +ParallelRunnerEnv.getEnvironmentSettingsInputNode = function (parent) { + return parent?.querySelector(".jenkins-input,.setting-input") ; +}; + +/** + * Set the environment text box input to the given input value, + * the input corresponds to the clicked environment wizard button. + * @param parent the parent container of the clicked environment wizard button, like "parallelRunnerEnvironments" + * @param inputValue the input value to be set + * @returns {boolean} true if it succeeded, false otherwise. + */ +ParallelRunnerEnv.setEnvironmentSettingsInput = function(parent,inputValue) { + let settingInput = ParallelRunnerEnv.getEnvironmentSettingsInputNode(parent); + settingInput && (settingInput.value = inputValue); +}; + +/** + * Enable the error div that corresponds to the clicked + * environment wizard button. + * @param parent the current environment container + * @param enable the div visibility state(true - visible, false - hidden) + * @returns {boolean} true if it succeeded, false otherwise. + */ +ParallelRunnerEnv.setEnvironmentError = function(parent, enable) { + const errorDiv = parent?.querySelector('div[name="mcSettingsError"]'); + errorDiv && (errorDiv.style.display = enable ? "block" : "none"); +}; + +/** + * Set the browser selection modal visibility. + * @param parent - the current environment container + * @param modalId - the browser modal id + * @param visible - should the modal be visible?(true / false) + * @param path - the patch to the root of the plugin + */ + //TODO refactor ModalDialog to be appended to a parent divMain instead of document, with divMain computed from button +ParallelRunnerEnv.setBrowsersModalVisibility = function(parent,modalId,visible,path) { + var modal = document.getElementById(modalId); + // it wasn't generated, so we need to generate it + if(modal == null) { + // generate it + modal = ModalDialog.generate(path); + + // add it to the DOM + document.body.appendChild(modal); + } + + ModalDialog.currentEnv = parent; + + modal = document.getElementById(modalId); + + let settingInput = ParallelRunnerEnv.getEnvironmentSettingsInputNode(parent); + const environmentInputValue = settingInput?.value; + + // set the selected browser to match the one in the input + if(environmentInputValue != null) { + var browser = environmentInputValue.split(":"); + + // should be of the form browser: BrowserName + if(browser?.length === 2) + { + ModalDialog.setSelectedBrowser (modal,browser[1].trim()); + } + } + + if(visible) { + modal.style.display = "block"; + + // also allow the user to hide it by clicking anywhere on the window + window.onclick = function(event) { + if (event.target === modal) { + modal.style.display = "none"; + } + }; + } + else + modal.style.display = "none"; +}; + +/** + * Determine the currently selected environment type. + * @param parent - the current environment container + * @returns {*} + */ +ParallelRunnerEnv.getCurrentEnvironmentType = function(parent) { + let input = parent?.querySelector('input[type="radio"][name$="environmentType"]:checked'); + return input?.defaultValue; +}; + +/** + * Set the environment text based on the browser selection. + * @param parent - the current environment container + * @param radio - the selected radio + * @param modal - the browser selection modal + */ +ParallelRunnerEnv.setUpBrowserEnvironment = function(parent,radio,modal) { + // we can close the modal now + modal.style.display = "none"; + // based on the browser chosen we will prepare the environment + ParallelRunnerEnv.setEnvironmentSettingsInput(parent,"browser : " + radio['id']); +}; + +/** + * Sets the environment and test set visibility based on the parallel runner checkBox state. + * @param panel - the current build step container + * @param visible - the visible boolean state to be aquired + */ +ParallelRunnerEnv.setEnvironmentsVisibility = function(panel, visible) { + var environments = panel.querySelectorAll("div[name='fileSystemTestSet']"); + if (environments == null || environments.length == 0) return; + [...environments].forEach(env => { + Utils.setJenkinsElementVisibility(env,visible); + }); +}; + +/** + * Click handler for the environment wizard button. + * @param btn the environment wizard button + * @param a first mc argument + * @param modalId the browser modalId to be shown + * @param visibility of the modal + * @param pluginPath the ${root} path + * @returns {boolean} + */ +ParallelRunnerEnv.onEnvironmentWizardClick = function(a,btn,modalId,visibility,pluginPath) { + // get the environment type for the current env, it could be: 'web' or 'mobile' + const prEnv = btn.parentElement.closest('div[name="parallelRunnerEnvironments"]'); + let type = ParallelRunnerEnv.getCurrentEnvironmentType(prEnv); + if(type == null) return false; + + // if the type is web we need to show the browsers modal + if(type.toLowerCase() === 'web') { + ParallelRunnerEnv.setBrowsersModalVisibility(prEnv,modalId,visibility,pluginPath); + return true; + } + + // open the mobile center wizard + if(type.toLowerCase() === 'mobile') { + try { + Utils.loadMC(a, btn, prEnv); + } catch(e) { + console.error(e); + } finally { + btn.disabled = false; + } + return true; + } + + return false; +}; + +/** + * Utility class for the RunFromFileSystem model. + * @constructor + */ +function RunFromFileSystemEnv() {} + +/** + * Sets the visibility of a given multi line text box. + * @param panel - the current build step container + * @param name the textbox name + * @param visible - the visible boolean state to be aquired + */ +RunFromFileSystemEnv.setMultiLineTextBoxVisibility = function(panel, name, visible) { + var textBox = panel.querySelector(`input[name="${name}"], textarea[name="${name}"]`); + let parent = textBox.parentElement.closest(".jenkins-form-item"); + parent.style.display = visible ? "" : "none"; +}; + +RunFromFileSystemEnv.setInputVisibility = function(panel, name, visible) { + var textBox = panel.querySelector(`input[name="${name}"]`); + Utils.setJenkinsElementVisibility(textBox,visible); +}; + +RunFromFileSystemEnv.setFsTestsVisibility = function(panel, visible) { + this.setMultiLineTextBoxVisibility(panel, "fsTests", visible); +}; + +RunFromFileSystemEnv.setFsReportPathVisibility = function(panel, visible) { + this.setInputVisibility(panel, "fsReportPath", visible); +}; + +RunFromFileSystemEnv.setTimeoutVisibility = function (panel, visible) { + this.setInputVisibility(panel, "fsTimeout", visible); +}; + +RunFromFileSystemEnv.setParamsVisibility = function(panel, visible) { + this.setInputVisibility(panel, "areParametersEnabled", visible); +}; + +/** + * Hide/Show the corresponding controls based on the parallel runner checkBox state. + */ +function setViewVisibility(panel) { + const chkParallelRunner = panel.querySelector("input[type=checkbox][name=isParallelRunnerEnabled]"); + updateFsView(panel, chkParallelRunner); + chkParallelRunner.addEventListener('click', () => { + updateFsView(panel, chkParallelRunner); + }, false); +} +function updateFsView(panel, chkParallelRunner) { + const isParallelRun = chkParallelRunner.checked; + RunFromFileSystemEnv.setFsTestsVisibility(panel, !isParallelRun); + RunFromFileSystemEnv.setTimeoutVisibility(panel, !isParallelRun); + RunFromFileSystemEnv.setParamsVisibility(panel, !isParallelRun); + //this panel should be automatically shown/hidden, so comment-out it for now to see if all works fine + //ParallelRunnerEnv.setEnvironmentsVisibility(panel, isParallelRun); +} +function setupFsTask() { + let divMain = null; + if (document.location.href.indexOf("pipeline-syntax")>0) { // we are on pipeline-syntax page, where runFromFileBuilder step can be selected only once + divMain = document; + } else if (document.currentScript) { // this block is used for non-IE browsers, for the first FS build step only, it finds very fast the parent DIV + divMain = document.currentScript.parentElement.closest(RUN_FROM_FS_BUILDER_SELECTOR); + } + setTimeout(function() { + prepareFsTask(divMain)}, 100); +} +function prepareFsTask(divMain) { + if (divMain == null) { // this block is needed for IE, but also for non-IE browsers when adding more than one FS build step + let divs = document.querySelectorAll(RUN_FROM_FS_BUILDER_SELECTOR); + divMain = divs[divs.length - 1]; + } + setViewVisibility(divMain); +} \ No newline at end of file diff --git a/src/main/webapp/scss/chartist.scss b/src/main/webapp/scss/chartist.scss index 0f19ba05e5..30b241e95e 100644 --- a/src/main/webapp/scss/chartist.scss +++ b/src/main/webapp/scss/chartist.scss @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + @import "settings/chartist-settings"; @mixin ct-responsive-svg-container($width: 100%, $ratio: $ct-container-ratio) { diff --git a/src/main/webapp/scss/chartistLegend.scss b/src/main/webapp/scss/chartistLegend.scss index 9aff54f822..338438d525 100644 --- a/src/main/webapp/scss/chartistLegend.scss +++ b/src/main/webapp/scss/chartistLegend.scss @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + @import "settings/chartist-settings"; .ct-legend { position: relative; diff --git a/src/main/webapp/scss/settings/_chartist-settings.scss b/src/main/webapp/scss/settings/_chartist-settings.scss index 21b92c133a..050bf0c8e6 100644 --- a/src/main/webapp/scss/settings/_chartist-settings.scss +++ b/src/main/webapp/scss/settings/_chartist-settings.scss @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + // Scales for responsive SVG containers $ct-scales: ((1), (15/16), (8/9), (5/6), (4/5), (3/4), (2/3), (5/8), (1/1.618), (3/5), (9/16), (8/15), (1/2), (2/5), (3/8), (1/3), (1/4)) !default; $ct-scales-names: (ct-square, ct-minor-second, ct-major-second, ct-minor-third, ct-major-third, ct-perfect-fourth, ct-perfect-fifth, ct-minor-sixth, ct-golden-section, ct-major-sixth, ct-minor-seventh, ct-major-seventh, ct-octave, ct-major-tenth, ct-major-eleventh, ct-major-twelfth, ct-double-octave) !default; diff --git a/src/test/java/com/hp/application/automation/tools/common/TestALMRESTVersionUtils.java b/src/test/java/com/hp/application/automation/tools/common/TestALMRESTVersionUtils.java deleted file mode 100644 index 0d907e3a8c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/common/TestALMRESTVersionUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.common; - -import com.hp.application.automation.tools.model.ALMVersion; -import org.junit.Assert; -import org.junit.Test; - -import java.io.UnsupportedEncodingException; - -/** - * @author Effi Bar-She'an - */ -@SuppressWarnings("squid:S2699") -public class TestALMRESTVersionUtils { - - @Test - public void testToModel() throws UnsupportedEncodingException { - - final String MAJOR = "12"; - final String MINOR = "5"; - final String _dataFormat = "\n" + - "12.50.39 (Patch 1)\n" + - "%s\n" + - "%s\n" + - "0\n" + - "1\n" + - "1\n" + - ""; - ALMVersion version = ALMRESTVersionUtils.toModel(String.format(_dataFormat, MAJOR, MINOR).getBytes("UTF-8")); - Assert.assertEquals(MAJOR, version.getMajorVersion()); - Assert.assertEquals(MINOR, version.getMinorVersion()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/model/SecretContainerTest.java b/src/test/java/com/hp/application/automation/tools/model/SecretContainerTest.java deleted file mode 100644 index 0547b3f9f1..0000000000 --- a/src/test/java/com/hp/application/automation/tools/model/SecretContainerTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.model; - -public class SecretContainerTest implements SecretContainer { - - private String _secret; - - public void initialize(String secret) { - - _secret = secret; - } - - @Override - public String toString() { - - return _secret; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/EnumsTest.java b/src/test/java/com/hp/application/automation/tools/octane/EnumsTest.java deleted file mode 100644 index 44ba9d0c2d..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/EnumsTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane; - -import com.hp.octane.integrations.dto.causes.CIEventCauseType; -import com.hp.octane.integrations.dto.events.CIEventType; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.scm.SCMType; -import com.hp.octane.integrations.dto.snapshots.CIBuildResult; -import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 21:32 - * To change this template use File | Settings | File Templates. - */ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -public class EnumsTest { - - @Test - public void testCIEventCauseType() { - assertEquals(CIEventCauseType.values().length, 5); - assertEquals(CIEventCauseType.SCM.value(), "scm"); - assertEquals(CIEventCauseType.USER.value(), "user"); - assertEquals(CIEventCauseType.TIMER.value(), "timer"); - assertEquals(CIEventCauseType.UPSTREAM.value(), "upstream"); - assertEquals(CIEventCauseType.UNDEFINED.value(), "undefined"); - assertEquals(CIEventCauseType.fromValue("scm"), CIEventCauseType.SCM); - } - - @Test - public void testCIEventType() { - assertEquals(CIEventType.values().length, 5); - assertEquals(CIEventType.QUEUED.value(), "queued"); - assertEquals(CIEventType.SCM.value(), "scm"); - assertEquals(CIEventType.STARTED.value(), "started"); - assertEquals(CIEventType.FINISHED.value(), "finished"); - assertEquals(CIEventType.fromValue("queued"), CIEventType.QUEUED); - } - - @Test - public void testParameterType() { - assertEquals(CIParameterType.values().length, 7); - assertEquals(CIParameterType.UNKNOWN.value(), "unknown"); - assertEquals(CIParameterType.PASSWORD.value(), "password"); - assertEquals(CIParameterType.BOOLEAN.value(), "boolean"); - assertEquals(CIParameterType.STRING.value(), "string"); - assertEquals(CIParameterType.NUMBER.value(), "number"); - assertEquals(CIParameterType.FILE.value(), "file"); - assertEquals(CIParameterType.AXIS.value(), "axis"); - assertEquals(CIParameterType.fromValue("unavailable"), CIParameterType.UNKNOWN); - } - - @Test - public void testSnapshotResult() { - assertEquals(CIBuildResult.values().length, 5); - assertEquals(CIBuildResult.UNAVAILABLE.value(), "unavailable"); - assertEquals(CIBuildResult.UNSTABLE.value(), "unstable"); - assertEquals(CIBuildResult.ABORTED.value(), "aborted"); - assertEquals(CIBuildResult.FAILURE.value(), "failure"); - assertEquals(CIBuildResult.SUCCESS.value(), "success"); - assertEquals(CIBuildResult.fromValue("unavailable"), CIBuildResult.UNAVAILABLE); - } - - @Test - public void testSnapshotStatus() { - assertEquals(CIBuildStatus.values().length, 4); - assertEquals(CIBuildStatus.UNAVAILABLE.value(), "unavailable"); - assertEquals(CIBuildStatus.QUEUED.value(), "queued"); - assertEquals(CIBuildStatus.RUNNING.value(), "running"); - assertEquals(CIBuildStatus.FINISHED.value(), "finished"); - assertEquals(CIBuildStatus.fromValue("unavailable"), CIBuildStatus.UNAVAILABLE); - } - - @Test - public void testSCMType() { - assertEquals(SCMType.values().length, 3); - assertEquals(SCMType.UNKNOWN.value(), "unknown"); - assertEquals(SCMType.GIT.value(), "git"); - assertEquals(SCMType.SVN.value(), "svn"); - assertEquals(SCMType.fromValue("unknown"), SCMType.UNKNOWN); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/Configuration.java b/src/test/java/com/hp/application/automation/tools/octane/actions/Configuration.java deleted file mode 100644 index a31c2ad0bf..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/Configuration.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hp.application.automation.tools.octane.actions; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 12:05 - * To change this template use File | Settings | File Templates. - */ - -public class Configuration { - public static enum OS { - WINDOWS("windows"), - LINUX("linux"); - - private String value; - private static OS current; - - private OS(String v) { - value = v; - } - - public static OS getCurrent() { - String tmpVal; - if (current == null) { - tmpVal = System.getProperty("os.name").toLowerCase(); - if (tmpVal.indexOf("windows") == 0) current = WINDOWS; - else if (tmpVal.indexOf("linux") == 0) current = LINUX; - else current = LINUX; - } - return current; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/Utils.java b/src/test/java/com/hp/application/automation/tools/octane/actions/Utils.java deleted file mode 100644 index 9ed17c4e1c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/Utils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions; - -import hudson.model.AbstractProject; -import hudson.tasks.BatchFile; -import hudson.tasks.CommandInterpreter; -import hudson.tasks.Shell; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 13:55 - * To change this template use File | Settings | File Templates. - */ - -public class Utils { - public static CommandInterpreter getSleepScript(int seconds) { - if (Configuration.OS.getCurrent() == Configuration.OS.WINDOWS) { - return new BatchFile("ping -n " + seconds + " 127.0.0.1 >nul"); - } else if (Configuration.OS.getCurrent() == Configuration.OS.LINUX) { - return new Shell("sleep " + seconds); - } else { - return null; - } - } - - public static void buildProject(JenkinsRule.WebClient client, AbstractProject project) throws IOException, SAXException { - client.goTo("job/" + project.getName() + "/build", ""); - } - - public static void buildProjectWithParams(JenkinsRule.WebClient client, AbstractProject project, String params) throws IOException, SAXException { - client.goTo("job/" + project.getName() + "/buildWithParameters?" + params, ""); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsFreeStyleTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsFreeStyleTest.java deleted file mode 100644 index 2666014371..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsFreeStyleTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.build; - -import com.gargoylesoftware.htmlunit.Page; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.causes.CIEventCauseType; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.snapshots.SnapshotNode; -import com.hp.octane.integrations.dto.snapshots.CIBuildResult; -import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; -import com.hp.application.automation.tools.octane.actions.Utils; -import hudson.model.*; -import hudson.plugins.parameterizedtrigger.*; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -import java.io.IOException; -import java.util.Arrays; -import java.util.UUID; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:46 - * To change this template use File | Settings | File Templates. - */ - -public class BuildActionsFreeStyleTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - // Snapshot: free-style, no params, no children - // - @Test - public void testFreeStyleNoParamsNoChildren() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - int retries = 0; - FreeStyleProject p = rule.createFreeStyleProject(projectName); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - SnapshotNode snapshot; - - assertEquals(p.getBuilds().toArray().length, 0); - Utils.buildProject(client, p); - while ((p.getLastBuild() == null || p.getLastBuild().isBuilding()) && ++retries < 40) { - Thread.sleep(500); - } - assertEquals(p.getBuilds().toArray().length, 1); - - page = client.goTo("nga/api/v1/jobs/" + projectName + "/builds/" + p.getLastBuild().getNumber(), "application/json"); - snapshot = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), SnapshotNode.class); - assertEquals(projectName, snapshot.getJobCiId()); - assertEquals(projectName, snapshot.getName()); - assertEquals(0, snapshot.getParameters().size()); - - assertEquals(0, snapshot.getPhasesInternal().size()); - assertEquals(0, snapshot.getPhasesPostBuild().size()); - assertEquals(1, snapshot.getCauses().size()); - assertEquals(CIEventCauseType.USER, snapshot.getCauses().get(0).getType()); - assertEquals(String.valueOf(p.getLastBuild().getNumber()), snapshot.getNumber()); - assertEquals(CIBuildStatus.FINISHED, snapshot.getStatus()); - assertEquals(CIBuildResult.SUCCESS, snapshot.getResult()); - assertNotNull(snapshot.getStartTime()); - assertNotNull(snapshot.getDuration()); - assertNotNull(snapshot.getEstimatedDuration()); - } - - // Snapshot: free-style, with params, no children - // - @Test - public void testFreeStyleWithParamsNoChildren() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - int retries = 0; - FreeStyleProject p = rule.createFreeStyleProject(projectName); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), - (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"one", "two", "three"}, "choice"), - (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") - )); - p.addProperty(params); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - SnapshotNode snapshot; - CIParameter tmpParam; - - assertEquals(p.getBuilds().toArray().length, 0); - Utils.buildProjectWithParams(client, p, "ParamA=false&ParamD=two&ParamX=some_string"); - while ((p.getLastBuild() == null || p.getLastBuild().isBuilding()) && ++retries < 40) { - Thread.sleep(500); - } - assertEquals(p.getBuilds().toArray().length, 1); - - page = client.goTo("nga/api/v1/jobs/" + projectName + "/builds/" + p.getLastBuild().getNumber(), "application/json"); - snapshot = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), SnapshotNode.class); - assertEquals(projectName, snapshot.getJobCiId()); - assertEquals(projectName, snapshot.getName()); - assertEquals(5, snapshot.getParameters().size()); - assertEquals(0, snapshot.getPhasesInternal().size()); - assertEquals(0, snapshot.getPhasesPostBuild().size()); - assertEquals(1, snapshot.getCauses().size()); - assertEquals(CIEventCauseType.USER, snapshot.getCauses().get(0).getType()); - assertEquals(String.valueOf(p.getLastBuild().getNumber()), snapshot.getNumber()); - assertEquals(CIBuildStatus.FINISHED, snapshot.getStatus()); - assertEquals(CIBuildResult.SUCCESS, snapshot.getResult()); - assertNotNull(snapshot.getStartTime()); - assertNotNull(snapshot.getDuration()); - assertNotNull(snapshot.getEstimatedDuration()); - - tmpParam = snapshot.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertEquals("false", tmpParam.getValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = snapshot.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertEquals("str", tmpParam.getValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = snapshot.getParameters().get(2); - assertEquals("ParamC", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("text", tmpParam.getDescription()); - assertEquals("txt", tmpParam.getDefaultValue()); - assertEquals("txt", tmpParam.getValue()); - - tmpParam = snapshot.getParameters().get(3); - assertEquals("ParamD", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("choice", tmpParam.getDescription()); - assertEquals("one", tmpParam.getDefaultValue()); - assertEquals("two", tmpParam.getValue()); - - tmpParam = snapshot.getParameters().get(4); - assertEquals("ParamE", tmpParam.getName()); - assertEquals(CIParameterType.FILE, tmpParam.getType()); - assertEquals("file param", tmpParam.getDescription()); - assertEquals("", tmpParam.getDefaultValue()); - assertEquals(null, tmpParam.getValue()); - } - - // Snapshot: free-style, with params, with children - // - @Test - public void testFreeStyleWithParamsWithChildren() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - int retries = 0; - rule.jenkins.setNumExecutors(10); - rule.jenkins.setNodes(rule.jenkins.getNodes()); - FreeStyleProject p = rule.createFreeStyleProject(projectName); - createProjectStructure(p); - FreeStyleProject lastToBeBuilt = (FreeStyleProject) rule.jenkins.getItem("jobCC"); - - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") - )); - p.addProperty(params); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - SnapshotNode snapshot; - - assertEquals(p.getBuilds().toArray().length, 0); - Utils.buildProjectWithParams(client, p, "ParamA=false&ParamC=not_exists"); - while ((lastToBeBuilt.getLastBuild() == null || - lastToBeBuilt.getLastBuild().getNumber() < 6 || - lastToBeBuilt.getLastBuild().isBuilding()) && retries++ < 100) { - Thread.sleep(500); - } - assertEquals(p.getBuilds().toArray().length, 1); - - page = client.goTo("nga/api/v1/jobs/" + projectName + "/builds/" + p.getLastBuild().getNumber(), "application/json"); - snapshot = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), SnapshotNode.class); - assertEquals(projectName, snapshot.getJobCiId()); - assertEquals(projectName, snapshot.getName()); - assertEquals(2, snapshot.getParameters().size()); - assertEquals(2, snapshot.getPhasesInternal().size()); - assertEquals(2, snapshot.getPhasesPostBuild().size()); - assertEquals(1, snapshot.getCauses().size()); - assertEquals(CIEventCauseType.USER, snapshot.getCauses().get(0).getType()); - assertEquals(String.valueOf(p.getLastBuild().getNumber()), snapshot.getNumber()); - assertEquals(CIBuildStatus.FINISHED, snapshot.getStatus()); - assertEquals(CIBuildResult.SUCCESS, snapshot.getResult()); - assertNotNull(snapshot.getStartTime()); - assertNotNull(snapshot.getDuration()); - assertNotNull(snapshot.getEstimatedDuration()); - } - - - private void createProjectStructure(FreeStyleProject project) throws IOException { - FreeStyleProject jobA = rule.createFreeStyleProject("jobA"); - FreeStyleProject jobB = rule.createFreeStyleProject("jobB"); - FreeStyleProject jobC = rule.createFreeStyleProject("jobC"); - FreeStyleProject jobAA = rule.createFreeStyleProject("jobAA"); - FreeStyleProject jobBB = rule.createFreeStyleProject("jobBB"); - FreeStyleProject jobCC = rule.createFreeStyleProject("jobCC"); - - - // jobA - jobA.getBuildersList().add(Utils.getSleepScript(5)); - jobA.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobAA, jobC", new BlockingBehaviour( - Result.FAILURE, - Result.FAILURE, - Result.UNSTABLE - ), null) - ))); - - // jobB - jobB.getBuildersList().add(Utils.getSleepScript(2)); - jobB.getPublishersList().add(new hudson.tasks.BuildTrigger("jobBB, jobC", Result.SUCCESS)); - - // jobC - jobC.getBuildersList().add(Utils.getSleepScript(5)); - jobC.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobCC", ResultCondition.ALWAYS, true, null) - ))); - - jobAA.getBuildersList().add(Utils.getSleepScript(2)); - jobBB.getBuildersList().add(Utils.getSleepScript(4)); - jobCC.getBuildersList().add(Utils.getSleepScript(3)); - - // root job config - project.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.FAILURE, - Result.UNSTABLE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC", new BlockingBehaviour( - Result.FAILURE, - Result.FAILURE, - Result.UNSTABLE - ), Arrays.asList(new AbstractBuildParameters[0])) - ))); - project.getPublishersList().add(new hudson.tasks.BuildTrigger("jobA, jobB", Result.SUCCESS)); - project.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobC", ResultCondition.ALWAYS, true, null) - ))); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMatrixTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMatrixTest.java deleted file mode 100644 index 84a8b803f6..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMatrixTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hp.application.automation.tools.octane.actions.build; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.jvnet.hudson.test.JenkinsRule; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:47 - * To change this template use File | Settings | File Templates. - */ - -public class BuildActionsMatrixTest { - -// TBD -// @ClassRule -// final public JenkinsRule rule = new JenkinsRule(); -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMavenTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMavenTest.java deleted file mode 100644 index 139a7b8002..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMavenTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hp.application.automation.tools.octane.actions.build; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.jvnet.hudson.test.JenkinsRule; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:47 - * To change this template use File | Settings | File Templates. - */ - -public class BuildActionsMavenTest { - -// TBD -// @ClassRule -// final public JenkinsRule rule = new JenkinsRule(); -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMultiJobTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMultiJobTest.java deleted file mode 100644 index 7afd7a3e0b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/build/BuildActionsMultiJobTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hp.application.automation.tools.octane.actions.build; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.jvnet.hudson.test.JenkinsRule; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:47 - * To change this template use File | Settings | File Templates. - */ - -public class BuildActionsMultiJobTest { - -// TBD -// @ClassRule -// final public JenkinsRule rule = new JenkinsRule(); -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/plugin/PluginActionsTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/plugin/PluginActionsTest.java deleted file mode 100644 index 691eb231cd..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/plugin/PluginActionsTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.plugin; - -import com.gargoylesoftware.htmlunit.Page; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.general.CIJobsList; -import com.hp.octane.integrations.dto.general.CIProviderSummaryInfo; -import com.hp.octane.integrations.dto.general.CIServerTypes; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.application.automation.tools.octane.actions.PluginActions; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import hudson.model.BooleanParameterDefinition; -import hudson.model.FileParameterDefinition; -import hudson.model.FreeStyleProject; -import hudson.model.ParameterDefinition; -import hudson.model.ParametersDefinitionProperty; -import hudson.model.StringParameterDefinition; -import jenkins.model.Jenkins; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.Arrays; -import java.util.UUID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 07/01/15 - * Time: 22:09 - * To change this template use File | Settings | File Templates. - */ - -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S3578","squid:S2698"}) -public class PluginActionsTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - private final JenkinsRule.WebClient client = rule.createWebClient(); - - @Test - public void testPluginActionsMethods() { - PluginActions pluginActions = new PluginActions(); - assertEquals(pluginActions.getIconFileName(), null); - assertEquals(pluginActions.getDisplayName(), null); - assertEquals("nga", pluginActions.getUrlName()); - } - - @Test - public void testPluginActions_REST_Status() throws IOException, SAXException { - Page page = client.goTo("nga/api/v1/status", "application/json"); - CIProviderSummaryInfo status = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIProviderSummaryInfo.class); - - assertNotNull(status); - - assertNotNull(status.getServer()); - assertEquals(CIServerTypes.JENKINS, status.getServer().getType()); - assertEquals(Jenkins.VERSION, status.getServer().getVersion()); - assertEquals(rule.getInstance().getRootUrl(), status.getServer().getUrl() + "/"); - assertEquals(ConfigurationService.getModel().getIdentity(), status.getServer().getInstanceId()); - assertEquals(ConfigurationService.getModel().getIdentityFrom(), status.getServer().getInstanceIdFrom()); - assertNotNull(status.getServer().getSendingTime()); - - assertNotNull(status.getPlugin()); - assertEquals(ConfigurationService.getPluginVersion(), status.getPlugin().getVersion()); - } - - @Test - public void testPluginActions_REST_Jobs_NoParams() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - Page page = client.goTo("nga/api/v1/jobs", "application/json"); - CIJobsList response = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIJobsList.class); - - assertNotNull(response); - assertNotNull(response.getJobs()); - assertEquals(rule.getInstance().getTopLevelItemNames().size(), response.getJobs().length); - - rule.createFreeStyleProject(projectName); - page = client.goTo("nga/api/v1/jobs", "application/json"); - response = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIJobsList.class); - - assertNotNull(response); - assertNotNull(response.getJobs()); - for (PipelineNode ciJob : response.getJobs()) { - if (projectName.equals(ciJob.getName())) { - assertNotNull(ciJob.getParameters()); - assertEquals(0, ciJob.getParameters().size()); - } - } - } - - @Test - public void testPluginActions_REST_Jobs_WithParams() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject fsp; - Page page = client.goTo("nga/api/v1/jobs", "application/json"); - CIJobsList response = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIJobsList.class); - - assertNotNull(response); - assertNotNull(response.getJobs()); - assertEquals(0, response.getJobs().length); - - fsp = rule.createFreeStyleProject(projectName); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new FileParameterDefinition("ParamC", "file param") - )); - fsp.addProperty(params); - - page = client.goTo("nga/api/v1/jobs", "application/json"); - response = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIJobsList.class); - - assertNotNull(response); - assertNotNull(response.getJobs()); - assertEquals(1, response.getJobs().length); - assertEquals(projectName, response.getJobs()[0].getName()); - assertNotNull(response.getJobs()[0].getParameters()); - assertEquals(3, response.getJobs()[0].getParameters().size()); - - // Test ParamA - assertNotNull(response.getJobs()[0].getParameters().get(0)); - assertEquals("ParamA", response.getJobs()[0].getParameters().get(0).getName()); - assertEquals(CIParameterType.BOOLEAN, response.getJobs()[0].getParameters().get(0).getType()); - assertEquals("bool", response.getJobs()[0].getParameters().get(0).getDescription()); - assertEquals(true, response.getJobs()[0].getParameters().get(0).getDefaultValue()); - - // Test ParamB - assertNotNull(response.getJobs()[0].getParameters().get(1)); - assertEquals("ParamB", response.getJobs()[0].getParameters().get(1).getName()); - assertEquals(CIParameterType.STRING, response.getJobs()[0].getParameters().get(1).getType()); - assertEquals("string", response.getJobs()[0].getParameters().get(1).getDescription()); - assertEquals("str", response.getJobs()[0].getParameters().get(1).getDefaultValue()); - - // Test ParamC - assertNotNull(response.getJobs()[0].getParameters().get(2)); - assertEquals("ParamC", response.getJobs()[0].getParameters().get(2).getName()); - assertEquals(CIParameterType.FILE, response.getJobs()[0].getParameters().get(2).getType()); - assertEquals("file param", response.getJobs()[0].getParameters().get(2).getDescription()); - assertEquals("", response.getJobs()[0].getParameters().get(2).getDefaultValue()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/project/CustomProject.java b/src/test/java/com/hp/application/automation/tools/octane/actions/project/CustomProject.java deleted file mode 100644 index 4b32dbf423..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/project/CustomProject.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.project; - -import hudson.Extension; -import hudson.model.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 12/01/15 - * Time: 17:55 - * To change this template use File | Settings | File Templates. - */ - -@Extension -final public class CustomProject extends Project implements TopLevelItem { - - @Extension(ordinal = 1000) - public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); - - public static final class DescriptorImpl extends AbstractProject.AbstractProjectDescriptor { - public String getDisplayName() { - return "Custom Project"; - } - - public CustomProject newInstance(ItemGroup itemGroup, String name) { - return new CustomProject(itemGroup, name); - } - } - - public CustomProject() { - super(null, null); - } - - public CustomProject(ItemGroup group, String name) { - super(group, name); - } - - @Override - public TopLevelItemDescriptor getDescriptor() { - return DESCRIPTOR; - } - - @Override - protected Class getBuildClass() { - return FreeStyleBuild.class; - } -} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsFreeStyleTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsFreeStyleTest.java deleted file mode 100644 index 238110be67..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsFreeStyleTest.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.project; - -import com.gargoylesoftware.htmlunit.Page; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import hudson.matrix.MatrixProject; -import hudson.maven.MavenModuleSet; -import hudson.model.*; -import hudson.plugins.parameterizedtrigger.*; -import hudson.tasks.BuildTrigger; -import hudson.tasks.Fingerprinter; -import hudson.tasks.Shell; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:39 - * To change this template use File | Settings | File Templates. - */ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701"}) -public class ProjectActionsFreeStyleTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - // Structure test: free-style, no params, no children - // - @Test - public void testStructureFreeStyleNoParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - rule.createFreeStyleProject(projectName); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(0, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - } - - // Structure test: free-style, with params, no children - // - @Test - public void testStructureFreeStyleWithParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject p = rule.createFreeStyleProject(projectName); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), - (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"one", "two", "three"}, "choice"), - (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") - )); - p.addProperty(params); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(5, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(2); - assertEquals("ParamC", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("text", tmpParam.getDescription()); - assertEquals("txt", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(3); - assertEquals("ParamD", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("choice", tmpParam.getDescription()); - assertEquals("one", tmpParam.getDefaultValue()); - assertNotNull(tmpParam.getChoices()); - assertEquals(3, tmpParam.getChoices().length); - assertEquals("one", tmpParam.getChoices()[0]); - assertEquals("two", tmpParam.getChoices()[1]); - assertEquals("three", tmpParam.getChoices()[2]); - - tmpParam = pipeline.getParameters().get(4); - assertEquals("ParamE", tmpParam.getName()); - assertEquals(CIParameterType.FILE, tmpParam.getType()); - assertEquals("file param", tmpParam.getDescription()); - assertEquals("", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - } - - // Structure test: free-style, with params, with children - // - @Test - public void testStructureFreeStyleWithParamsWithChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject p = rule.createFreeStyleProject(projectName); - FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); - MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); - FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); - MavenModuleSet p4 = rule.createProject(MavenModuleSet.class, "jobD"); - CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") - )); - p.addProperty(params); - p.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getBuildersList().add(new Shell("")); - p.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB, jobE", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); - p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) - ))); - p.getPublishersList().add(new Fingerprinter("")); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - CIParameter tmpParam; - List tmpPhases; - PipelineNode tmpNode; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(2, pipeline.getParameters().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - // Phases Internal - // - tmpPhases = pipeline.getPhasesInternal(); - assertEquals(4, tmpPhases.size()); - - // Phase 0 - assertEquals("", tmpPhases.get(0).getName()); - assertEquals(true, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 2 - assertEquals("", tmpPhases.get(2).getName()); - assertEquals(true, tmpPhases.get(2).isBlocking()); - assertEquals(3, tmpPhases.get(2).getJobs().size()); - - tmpNode = tmpPhases.get(2).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(2).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(2).getJobs().get(2); - assertEquals("jobE", tmpNode.getJobCiId()); - assertEquals("jobE", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 3 - assertEquals("", tmpPhases.get(3).getName()); - assertEquals(false, tmpPhases.get(3).isBlocking()); - assertEquals(2, tmpPhases.get(3).getJobs().size()); - - tmpNode = tmpPhases.get(3).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(3).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phases Post build - // - tmpPhases = pipeline.getPhasesPostBuild(); - assertEquals(2, tmpPhases.size()); - - // Phase 0 - assertEquals("downstream", tmpPhases.get(0).getName()); - assertEquals(false, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMatrixTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMatrixTest.java deleted file mode 100644 index 5476a05195..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMatrixTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.project; - -import com.gargoylesoftware.htmlunit.Page; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import hudson.matrix.MatrixProject; -import hudson.maven.MavenModuleSet; -import hudson.model.*; -import hudson.plugins.parameterizedtrigger.*; -import hudson.tasks.BuildTrigger; -import hudson.tasks.Fingerprinter; -import hudson.tasks.Shell; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:41 - * To change this template use File | Settings | File Templates. - */ - -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701"}) -public class ProjectActionsMatrixTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - // Structure test: matrix, no params, no children - // - @Test - public void testStructureMatrixNoParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - rule.createProject(MatrixProject.class, projectName); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(0, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - } - - // Structure test: matrix, with params, no children - // - @Test - public void testStructureMatrixWithParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MatrixProject p = rule.createProject(MatrixProject.class, projectName); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), - (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"1", "2", "3"}, "choice"), - (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") - )); - p.addProperty(params); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(5, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(2); - assertEquals("ParamC", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("text", tmpParam.getDescription()); - assertEquals("txt", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(3); - assertEquals("ParamD", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("choice", tmpParam.getDescription()); - assertEquals("1", tmpParam.getDefaultValue()); - assertNotNull(tmpParam.getChoices()); - assertEquals(3, tmpParam.getChoices().length); - assertEquals("1", tmpParam.getChoices()[0]); - assertEquals("2", tmpParam.getChoices()[1]); - assertEquals("3", tmpParam.getChoices()[2]); - - tmpParam = pipeline.getParameters().get(4); - assertEquals("ParamE", tmpParam.getName()); - assertEquals(CIParameterType.FILE, tmpParam.getType()); - assertEquals("file param", tmpParam.getDescription()); - assertEquals("", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - } - - // Structure test: matrix, with params, with children - // - @Test - public void testStructureMatrixWithParamsWithChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MatrixProject p = rule.createProject(MatrixProject.class, projectName); - FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); - MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); - FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); - MavenModuleSet p4 = rule.createProject(MavenModuleSet.class, "jobD"); - CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") - )); - p.addProperty(params); - p.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getBuildersList().add(new Shell("")); - p.getPublishersList().add(new Fingerprinter("")); - p.getPublishersList().add(new BuildTrigger("jobA, jobB, JobE", Result.SUCCESS)); - p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) - ))); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - List tmpPhases; - PipelineNode tmpNode; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(2, pipeline.getParameters().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - // Phases Internal - // - tmpPhases = pipeline.getPhasesInternal(); - assertEquals(2, tmpPhases.size()); - - // Phase 0 - assertEquals("", tmpPhases.get(0).getName()); - assertEquals(true, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phases Post build - // - tmpPhases = pipeline.getPhasesPostBuild(); - assertEquals(2, tmpPhases.size()); - - // Phase 0 - assertEquals("downstream", tmpPhases.get(0).getName()); - assertEquals(false, tmpPhases.get(0).isBlocking()); - assertEquals(3, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(2); - assertEquals("jobE", tmpNode.getJobCiId()); - assertEquals("jobE", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMavenTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMavenTest.java deleted file mode 100644 index 605596c7d4..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMavenTest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.project; - -import com.gargoylesoftware.htmlunit.HttpMethod; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.WebRequest; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import hudson.matrix.MatrixProject; -import hudson.maven.MavenModuleSet; -import hudson.model.*; -import hudson.plugins.parameterizedtrigger.*; -import hudson.tasks.BuildTrigger; -import hudson.tasks.Fingerprinter; -import hudson.tasks.Shell; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.net.URL; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:42 - * To change this template use File | Settings | File Templates. - */ - -public class ProjectActionsMavenTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - private final JenkinsRule.WebClient client = rule.createWebClient(); - - // Structure test: maven, no params, no children - // - @Test - public void testStructureMavenNoParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); - project.runHeadless(); - Page page; - PipelineNode pipeline; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(0, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - } - - @Test - //@Ignore - public void testDoRun() throws IOException, SAXException, InterruptedException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - int retries = 0; - MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); - p.runHeadless(); - - WebRequest webRequest = new WebRequest(new URL(client.getContextPath() + "nga/api/v1/jobs/" + projectName + "/run"), HttpMethod.GET); - client.loadWebResponse(webRequest); - - while ((p.getLastBuild() == null || p.getLastBuild().isBuilding()) && ++retries < 20) { - Thread.sleep(1000); - } - assertEquals(p.getBuilds().toArray().length, 1); - } - - // Structure test: maven, with params, no children - // - @Test - public void testStructureMavenWithParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); - p.runHeadless(); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), - (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"one", "two", "three"}, "choice"), - (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") - )); - p.addProperty(params); - - Page page; - PipelineNode pipeline; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(5, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(2); - assertEquals("ParamC", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("text", tmpParam.getDescription()); - assertEquals("txt", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(3); - assertEquals("ParamD", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("choice", tmpParam.getDescription()); - assertEquals("one", tmpParam.getDefaultValue()); - assertNotNull(tmpParam.getChoices()); - assertEquals(3, tmpParam.getChoices().length); - assertEquals("one", tmpParam.getChoices()[0]); - assertEquals("two", tmpParam.getChoices()[1]); - assertEquals("three", tmpParam.getChoices()[2]); - - tmpParam = pipeline.getParameters().get(4); - assertEquals("ParamE", tmpParam.getName()); - assertEquals(CIParameterType.FILE, tmpParam.getType()); - assertEquals("file param", tmpParam.getDescription()); - assertEquals("", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - } - - // Structure test: maven, with params, with children - // - @Test - public void testStructureMavenWithParamsWithChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); - p.runHeadless(); - FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); - MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); - FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); - MatrixProject p4 = rule.createProject(MatrixProject.class, "jobD"); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") - )); - p.addProperty(params); - p.getPrebuilders().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC, jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getPrebuilders().add(new Shell("")); - p.getPostbuilders().add(new Shell("")); - p.getPostbuilders().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC, jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); - p.getPublishersList().add(new Fingerprinter("")); - p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobC, jobD", ResultCondition.ALWAYS, false, null) - ))); - - Page page; - PipelineNode pipeline; - List tmpPhases; - PipelineNode tmpNode; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(2, pipeline.getParameters().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - // Phases Internal - // - tmpPhases = pipeline.getPhasesInternal(); - assertEquals(4, tmpPhases.size()); - - // Phase 0 - assertEquals("pre-maven", tmpPhases.get(0).getName()); - assertEquals(true, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("pre-maven", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 2 - assertEquals("post-maven", tmpPhases.get(2).getName()); - assertEquals(true, tmpPhases.get(2).isBlocking()); - assertEquals(2, tmpPhases.get(2).getJobs().size()); - - tmpNode = tmpPhases.get(2).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(2).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 3 - assertEquals("post-maven", tmpPhases.get(3).getName()); - assertEquals(false, tmpPhases.get(3).isBlocking()); - assertEquals(2, tmpPhases.get(3).getJobs().size()); - - tmpNode = tmpPhases.get(3).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(3).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phases Post build - // - tmpPhases = pipeline.getPhasesPostBuild(); - assertEquals(2, tmpPhases.size()); - - // Phase 0 - assertEquals("downstream", tmpPhases.get(0).getName()); - assertEquals(false, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMultiJobTest.java b/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMultiJobTest.java deleted file mode 100644 index e6beb946e4..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/actions/project/ProjectActionsMultiJobTest.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.actions.project; - -import com.gargoylesoftware.htmlunit.Page; -import com.hp.octane.integrations.dto.DTOFactory; -import com.hp.octane.integrations.dto.parameters.CIParameter; -import com.hp.octane.integrations.dto.parameters.CIParameterType; -import com.hp.octane.integrations.dto.pipelines.PipelineNode; -import com.hp.octane.integrations.dto.pipelines.PipelinePhase; -import com.tikal.jenkins.plugins.multijob.MultiJobBuilder; -import com.tikal.jenkins.plugins.multijob.MultiJobProject; -import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig; -import hudson.matrix.MatrixProject; -import hudson.model.*; -import hudson.plugins.parameterizedtrigger.*; -import hudson.tasks.BuildTrigger; -import hudson.tasks.Fingerprinter; -import hudson.tasks.Shell; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 11:44 - * To change this template use File | Settings | File Templates. - */ - -public class ProjectActionsMultiJobTest { - private static final DTOFactory dtoFactory = DTOFactory.getInstance(); - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - // Structure test: multi-job, no params, no children - // - @Test - public void testStructureMultiJobNoParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - rule.getInstance().createProject(MultiJobProject.class, projectName); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(0, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - } - - // Structure test: multi-job, with params, no children - // - @Test - public void testStructureMultiJobWithParamsNoChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MultiJobProject p = rule.getInstance().createProject(MultiJobProject.class, projectName); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), - (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), - (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"A", "B", "C"}, "choice"), - (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") - )); - p.addProperty(params); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(5, pipeline.getParameters().size()); - assertEquals(0, pipeline.getPhasesInternal().size()); - assertEquals(0, pipeline.getPhasesPostBuild().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(2); - assertEquals("ParamC", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("text", tmpParam.getDescription()); - assertEquals("txt", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(3); - assertEquals("ParamD", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("choice", tmpParam.getDescription()); - assertEquals("A", tmpParam.getDefaultValue()); - assertNotNull(tmpParam.getChoices()); - assertEquals(3, tmpParam.getChoices().length); - assertEquals("A", tmpParam.getChoices()[0]); - assertEquals("B", tmpParam.getChoices()[1]); - assertEquals("C", tmpParam.getChoices()[2]); - - tmpParam = pipeline.getParameters().get(4); - assertEquals("ParamE", tmpParam.getName()); - assertEquals(CIParameterType.FILE, tmpParam.getType()); - assertEquals("file param", tmpParam.getDescription()); - assertEquals("", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - } - - // Structure test: multi-job, with params, with children - // - @Test - public void testStructureMultiJobWithParamsWithChildren() throws IOException, SAXException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MultiJobProject p = rule.getInstance().createProject(MultiJobProject.class, projectName); - FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); - MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); - MultiJobProject p3 = rule.getInstance().createProject(MultiJobProject.class, "jobC"); - MatrixProject p4 = rule.createProject(MatrixProject.class, "jobD"); - CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); - ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( - (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), - (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") - )); - p.addProperty(params); - p.getBuildersList().add(new TriggerBuilder(Arrays.asList( - new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( - Result.FAILURE, - Result.UNSTABLE, - Result.FAILURE - ), Arrays.asList(new AbstractBuildParameters[0])), - new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) - ))); - p.getBuildersList().add(new MultiJobBuilder( - "Build", - Arrays.asList( - new PhaseJobsConfig("jobA", "", false, null, PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "", false), - new PhaseJobsConfig("jobB", "", false, null, PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "", false), - new PhaseJobsConfig("jobE", "", false, null, PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "", false) - ), - MultiJobBuilder.ContinuationCondition.SUCCESSFUL - )); - p.getBuildersList().add(new Shell("")); - p.getBuildersList().add(new MultiJobBuilder( - "Test", - Arrays.asList( - new PhaseJobsConfig("jobC", "", false, null, PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "", false), - new PhaseJobsConfig("jobD", "", false, null, PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "", false) - ), - MultiJobBuilder.ContinuationCondition.SUCCESSFUL - )); - p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); - p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( - new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) - ))); - p.getPublishersList().add(new Fingerprinter("")); - - JenkinsRule.WebClient client = rule.createWebClient(); - Page page; - PipelineNode pipeline; - List tmpPhases; - PipelineNode tmpNode; - CIParameter tmpParam; - - page = client.goTo("nga/api/v1/jobs/" + projectName, "application/json"); - pipeline = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), PipelineNode.class); - assertEquals(projectName, pipeline.getJobCiId()); - assertEquals(projectName, pipeline.getName()); - assertEquals(2, pipeline.getParameters().size()); - - tmpParam = pipeline.getParameters().get(0); - assertEquals("ParamA", tmpParam.getName()); - assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); - assertEquals("bool", tmpParam.getDescription()); - assertEquals(true, tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - tmpParam = pipeline.getParameters().get(1); - assertEquals("ParamB", tmpParam.getName()); - assertEquals(CIParameterType.STRING, tmpParam.getType()); - assertEquals("string", tmpParam.getDescription()); - assertEquals("str", tmpParam.getDefaultValue()); - assertNull(tmpParam.getChoices()); - - // Phases Internal - // - tmpPhases = pipeline.getPhasesInternal(); - assertEquals(4, tmpPhases.size()); - - // Phase 0 - assertEquals("", tmpPhases.get(0).getName()); - assertEquals(true, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 2 - assertEquals("Build", tmpPhases.get(2).getName()); - assertEquals(true, tmpPhases.get(2).isBlocking()); - assertEquals(3, tmpPhases.get(2).getJobs().size()); - - tmpNode = tmpPhases.get(2).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(2).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(2).getJobs().get(2); - assertEquals("jobE", tmpNode.getJobCiId()); - assertEquals("jobE", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 3 - assertEquals("Test", tmpPhases.get(3).getName()); - assertEquals(true, tmpPhases.get(3).isBlocking()); - assertEquals(2, tmpPhases.get(3).getJobs().size()); - - tmpNode = tmpPhases.get(3).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(3).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phases Post build - // - tmpPhases = pipeline.getPhasesPostBuild(); - assertEquals(2, tmpPhases.size()); - - // Phase 0 - assertEquals("downstream", tmpPhases.get(0).getName()); - assertEquals(false, tmpPhases.get(0).isBlocking()); - assertEquals(2, tmpPhases.get(0).getJobs().size()); - - tmpNode = tmpPhases.get(0).getJobs().get(0); - assertEquals("jobA", tmpNode.getJobCiId()); - assertEquals("jobA", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(0).getJobs().get(1); - assertEquals("jobB", tmpNode.getJobCiId()); - assertEquals("jobB", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - - // Phase 1 - assertEquals("", tmpPhases.get(1).getName()); - assertEquals(false, tmpPhases.get(1).isBlocking()); - assertEquals(2, tmpPhases.get(1).getJobs().size()); - - tmpNode = tmpPhases.get(1).getJobs().get(0); - assertEquals("jobC", tmpNode.getJobCiId()); - assertEquals("jobC", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - tmpNode = tmpPhases.get(1).getJobs().get(1); - assertEquals("jobD", tmpNode.getJobCiId()); - assertEquals("jobD", tmpNode.getName()); - assertEquals(0, tmpNode.getParameters().size()); - assertEquals(0, tmpNode.getPhasesInternal().size()); - assertEquals(0, tmpNode.getPhasesPostBuild().size()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/client/RetryModelTest.java b/src/test/java/com/hp/application/automation/tools/octane/client/RetryModelTest.java deleted file mode 100644 index a7b4c79e74..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/client/RetryModelTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.client; - -import hudson.util.TimeUnit2; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -@SuppressWarnings("squid:S2699") -public class RetryModelTest { - - private RetryModel retryModel; - private TestTimeProvider testTimeProvider; - private TestEventPublisher testEventPublisher; - - @Before - public void init() { - testEventPublisher = new TestEventPublisher(); - retryModel = new RetryModel(testEventPublisher); - testTimeProvider = new TestTimeProvider(); - retryModel.setTimeProvider(testTimeProvider); - } - - @Test - public void testRetryModel() { - Assert.assertFalse(retryModel.isQuietPeriod()); - - retryModel.failure(); - // 1 minute - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.SECONDS.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.SECONDS.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.SECONDS.toMillis(25)); - Assert.assertFalse(retryModel.isQuietPeriod()); - - retryModel.failure(); - // 10 minutes - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(4)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(4)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(4)); - Assert.assertFalse(retryModel.isQuietPeriod()); - - retryModel.failure(); - // 60 minutes - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertFalse(retryModel.isQuietPeriod()); - - retryModel.failure(); - // 60 minutes - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.MINUTES.toMillis(25)); - Assert.assertFalse(retryModel.isQuietPeriod()); - } - - @Test - public void testRetryModelSuccess() { - Assert.assertFalse(retryModel.isQuietPeriod()); - - retryModel.failure(); - // 1 minute - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.SECONDS.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - testTimeProvider.addOffset(TimeUnit2.SECONDS.toMillis(25)); - Assert.assertTrue(retryModel.isQuietPeriod()); - Assert.assertEquals(0, testEventPublisher.getResumeCount()); - retryModel.success(); - Assert.assertFalse(retryModel.isQuietPeriod()); - Assert.assertEquals(1, testEventPublisher.getResumeCount()); - } - - private static class TestTimeProvider implements RetryModel.TimeProvider { - - private long time = System.currentTimeMillis(); - - public void addOffset(long time) { - this.time += time; - } - - @Override - public long getTime() { - return time; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/client/TestEventPublisher.java b/src/test/java/com/hp/application/automation/tools/octane/client/TestEventPublisher.java deleted file mode 100644 index c7ec947e5b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/client/TestEventPublisher.java +++ /dev/null @@ -1,27 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.client; - -public class TestEventPublisher implements EventPublisher { - - private boolean suspended; - private int resumeCount; - - @Override - public boolean isSuspended() { - return suspended; - } - - @Override - public void resume() { - ++resumeCount; - } - - public void setSuspended(boolean suspended) { - this.suspended = suspended; - } - - public int getResumeCount() { - return resumeCount; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigApiTest.java b/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigApiTest.java deleted file mode 100644 index fe8a4dd4a4..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigApiTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.HttpMethod; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.WebRequest; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import hudson.util.Secret; -import net.jcip.annotations.NotThreadSafe; -import net.sf.json.JSONObject; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; - -// import com.gargoylesoftware.htmlunit.WebRequestSettings; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -@NotThreadSafe -public class ConfigApiTest { - - @ClassRule - static final public JenkinsRule rule = new JenkinsRule(); - static final private JenkinsRule.WebClient client = rule.createWebClient(); - - @Before - public void init() throws Exception { - HtmlPage configPage = client.goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8008/ui/?p=1001/1002"); - form.getInputByName("_.username").setValueAttribute("username"); - form.getInputByName("_.password").setValueAttribute("password"); - rule.submit(form); - } - - @Test - public void testRead() throws Exception { - Page page = client.goTo("nga/configuration/read", "application/json"); - String configAsString = page.getWebResponse().getContentAsString(); - JSONObject config = JSONObject.fromObject(configAsString); - Assert.assertEquals("http://localhost:8008", config.getString("location")); - Assert.assertEquals("1001", config.getString("sharedSpace")); - Assert.assertEquals("username", config.getString("username")); - Assert.assertEquals(ConfigurationService.getModel().getIdentity(), config.getString("serverIdentity")); - } - - @Test - public void testSave() throws Exception { - //URL url = client.createCrumbedUrl("nga/configuration/save"); - //WebRequest request = new WebRequest(url,HttpMethod.POST); - - // basic scenario: location, shared space and credentials - JSONObject config = new JSONObject(); - config.put("location", "http://localhost:8088"); - config.put("sharedSpace", "1001"); - config.put("username", "username1"); - config.put("password", "password1"); - JenkinsRule.WebClient wc = rule.createWebClient(); - WebRequest req = new WebRequest(wc.createCrumbedUrl("nga/configuration/save"), HttpMethod.POST); - req.setEncodingType(null); - req.setRequestBody(config.toString()); - Page page = wc.getPage(req); - config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); - checkConfig(config, "http://localhost:8088", "1001", "username1", Secret.fromString("password1")); - Assert.assertEquals(ConfigurationService.getModel().getIdentity(), config.getString("serverIdentity")); - - - // location, shared space, no credentials - config = new JSONObject(); - config.put("location", "http://localhost:8888"); - config.put("sharedSpace", "1002"); - req.setRequestBody(config.toString()); - page = client.getPage(req); - config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); - checkConfig(config, "http://localhost:8888", "1002", "username1", Secret.fromString("password1")); - Assert.assertEquals(ConfigurationService.getModel().getIdentity(), config.getString("serverIdentity")); -// - // location, shared space and username without password - config = new JSONObject(); - config.put("location", "http://localhost:8882"); - config.put("sharedSpace", "1003"); - config.put("username", "username3"); - req.setRequestBody(config.toString()); - page = client.getPage(req); - config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); - checkConfig(config, "http://localhost:8882", "1003", "username3", Secret.fromString("")); - Assert.assertEquals(ConfigurationService.getModel().getIdentity(), config.getString("serverIdentity")); - - // uiLocation and identity - config = new JSONObject(); - config.put("uiLocation", "http://localhost:8881/ui?p=1001/1002"); - config.put("serverIdentity", "2d2fa955-1d13-4d8c-947f-ab11c72bf850"); - req.setRequestBody(config.toString()); - page = client.getPage(req); - config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); - checkConfig(config, "http://localhost:8881", "1001", "username3", Secret.fromString("")); - Assert.assertEquals("2d2fa955-1d13-4d8c-947f-ab11c72bf850", config.getString("serverIdentity")); - Assert.assertEquals("2d2fa955-1d13-4d8c-947f-ab11c72bf850", ConfigurationService.getModel().getIdentity()); - - // requires POST - req.setHttpMethod(HttpMethod.GET); - try { - client.getPage(req); - Assert.fail("Only POST should be allowed"); - } catch (FailingHttpStatusCodeException ex) { - // expected - } - } - - - - - - - - - - - - - - - - - - private void checkConfig(JSONObject config, String location, String sharedSpace, String username, Secret password) { - // check values returned - Assert.assertEquals(location, config.getString("location")); - Assert.assertEquals(sharedSpace, config.getString("sharedSpace")); - Assert.assertEquals(username, config.getString("username")); - // check values stored - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - Assert.assertEquals(location, serverConfiguration.location); - Assert.assertEquals(sharedSpace, serverConfiguration.sharedSpace); - Assert.assertEquals(username, serverConfiguration.username); - Assert.assertEquals(password, serverConfiguration.password); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java b/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java deleted file mode 100644 index 87d91461fc..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.hp.application.automation.tools.octane.tests.ExtensionUtil; -import hudson.matrix.Axis; -import hudson.matrix.AxisList; -import hudson.matrix.MatrixConfiguration; -import hudson.matrix.MatrixProject; -import hudson.model.FreeStyleProject; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -import java.io.IOException; - -public class ConfigurationActionFactoryTest { - - @ClassRule - static final public JenkinsRule jenkins = new JenkinsRule(); - - private ConfigurationActionFactory configurationActionFactory; - - @Before - public void initialize() { - configurationActionFactory = ExtensionUtil.getInstance(jenkins, ConfigurationActionFactory .class); - } - - @Test - public void testMatrixJob() throws IOException { - - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class, "ConfigurationActionFactoryTest.testMatrixJob"); - //jenkins.createMatrixProject("ConfigurationActionFactoryTest.testMatrixJob"); - matrixProject.setAxes(new AxisList(new Axis("OS", "Linux", "Windows"))); - - Assert.assertEquals(1, configurationActionFactory.createFor(matrixProject).size()); - for (MatrixConfiguration configuration: matrixProject.getItems()) { - Assert.assertEquals(0, configurationActionFactory.createFor(configuration).size()); - } - } - - @Test - public void testFreeStyleJob() throws IOException { - FreeStyleProject project = jenkins.createFreeStyleProject("ConfigurationActionFactoryTest.testFreeStyleJob"); - Assert.assertEquals(1, configurationActionFactory.createFor(project).size()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListenerTest.java b/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListenerTest.java deleted file mode 100644 index 7ae3a73f68..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationListenerTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.hp.application.automation.tools.octane.tests.ExtensionUtil; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.TestExtension; - -import java.util.ArrayList; -import java.util.List; - -public class ConfigurationListenerTest { - - @ClassRule - static final public JenkinsRule rule = new JenkinsRule(); - - private TestConfigurationListener listener; - - @Before - public void init() throws Exception { - HtmlPage configPage = rule.createWebClient().goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - - form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8028/ui/?p=1001/1002"); - form.getInputByName("_.username").setValueAttribute("username"); - form.getInputByName("_.password").setValueAttribute("password"); - rule.submit(form); - - listener = ExtensionUtil.getInstance(rule, TestConfigurationListener.class); - Assert.assertEquals("Listener count doesn't match 1",1, listener.getCount()); - - List confs = listener.getConfigurationsChange(); - Assert.assertNotNull("Configuration is null",confs); - Assert.assertEquals("Config size doesn't match 2",2, confs.size()); - Assert.assertEquals("location doesn't match localhost:8020","http://localhost:8028", confs.get(0).location); - Assert.assertEquals("username doesn't match username","username", confs.get(0).username); - Assert.assertNull(confs.get(1).location); - Assert.assertNull(confs.get(1).username); - } - - @Test - public void testConfigurationListener() throws Exception { - HtmlPage configPage = rule.createWebClient().goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - // password is cleared upon form retrieval (restore the value) - form.getInputByName("_.password").setValueAttribute("password"); - - // not increased on re-submit - rule.submit(form); - Assert.assertEquals("Listener count doesn't match 1",1, listener.getCount()); - - configPage = rule.createWebClient().goTo("configure"); - form = configPage.getFormByName("config"); - // increased when configuration changes - form.getInputByName("_.username").setValueAttribute("username2"); - rule.submit(form); - Assert.assertEquals("Listener count doesn't match 2",2, listener.getCount()); - - List confs = listener.getConfigurationsChange(); - Assert.assertNotNull("Configuration is null",confs); - Assert.assertEquals("Config count doesn't match 2",2, confs.size()); - Assert.assertEquals("http://localhost:8028", confs.get(0).location); - Assert.assertEquals("username2", confs.get(0).username); - Assert.assertEquals("http://localhost:8028", confs.get(1).location); - Assert.assertEquals("username", confs.get(1).username); - } - - @TestExtension - public static class TestConfigurationListener implements ConfigurationListener { - - private int count; - private List newAndOld; - - @Override - public void onChanged(ServerConfiguration conf, ServerConfiguration oldConf) { - ++count; - newAndOld = new ArrayList<>(); - newAndOld.add(conf); - newAndOld.add(oldConf); - } - - public int getCount() { - return count; - } - - public List getConfigurationsChange() { - return newAndOld; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationServiceTest.java b/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationServiceTest.java deleted file mode 100644 index 9bdc9e3586..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/configuration/ConfigurationServiceTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.configuration; - -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.hp.application.automation.tools.octane.tests.ExtensionUtil; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.AuthenticationException; -import com.hp.mqm.client.exception.SharedSpaceNotExistException; -import com.hp.application.automation.tools.octane.Messages; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import hudson.util.FormValidation; -import hudson.util.Secret; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.mockito.Mockito; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -public class ConfigurationServiceTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - private final JenkinsRule.WebClient jClient = rule.createWebClient(); - - private ConfigurationParser configurationParser; - private JenkinsMqmRestClientFactory clientFactory; - private MqmRestClient client; - private Secret password; - - @Before - public void init() throws Exception { - client = Mockito.mock(MqmRestClient.class); - clientFactory = Mockito.mock(JenkinsMqmRestClientFactory.class); - configurationParser = ExtensionUtil.getInstance(rule, ConfigurationParser.class); - configurationParser._setMqmRestClientFactory(clientFactory); - password = Secret.fromString("password"); - - HtmlPage configPage = jClient.goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - - form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8008/ui/?p=1001/1002"); - form.getInputByName("_.username").setValueAttribute("username"); - form.getInputByName("_.password").setValueAttribute("password"); - rule.submit(form); - } - - @Test - public void testGetServerConfiguration() throws Exception { - ServerConfiguration configuration = ConfigurationService.getServerConfiguration(); - Assert.assertEquals("http://localhost:8008", configuration.location); - Assert.assertEquals("1001", configuration.sharedSpace); - Assert.assertEquals("username", configuration.username); - Assert.assertEquals(password, configuration.password); - } - - @Test - public void testConfigurationRoundTrip() throws Exception { - HtmlForm formIn = jClient.goTo("configure").getFormByName("config"); - rule.submit(formIn); - HtmlForm formOut = jClient.goTo("configure").getFormByName("config"); - Assert.assertEquals(formIn.getInputByName("_.uiLocation").getValueAttribute(), formOut.getInputByName("_.uiLocation").getValueAttribute()); - Assert.assertEquals(formIn.getInputByName("_.username").getValueAttribute(), formOut.getInputByName("_.username").getValueAttribute()); - // NOTE: password is actually empty (bug or security feature?) - Assert.assertEquals(formIn.getInputByName("_.password").getValueAttribute(), formOut.getInputByName("_.password").getValueAttribute()); - } - - @Test - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void testCheckConfiguration() { - Mockito.when(clientFactory.obtainTemp("http://localhost:8088/", "1001", "username1", password)).thenReturn(client); - - // valid configuration - Mockito.doNothing().when(client).validateConfiguration(); - - FormValidation validation = configurationParser.checkConfiguration("http://localhost:8088/", "1001", "username1", password); - Assert.assertEquals(FormValidation.Kind.OK, validation.kind); - Assert.assertTrue(validation.getMessage().contains("Connection successful")); - - // authentication failed - Mockito.doThrow(new AuthenticationException()).when(client).validateConfiguration(); - - validation = configurationParser.checkConfiguration("http://localhost:8088/", "1001", "username1", password); - Assert.assertEquals(FormValidation.Kind.ERROR, validation.kind); - Assert.assertTrue(validation.getMessage().contains(Messages.AuthenticationFailure())); - - // domain project does not exists - Mockito.doThrow(new SharedSpaceNotExistException()).when(client).validateConfiguration(); - - validation = configurationParser.checkConfiguration("http://localhost:8088/", "1001", "username1", password); - Assert.assertEquals(FormValidation.Kind.ERROR, validation.kind); - Assert.assertTrue(validation.getMessage().contains(Messages.ConnectionSharedSpaceInvalid())); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/detection/ResultFieldsTest.java b/src/test/java/com/hp/application/automation/tools/octane/detection/ResultFieldsTest.java deleted file mode 100644 index aad44489a0..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/detection/ResultFieldsTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hp.application.automation.tools.octane.detection; - -import com.hp.application.automation.tools.octane.tests.detection.ResultFields; -import org.junit.Assert; -import org.junit.Test; - -public class ResultFieldsTest { - - @Test - public void testEquals() { - ResultFields x = new ResultFields("foo", "bar", null); - Assert.assertTrue(x.equals(x)); - Assert.assertTrue(!x.equals(null)); - - ResultFields y = new ResultFields("foo", "bar", null); - Assert.assertTrue(x.equals(y) && y.equals(x)); - Assert.assertTrue(x.hashCode() == y.hashCode()); - - ResultFields z = new ResultFields("foo", "bar", ""); - Assert.assertTrue(!x.equals(z) && !z.equals(x)); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/events/EventsTest.java b/src/test/java/com/hp/application/automation/tools/octane/events/EventsTest.java deleted file mode 100644 index ea43cac981..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/events/EventsTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.events; - -import com.hp.application.automation.tools.model.OctaneServerSettingsModel; -import com.hp.application.automation.tools.octane.tests.ExtensionUtil; -import com.hp.octane.integrations.dto.events.CIEventType; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import com.hp.application.automation.tools.octane.configuration.ServerConfiguration; -import hudson.model.FreeStyleProject; -import hudson.util.Secret; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; - -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.logging.Logger; - -import static org.junit.Assert.*; - -/** - * Created with IntelliJ IDEA. - * User: gullery - * Date: 13/01/15 - * Time: 22:05 - * To change this template use File | Settings | File Templates. - */ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -public class EventsTest { - private static final Logger logger = Logger.getLogger(EventsTest.class.getName()); - - static final private String projectName = "root-job-events-case"; - static final private int DEFAULT_TESTING_SERVER_PORT = 9999; - static final private String sharedSpaceId = "1007"; - static final private String username = "some"; - static final private String password = "pass"; - - static private Server server; - static private int testingServerPort = DEFAULT_TESTING_SERVER_PORT; - static private EventsHandler eventsHandler; - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - @BeforeClass - static public void beforeClass() throws Exception { - String p = System.getProperty("testingServerPort"); - try { - if (p != null) testingServerPort = Integer.parseInt(p); - } catch (NumberFormatException nfe) { - logger.info("EVENTS TEST: bad port number format, default port will be used: " + testingServerPort); - } - logger.info("EVENTS TEST: port chosen for mock Octane server: " + testingServerPort); - - eventsHandler = new EventsHandler(); - server = new Server(testingServerPort); - server.setHandler(eventsHandler); - server.start(); - logger.info("EVENTS TEST: mock Octane server started on local port " + testingServerPort); - } - - @AfterClass - static public void afterClass() throws Exception { - logger.info("EVENTS TEST: stopping and destroying mock Octane server"); - server.stop(); - server.destroy(); - } - - @Test - @Ignore - public void testEventsA() throws Exception { - configurePlugin(); - - EventsService eventsService = ExtensionUtil.getInstance(rule, EventsService.class); - assertNotNull(eventsService.getClient()); - assertEquals("http://127.0.0.1:" + testingServerPort, eventsService.getClient().getLocation()); - assertEquals(sharedSpaceId, eventsService.getClient().getSharedSpace()); - logger.info("EVENTS TEST: event client configuration is: " + - eventsService.getClient().getLocation() + " - " + - eventsService.getClient().getSharedSpace() + " - " + - eventsService.getClient().getUsername()); - - FreeStyleProject p = rule.createFreeStyleProject(projectName); - - assertEquals(0, p.getBuilds().toArray().length); - p.scheduleBuild2(0); - while (p.getLastBuild() == null || p.getLastBuild().isBuilding()) { - Thread.sleep(1000); - } - assertEquals(1, p.getBuilds().toArray().length); - Thread.sleep(5000); - - List eventsOrder = new ArrayList<>(Arrays.asList(CIEventType.STARTED, CIEventType.FINISHED)); - List eventsLists = eventsHandler.getResults(); - JSONObject tmp; - JSONArray events; - logger.info(eventsLists.toString()); - System.out.print(eventsLists.toString()); - logger.info("EVENTS TEST: server mock received " + eventsLists.size() + " list/s of events"); - for (JSONObject l : eventsLists) { - assertEquals(2, l.length()); - - assertFalse(l.isNull("server")); - tmp = l.getJSONObject("server"); - assertTrue(rule.getInstance().getRootUrl().startsWith(tmp.getString("url"))); - assertEquals("jenkins", tmp.getString("type")); - assertEquals(ConfigurationService.getModel().getIdentity(), tmp.getString("instanceId")); - - assertFalse(l.isNull("events")); - events = l.getJSONArray("events"); - for (int i = 0; i < events.length(); i++) { - tmp = events.getJSONObject(i); - if (tmp.getString("project").equals(projectName)) { - assertEquals(eventsOrder.get(0), CIEventType.fromValue(tmp.getString("eventType"))); - eventsOrder.remove(0); - } - } - } - assertEquals(0, eventsOrder.size()); - } - - private static final class EventsHandler extends AbstractHandler { - private final List eventsLists = new ArrayList<>(); - - @Override - public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - logger.info("EVENTS TEST: server mock requested: " + baseRequest.getMethod() + " " + baseRequest.getPathInfo()); - - String body = ""; - byte[] buffer; - int len; - if (request.getPathInfo().equals("/authentication/sign_in")) { - response.addCookie(new Cookie("LWSSO_COOKIE_KEY", "some_dummy_security_token")); - response.setStatus(HttpServletResponse.SC_OK); - } else if (request.getPathInfo().endsWith("/tasks")) { - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - // do nothing here - } finally { - response.setStatus(HttpServletResponse.SC_OK); - } - } else if (request.getPathInfo().equals("/internal-api/shared_spaces/" + sharedSpaceId + "/analytics/ci/events")) { - buffer = new byte[1024]; - while ((len = request.getInputStream().read(buffer, 0, 1024)) > 0) { - body += new String(buffer, 0, len); - } - try { - eventsLists.add(new JSONObject(body)); - } catch (JSONException e) { - logger.warning("EVENTS TEST: response wasn't JSON compatible"); - } - logger.info("EVENTS TEST: server mock events list length " + eventsLists.size()); - response.setStatus(HttpServletResponse.SC_OK); - } - baseRequest.setHandled(true); - } - - List getResults() { - return eventsLists; - } - } - - private void configurePlugin() throws Exception { - OctaneServerSettingsModel model = new OctaneServerSettingsModel("http://127.0.0.1:" + testingServerPort + "/ui?p=" + sharedSpaceId, - username, - Secret.fromString(password), - ""); - ConfigurationService.configurePlugin(model); - - ServerConfiguration serverConfiguration = ConfigurationService.getServerConfiguration(); - assertNotNull(serverConfiguration); - assertEquals("http://127.0.0.1:" + testingServerPort, serverConfiguration.location); - assertEquals(sharedSpaceId, serverConfiguration.sharedSpace); - logger.info("EVENTS TEST: plugin configured with the following server configuration: " + serverConfiguration); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/identity/ServerIdentityTest.java b/src/test/java/com/hp/application/automation/tools/octane/identity/ServerIdentityTest.java deleted file mode 100644 index de864439a0..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/identity/ServerIdentityTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hp.application.automation.tools.octane.identity; - -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -public class ServerIdentityTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - @Test - public void testIdentity() throws Exception { - String identity = ConfigurationService.getModel().getIdentity(); - Assert.assertNotNull(identity); - Assert.assertFalse(identity.isEmpty()); - - String identity2 = ConfigurationService.getModel().getIdentity(); - Assert.assertEquals(identity2, identity); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/CopyResourceSCM.java b/src/test/java/com/hp/application/automation/tools/octane/tests/CopyResourceSCM.java deleted file mode 100644 index c38625bba3..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/CopyResourceSCM.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests;// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.scm.NullSCM; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; - -import java.io.File; -import java.io.IOException; - -public class CopyResourceSCM extends NullSCM { - - private String path; - private String targetPath; - - public CopyResourceSCM(String path) { - this(path, ""); - } - - public CopyResourceSCM(String path, String targetPath) { - this.path = path; - this.targetPath = targetPath; - } - - @Override - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { - if (workspace.exists()) { - listener.getLogger().println("Deleting existing workspace " + workspace.getRemote()); - workspace.deleteRecursive(); - } - Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:" + path + "/**"); - for (Resource resource : resources) { - if (resource.exists() && resource.isReadable()) { - String urlString = resource.getURL().toExternalForm(); - String targetName = urlString.substring(urlString.indexOf(path) + path.length()); - byte[] fileContent = IOUtils.toByteArray(resource.getInputStream()); - FileUtils.writeByteArrayToFile(new File(new File(workspace.getRemote(), targetPath), targetName), fileContent); - } - } - return true; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/ExtensionUtil.java b/src/test/java/com/hp/application/automation/tools/octane/tests/ExtensionUtil.java deleted file mode 100644 index 3c75084b01..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/ExtensionUtil.java +++ /dev/null @@ -1,16 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests; - -import hudson.ExtensionList; -import org.junit.Assert; -import org.jvnet.hudson.test.JenkinsRule; - -public class ExtensionUtil { - - public static E getInstance(JenkinsRule rule, Class clazz) { - ExtensionList items = rule.getInstance().getExtensionList(clazz); - Assert.assertEquals(1, items.size()); - return items.get(0); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/JUnitResultsTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/JUnitResultsTest.java deleted file mode 100644 index 96c07e206b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/JUnitResultsTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.ResultQueue; -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import hudson.matrix.*; -import hudson.maven.MavenModuleSet; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.*; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -public class JUnitResultsTest { - - private static Set helloWorld2Tests = new HashSet<>(); - - static { - helloWorld2Tests.add(TestUtils.testSignature("helloWorld2", "hello", "HelloWorld2Test", "testOnce", TestResultStatus.PASSED)); - helloWorld2Tests.add(TestUtils.testSignature("helloWorld2", "hello", "HelloWorld2Test", "testDoce", TestResultStatus.PASSED)); - } - - private static Set subFolderHelloWorldTests = new HashSet<>(); - - static { - subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testOne", TestResultStatus.PASSED)); - subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testTwo", TestResultStatus.FAILED)); - subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testThree", TestResultStatus.SKIPPED)); - } - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - private static String mavenName; - - private TestQueue queue; - - @BeforeClass - public static void prepareClass() throws Exception { - rule.jenkins.setNumExecutors(10); - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - mavenName = mavenInstallation.getName(); - } - - @Before - public void prepareTest() { - TestListener testListener = ExtensionUtil.getInstance(rule, TestListener.class); - queue = new TestQueue(); - testListener._setTestResultQueue(queue); - } - - @Test - public void testJUnitResults() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsPom() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s subFolder/settings.xml clean test", mavenName, "subFolder/helloWorld/pom.xml", null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot", "subFolder")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, subFolderHelloWorldTests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsTwoPoms() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, "helloWorld/pom.xml", null, "-Dmaven.test.failure.ignore=true")); - project.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, "helloWorld2/pom.xml", null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsLegacy() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); - project.runHeadless(); - - project.setMaven(mavenName); - project.setGoals("-s settings.xml clean test -Dmaven.test.failure.ignore=true"); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsLegacyWithoutJUnitArchiver() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); - project.runHeadless(); - - project.setMaven(mavenName); - project.setGoals("-s settings.xml clean test -Dmaven.test.failure.ignore=true"); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsLegacySubfolder() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); - project.runHeadless(); - - project.setMaven(mavenName); - project.setRootPOM("subFolder/helloWorld/pom.xml"); - project.setGoals("-s settings.xml clean test -Dmaven.test.failure.ignore=true"); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot", "subFolder")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, subFolderHelloWorldTests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsWorkspaceStripping() throws Exception { - Set uftTests = new HashSet<>(); - uftTests.add(TestUtils.testSignature("", "All-Tests", "", "subfolder" + File.separator + "CalculatorPlusNextGen", TestResultStatus.FAILED)); - - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.getPublishersList().add(new TestCustomJUnitArchiver("UFT_results.xml")); - project.setScm(new CopyResourceSCM("/UFT")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, uftTests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsFreeStyleModule() throws Exception { - // this scenario simulates FreeStyle project with maven executed via shell (by not using Maven builder directly) - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - Assert.assertEquals(Collections.singleton(projectName + "#1"), getQueuedItems()); - } - - @Test - public void testJUnitResultsMatrixProject() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MatrixProject matrixProject = rule.createProject(MatrixProject.class, projectName); - matrixProject.setAxes(new AxisList(new Axis("osType", "Linux", "Windows"))); - - matrixProject.getBuildersList().add(new Maven("-s settings.xml clean test -Dmaven.test.failure.ignore=true -X", mavenName)); - - matrixProject.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - matrixProject.setScm(new CopyResourceSCM("/helloWorldRoot")); - MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); - - for (MatrixRun run : build.getExactRuns()) { - matchTests(run, projectName, TestUtils.helloWorldTests, helloWorld2Tests); - } - Assert.assertEquals(new HashSet<>(Arrays.asList(projectName + "/osType=Windows#1", projectName + "/osType=Linux#1")), getQueuedItems()); - Assert.assertFalse(new File(build.getRootDir(), "mqmTests.xml").exists()); - } - - private Set getQueuedItems() { - Set ret = new HashSet<>(); - ResultQueue.QueueItem item; - while ((item = queue.peekFirst()) != null) { - ret.add(item.getProjectName() + "#" + item.getBuildNumber()); - queue.remove(); - } - return ret; - } - - private void matchTests(AbstractBuild build, String projectName, Set... expectedTests) throws FileNotFoundException { - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - TestUtils.matchTests(new TestResultIterable(mqmTestsXml), projectName, build.getStartTimeInMillis(), expectedTests); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestApiTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestApiTest.java deleted file mode 100644 index 985678f39e..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestApiTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.hp.application.automation.tools.octane.client.TestEventPublisher; -import com.hp.mqm.client.LogOutput; -import com.hp.mqm.client.MqmRestClient; -import com.hp.application.automation.tools.octane.actions.BuildActions; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.RetryModel; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.util.Secret; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.xml.sax.SAXException; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringReader; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2698"}) -public class TestApiTest { - - private static JenkinsMqmRestClientFactory clientFactory; - private static MqmRestClient restClient; - private static TestQueue queue; - private static TestDispatcher testDispatcher; - private static AbstractBuild build; - private static JenkinsRule.WebClient client; - - @ClassRule - final public static JenkinsRule rule = new JenkinsRule(); - - @BeforeClass - public static void init() throws Exception { - restClient = Mockito.mock(MqmRestClient.class); - Mockito.when(restClient.postTestResult(Mockito.any(), Mockito.eq(false))).thenReturn(10001l); - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocationOnMock) throws Throwable { - LogOutput logOutput = (LogOutput) invocationOnMock.getArguments()[1]; - logOutput.setContentType("text/plain"); - OutputStream os = logOutput.getOutputStream(); - os.write("This is the log".getBytes("UTF-8")); - os.flush(); - return null; - } - }).when(restClient).getTestResultLog(Mockito.eq(10001l), Mockito.any()); - - clientFactory = Mockito.mock(JenkinsMqmRestClientFactory.class); - Mockito.when(clientFactory.obtain(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(restClient); - - BuildActions buildActions = ExtensionUtil.getInstance(rule, BuildActions.class); - buildActions._setMqmRestClientFactory(clientFactory); - - testDispatcher = ExtensionUtil.getInstance(rule, TestDispatcher.class); - testDispatcher._setMqmRestClientFactory(clientFactory); - queue = new TestQueue(); - testDispatcher._setTestResultQueue(queue); - TestListener testListener = ExtensionUtil.getInstance(rule, TestListener.class); - testListener._setTestResultQueue(queue); - queue.waitForTicks(1); // needed to avoid occasional interaction with the client we just overrode (race condition) - - TestEventPublisher testEventPublisher = new TestEventPublisher(); - RetryModel retryModel = new RetryModel(testEventPublisher); - testDispatcher._setRetryModel(retryModel); - testDispatcher._setEventPublisher(testEventPublisher); - Mockito.when(restClient.isTestResultRelevant(Mockito.anyString(), Mockito.anyString())).thenReturn(true); - - // server needs to be configured in order for the processing to happen - client = rule.createWebClient(); - HtmlPage configPage = client.goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8008/ui/?p=1001/1002"); - form.getInputByName("_.username").setValueAttribute("username"); - form.getInputByName("_.password").setValueAttribute("password"); - rule.submit(form); - - FreeStyleProject project = rule.createFreeStyleProject("test-api-test"); - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - project.getBuildersList().add(new Maven("-s settings.xml test", mavenInstallation.getName(), "helloWorld/pom.xml", null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - build = TestUtils.runAndCheckBuild(project); - - // make sure dispatcher logic was executed - queue.waitForTicks(3); - } - - @Test - public void testXml() throws Exception { - Page testResults = client.goTo("job/test-api-test/" + build.getNumber() + "/nga/tests/xml", "application/xml"); - TestUtils.matchTests(new TestResultIterable(new StringReader(testResults.getWebResponse().getContentAsString())), "test-api-test", build.getStartTimeInMillis(), TestUtils.helloWorldTests); - } - - @Test - public void testAudit() throws Exception { - Page auditLog = client.goTo("job/test-api-test/" + build.getNumber() + "/nga/tests/audit", "application/json"); - JSONArray audits = JSONArray.fromObject(auditLog.getWebResponse().getContentAsString()); - Assert.assertEquals(1, audits.size()); - JSONObject audit = audits.getJSONObject(0); - Assert.assertEquals(10001l, audit.getLong("id")); - Assert.assertTrue(audit.getBoolean("pushed")); - Assert.assertEquals("http://localhost:8008", audit.getString("location")); - Assert.assertEquals("1001", audit.getString("sharedSpace")); - Assert.assertNotNull(audit.getString("date")); - } - - @Test - public void testLog() throws InterruptedException, IOException, SAXException { - Page publishLog = client.goTo("job/test-api-test/" + build.getNumber() + "/nga/tests/log", "text/plain"); - Assert.assertEquals("This is the log", publishLog.getWebResponse().getContentAsString()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java deleted file mode 100644 index 04c9ff2541..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Recorder; -import hudson.tasks.test.AbstractTestResultAction; -import org.apache.commons.io.IOUtils; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -public class TestCustomJUnitArchiver extends Recorder { - - private String resultFile; - - public TestCustomJUnitArchiver(String resultFile) { - this.resultFile = resultFile; - } - - @Override - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - build.addAction(new TestResultAction()); - InputStream is = build.getWorkspace().child(resultFile).read(); - String junitResults = IOUtils.toString(is, "UTF-8"); - junitResults = junitResults - .replaceAll("%%%WORKSPACE%%%", build.getWorkspace().getRemote()) - .replaceAll("%%%SEPARATOR%%%", File.separator.equals("\\") ? "\\\\" : File.separator); - IOUtils.closeQuietly(is); - new FilePath(build.getRootDir()).child("junitResult.xml").write(junitResults, "UTF-8"); - return true; - } - - private static class TestResultAction extends AbstractTestResultAction { - - @Override - public int getFailCount() { - return 0; - } - - @Override - public int getTotalCount() { - return 0; - } - - @Override - public Object getResult() { - return new Object(); - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestDispatcherTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestDispatcherTest.java deleted file mode 100644 index 1c9f33b960..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestDispatcherTest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.hp.application.automation.tools.octane.client.TestEventPublisher; -import com.hp.mqm.client.MqmRestClient; -import com.hp.mqm.client.exception.*; -import com.hp.application.automation.tools.octane.client.JenkinsMqmRestClientFactory; -import com.hp.application.automation.tools.octane.client.RetryModel; -import com.hp.application.automation.tools.octane.configuration.ConfigurationService; -import hudson.FilePath; -import hudson.matrix.*; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.util.Secret; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.io.IOUtils; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; -import org.mockito.InOrder; -import org.mockito.Mockito; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2698"}) -public class TestDispatcherTest { - - private TestQueue queue; - private TestDispatcher testDispatcher; - private JenkinsMqmRestClientFactory clientFactory; - private MqmRestClient restClient; - private TestEventPublisher testEventPublisher; - - @Rule - final public JenkinsRule rule = new JenkinsRule(); - - private FreeStyleProject project; - - @BeforeClass - public static void initClass() { - System.setProperty("MQM.TestDispatcher.Period", "1000"); - } - - @Before - public void init() throws Exception { - restClient = Mockito.mock(MqmRestClient.class); - clientFactory = Mockito.mock(JenkinsMqmRestClientFactory.class); - Mockito.when(clientFactory.obtain(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(restClient); - testDispatcher = ExtensionUtil.getInstance(rule, TestDispatcher.class); - testDispatcher._setMqmRestClientFactory(clientFactory); - queue = new TestQueue(); - testDispatcher._setTestResultQueue(queue); - queue.waitForTicks(1); // needed to avoid occasional interaction with the client we just overrode (race condition) - - testEventPublisher = new TestEventPublisher(); - RetryModel retryModel = new RetryModel(testEventPublisher); - testDispatcher._setRetryModel(retryModel); - testDispatcher._setEventPublisher(testEventPublisher); - - project = rule.createFreeStyleProject("TestDispatcher"); - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - - project.getBuildersList().add(new Maven("-s settings.xml install", mavenInstallation.getName(), null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - - // server needs to be configured in order for the processing to happen - HtmlPage configPage = rule.createWebClient().goTo("configure"); - HtmlForm form = configPage.getFormByName("config"); - form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8008/ui/?p=1001/1002"); - form.getInputByName("_.username").setValueAttribute("username"); - form.getInputByName("_.password").setValueAttribute("password"); - rule.submit(form); - } - - @Test - public void testDispatcher() throws Exception { - mockRestClient(restClient, true); - FreeStyleBuild build = executeBuild(); - queue.waitForTicks(5); - verifyRestClient(restClient, build, true); - verifyAudit(build, true); - - mockRestClient(restClient, true); - FreeStyleBuild build2 = executeBuild(); - queue.waitForTicks(5); - verifyRestClient(restClient, build2, true); - verifyAudit(build2, true); - Assert.assertEquals(0, queue.size()); - } - - @Test - public void testDispatcherBatch() throws Exception { - mockRestClient(restClient, true); - FreeStyleBuild build = project.scheduleBuild2(0).get(); - FreeStyleBuild build2 = project.scheduleBuild2(0).get(); - FreeStyleBuild build3 = project.scheduleBuild2(0).get(); - queue.add(Arrays.asList(build, build2, build3)); - queue.waitForTicks(10); - - Mockito.verify(restClient).validateConfigurationWithoutLogin(); - Mockito.verify(restClient, Mockito.atMost(3)).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - Mockito.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - Mockito.verify(restClient).postTestResult(new File(build2.getRootDir(), "mqmTests.xml"), false); - Mockito.verify(restClient).postTestResult(new File(build3.getRootDir(), "mqmTests.xml"), false); - Mockito.verifyNoMoreInteractions(restClient); - Assert.assertEquals(0, queue.size()); - - verifyAudit(build, true); - verifyAudit(build2, true); - verifyAudit(build3, true); - } - - @Test - public void testDispatcherSharedSpaceFailure() throws Exception { - mockRestClient(restClient, false); - FreeStyleBuild build = executeBuild(); - queue.waitForTicks(5); - - verifyRestClient(restClient, build, false); - verifyAudit(build); - Mockito.reset(restClient); - - executeBuild(); - queue.waitForTicks(5); - - // in quiet period - Mockito.verifyNoMoreInteractions(restClient); - Assert.assertEquals(2, queue.size()); - } - - @Test - public void testDispatcherBodyFailure() throws Exception { - // body post fails for the first time, succeeds afterwards - - Mockito.doNothing().when(restClient).validateConfigurationWithoutLogin(); - Mockito.when(restClient.isTestResultRelevant(Mockito.anyString(), Mockito.anyString())).thenReturn(true); - Mockito.doThrow(new RequestErrorException("fails")).doReturn(1L).when(restClient).postTestResult(Mockito.argThat(new MqmTestsFileMatcher()), Mockito.eq(false)); - InOrder order = Mockito.inOrder(restClient); - - FreeStyleBuild build = executeBuild(); - queue.waitForTicks(5); - - order.verify(restClient).validateConfigurationWithoutLogin(); - order.verify(restClient).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - order.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - - Mockito.verify(restClient, Mockito.times(2)).validateConfigurationWithoutLogin(); - Mockito.verify(restClient, Mockito.times(2)).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - Mockito.verify(restClient, Mockito.times(2)).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - Mockito.verifyNoMoreInteractions(restClient); - verifyAudit(build, false, true); - - Assert.assertEquals(0, queue.size()); - Assert.assertEquals(0, queue.getDiscards()); - - // body post fails for two consecutive times - - Mockito.reset(restClient); - Mockito.doNothing().when(restClient).validateConfigurationWithoutLogin(); - Mockito.when(restClient.isTestResultRelevant(Mockito.anyString(), Mockito.anyString())).thenReturn(true); - Mockito.doThrow(new RequestErrorException("fails")).doThrow(new RequestErrorException("fails")).when(restClient).postTestResult(Mockito.argThat(new MqmTestsFileMatcher()), Mockito.eq(false)); - - order = Mockito.inOrder(restClient); - - build = executeBuild(); - queue.waitForTicks(5); - - order.verify(restClient).validateConfigurationWithoutLogin(); - order.verify(restClient).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - order.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - order.verify(restClient).validateConfigurationWithoutLogin(); - order.verify(restClient).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - order.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - - Mockito.verify(restClient, Mockito.times(2)).validateConfigurationWithoutLogin(); - Mockito.verify(restClient, Mockito.times(2)).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - Mockito.verify(restClient, Mockito.times(2)).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - Mockito.verifyNoMoreInteractions(restClient); - verifyAudit(build, false, false); - - Assert.assertEquals(0, queue.size()); - Assert.assertEquals(1, queue.getDiscards()); - } - - @Test - public void testDispatcherSuspended() throws Exception { - testEventPublisher.setSuspended(true); - - executeBuild(); - - queue.waitForTicks(2); - - // events suspended - Mockito.verifyNoMoreInteractions(restClient); - Assert.assertEquals(1, queue.size()); - } - - @Ignore - @Test - public void testDispatchMatrixBuild() throws Exception { - MatrixProject matrixProject = rule.createProject(MatrixProject.class, "TestDispatcherMatrix"); - matrixProject.setAxes(new AxisList(new Axis("OS", "Linux", "Windows"))); - - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - - matrixProject.getBuildersList().add(new Maven("-s settings.xml install", mavenInstallation.getName(), null, null, "-Dmaven.test.failure.ignore=true")); - matrixProject.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - matrixProject.setScm(new CopyResourceSCM("/helloWorldRoot")); - - mockRestClient(restClient, true); - MatrixBuild matrixBuild = matrixProject.scheduleBuild2(0).get(); - for (MatrixRun run : matrixBuild.getExactRuns()) { - queue.add("TestDispatcherMatrix/" + run.getParent().getName(), run.getNumber()); - } - queue.waitForTicks(5); - Mockito.verify(restClient).validateConfigurationWithoutLogin(); - for (MatrixRun run : matrixBuild.getExactRuns()) { - Mockito.verify(restClient, Mockito.atLeast(2)).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), run.getProject().getParent().getName()); - Mockito.verify(restClient).postTestResult(new File(run.getRootDir(), "mqmTests.xml"), false); - verifyAudit(run, true); - } - Mockito.verifyNoMoreInteractions(restClient); - - Assert.assertEquals(0, queue.size()); - } - - @Test - public void testDispatcherTemporarilyUnavailable() throws Exception { - Mockito.reset(restClient); - Mockito.doReturn(1L) - .doThrow(new TemporarilyUnavailableException("Server busy")) - .doThrow(new TemporarilyUnavailableException("Server busy")) - .doThrow(new TemporarilyUnavailableException("Server busy")) - .doThrow(new TemporarilyUnavailableException("Server busy")) - .doThrow(new TemporarilyUnavailableException("Server busy")) - .doReturn(1L) - .when(restClient).postTestResult(Mockito.argThat(new MqmTestsFileMatcher()), Mockito.eq(false)); - Mockito.when(restClient.isTestResultRelevant(Mockito.anyString(), Mockito.anyString())).thenReturn(true); - FreeStyleBuild build = executeBuild(); - FreeStyleBuild build2 = executeBuild(); - queue.waitForTicks(12); - Mockito.verify(restClient, Mockito.atMost(7)).validateConfigurationWithoutLogin(); - Mockito.verify(restClient, Mockito.times(7)).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - Mockito.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - Mockito.verify(restClient, Mockito.times(6)).postTestResult(new File(build2.getRootDir(), "mqmTests.xml"), false); - Mockito.verifyNoMoreInteractions(restClient); - verifyAudit(build, true); - verifyAudit(true, build2, false, false, false, false, false, true); - Assert.assertEquals(0, queue.size()); - } - - private FreeStyleBuild executeBuild() throws ExecutionException, InterruptedException { - FreeStyleBuild build = project.scheduleBuild2(0).get(); - queue.add(build.getProject().getName(), build.getNumber()); - return build; - } - - private void verifyAudit(AbstractBuild build, boolean... statuses) throws IOException, InterruptedException { - verifyAudit(false, build, statuses); - } - - private void verifyAudit(boolean unavailableIfFailed, AbstractBuild build, boolean... statuses) throws IOException, InterruptedException { - FilePath auditFile = new FilePath(new File(build.getRootDir(), TestDispatcher.TEST_AUDIT_FILE)); - JSONArray audits; - if (statuses.length > 0) { - Assert.assertTrue(auditFile.exists()); - InputStream is = auditFile.read(); - audits = JSONArray.fromObject(IOUtils.toString(is, "UTF-8")); - IOUtils.closeQuietly(is); - } else { - Assert.assertFalse(auditFile.exists()); - audits = new JSONArray(); - } - Assert.assertEquals(statuses.length, audits.size()); - for (int i = 0; i < statuses.length; i++) { - JSONObject audit = audits.getJSONObject(i); - Assert.assertEquals("http://localhost:8008", audit.getString("location")); - Assert.assertEquals("1001", audit.getString("sharedSpace")); - Assert.assertEquals(statuses[i], audit.getBoolean("pushed")); - if (statuses[i]) { - Assert.assertEquals(1L, audit.getLong("id")); - } - if (!statuses[i] && unavailableIfFailed) { - Assert.assertTrue(audit.getBoolean("temporarilyUnavailable")); - } else { - Assert.assertFalse(audit.containsKey("temporarilyUnavailable")); - } - Assert.assertNotNull(audit.getString("date")); - } - } - - private void mockRestClient(MqmRestClient restClient, boolean sharedSpace) throws IOException { - Mockito.reset(restClient); - Mockito.when(restClient.isTestResultRelevant(Mockito.anyString(), Mockito.anyString())).thenReturn(true); - if (!sharedSpace) { - Mockito.doThrow(new SharedSpaceNotExistException()).when(restClient).validateConfigurationWithoutLogin(); - } else { - Mockito.doReturn(1L).when(restClient).postTestResult(Mockito.argThat(new MqmTestsFileMatcher()), Mockito.eq(false)); - } - } - - private void verifyRestClient(MqmRestClient restClient, AbstractBuild build, boolean body) throws IOException { - Mockito.verify(restClient).validateConfigurationWithoutLogin(); - - if (body) { - Mockito.verify(restClient).isTestResultRelevant(ConfigurationService.getModel().getIdentity(), build.getProject().getName()); - Mockito.verify(restClient).postTestResult(new File(build.getRootDir(), "mqmTests.xml"), false); - } - - Mockito.verifyNoMoreInteractions(restClient); - } - - private static class MqmTestsFileMatcher extends BaseMatcher { - @Override - public boolean matches(Object o) { - return o instanceof File && ((File) o).getName().endsWith("mqmTests.xml"); - } - - @Override - public void describeTo(Description description) { - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestJenkinsDurationTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestJenkinsDurationTest.java deleted file mode 100644 index f19023dbda..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestJenkinsDurationTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -import static org.junit.Assert.assertEquals; - -/** - * Created by berkovir on 06/02/2017. - */ -@SuppressWarnings({"squid:S2698","squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925"}) -public class TestJenkinsDurationTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - - @Test - public void testDuration() throws Exception { - - FreeStyleProject p = rule.createFreeStyleProject("test-duration"); - - assertEquals(0, p.getBuilds().toArray().length); - long start = System.currentTimeMillis(); - p.scheduleBuild2(0); - - while (p.getLastBuild() == null || p.getLastBuild().isBuilding()) { - Thread.sleep(100); - } - - long end = System.currentTimeMillis(); - FreeStyleBuild run1 = p.getBuilds().getLastBuild(); - - long buildDurationWithoutPostProcessTime = run1.getDuration(); - long buildDurationTotal = (end - start); - long pluginPostProcessWorkTime = buildDurationTotal - buildDurationWithoutPostProcessTime; - - - long buildDurationTotalExpected = 1750; - long pluginPostProcessWorkTimeExpected = 140; - - System.out.println(String.format("buildDurationTotal=%d, expected=%d", buildDurationTotal, buildDurationTotalExpected)); - System.out.println(String.format("pluginPostProcessWorkTime=%d, expected=%d", pluginPostProcessWorkTime, pluginPostProcessWorkTimeExpected)); - Assert.assertTrue(buildDurationTotal < buildDurationTotalExpected); - Assert.assertTrue(pluginPostProcessWorkTime < pluginPostProcessWorkTimeExpected); - - int t; - - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestQueue.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestQueue.java deleted file mode 100644 index c78c67530a..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestQueue.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.ResultQueue; -import hudson.model.AbstractBuild; -import org.junit.Assert; - -import java.util.Collection; -import java.util.LinkedList; - -@SuppressWarnings("squid:S2925") -public class TestQueue implements ResultQueue { - - private LinkedList queue = new LinkedList(); - private int discard; - - @Override - public synchronized QueueItem peekFirst() { - ++ticks; - if (!queue.isEmpty()) { - return queue.getFirst(); - } else { - return null; - } - } - - @Override - public synchronized boolean failed() { - QueueItem item = queue.removeFirst(); - if (item.incrementFailCount() < 1) { - queue.add(item); - return true; - } else { - ++discard; - return false; - } - } - - @Override - public synchronized void remove() { - queue.removeFirst(); - } - - @Override - public synchronized void add(String projectName, int buildNumber) { - queue.add(new QueueItem(projectName, buildNumber)); - } - - @Override - public void add(String projectName, int buildNumber, String workspace) { - queue.add(new QueueItem(projectName, buildNumber, workspace)); - } - - public synchronized void add(Collection builds) { - for (AbstractBuild build : builds) { - queue.add(new QueueItem(build.getProject().getName(), build.getNumber())); - } - } - - public synchronized int size() { - return queue.size(); - } - - public synchronized int getDiscards() { - return discard; - } - - // test usage only; [YG] - TODO: remove this code from here ASAP - private long ticks; - public void waitForTicks(int n) throws InterruptedException { - long current = ticks; - long target = current + n; - for (int i = 0; i < 2000; i++) { - current = ticks; - if (current >= target) { - return; - } - Thread.sleep(10); - } - Assert.fail("Timed out: ticks: expected=" + target + "; actual=" + current); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterable.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterable.java deleted file mode 100644 index 247a33e7af..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterable.java +++ /dev/null @@ -1,35 +0,0 @@ -// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.tests.junit.JUnitTestResult; - -import javax.xml.stream.XMLStreamException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.Reader; - -public class TestResultIterable implements Iterable { - - private Reader reader; - - public TestResultIterable(File file) throws FileNotFoundException { - this.reader = new FileReader(file); - } - - public TestResultIterable(Reader reader) { - this.reader = reader; - } - - @Override - public TestResultIterator iterator() { - try { - return new TestResultIterator(reader); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterator.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterator.java deleted file mode 100644 index ca9f658155..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultIterator.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.tests.junit.JUnitTestResult; -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import org.apache.commons.io.IOUtils; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.Attribute; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; -import java.io.FileNotFoundException; -import java.io.Reader; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.NoSuchElementException; - -public class TestResultIterator implements Iterator { - - private Reader input; - private XMLEventReader reader; - private LinkedList items = new LinkedList(); - private boolean closed; - private String serverId; - private String jobId; - private String buildId; - private String subType; - - public TestResultIterator(Reader input) throws FileNotFoundException, XMLStreamException { - this.input = input; - reader = XMLInputFactory.newInstance().createXMLEventReader(input); - } - - @Override - public boolean hasNext() { - try { - while (items.isEmpty() && !closed) { - if (reader.hasNext()) { - XMLEvent event = reader.nextEvent(); - if (event instanceof StartElement) { - StartElement element = (StartElement) event; - String localName = element.getName().getLocalPart(); - if ("test_run".equals(localName)) { - String moduleName = element.getAttributeByName(new QName("module")).getValue(); - String packageName = element.getAttributeByName(new QName("package")).getValue(); - String className = element.getAttributeByName(new QName("class")).getValue(); - String testName = element.getAttributeByName(new QName("name")).getValue(); - long duration = Long.valueOf(element.getAttributeByName(new QName("duration")).getValue()); - TestResultStatus status = TestResultStatus.fromPrettyName(element.getAttributeByName(new QName("status")).getValue()); - long started = Long.valueOf(element.getAttributeByName(new QName("started")).getValue()); - items.add(new JUnitTestResult(moduleName, packageName, className, testName, status, duration, started, null, null)); - } else if ("build".equals(localName)) { - serverId = element.getAttributeByName(new QName("server_id")).getValue(); - jobId = element.getAttributeByName(new QName("job_id")).getValue(); - buildId = element.getAttributeByName(new QName("build_id")).getValue(); - Attribute subType = element.getAttributeByName(new QName("sub_type")); - if (subType != null) { - this.subType = subType.getValue(); - } - } - } - } else { - closed = true; - IOUtils.closeQuietly(input); - reader.close(); - } - } - return !items.isEmpty(); - } catch (XMLStreamException e) { - throw new RuntimeException(e); - } - } - - @Override - public JUnitTestResult next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - return items.removeFirst(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - public String getServerId() { - hasNext(); - return serverId; - } - - public String getJobId() { - hasNext(); - return jobId; - } - - public String getBuildId() { - hasNext(); - return buildId; - } - - public String getSubType() { - hasNext(); - return subType; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultQueueTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultQueueTest.java deleted file mode 100644 index 8bddc04d2a..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestResultQueueTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.ResultQueue; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; - -@SuppressWarnings("squid:S2699") -public class TestResultQueueTest { - - private TestAbstractResultQueue queue; - - @Before - public void init() throws IOException { - File file = File.createTempFile("TestResultQueueTest", ""); - file.delete(); - queue = new TestAbstractResultQueue(file); - } - - @Test - public void testQueue() { - queue.add("foo", 1); - ResultQueue.QueueItem item = queue.peekFirst(); - Assert.assertEquals("foo", item.getProjectName()); - Assert.assertEquals(1, item.getBuildNumber()); - Assert.assertEquals(0, item.getFailCount()); - } - - @Test - public void testAddRemove() { - Assert.assertNull(queue.peekFirst()); - queue.add("foo", 1); - Assert.assertNotNull(queue.peekFirst()); - Assert.assertEquals(queue.peekFirst(), queue.peekFirst()); - queue.remove(); - Assert.assertNull(queue.peekFirst()); - } - - @Test - public void testRetry() { - Assert.assertNull(queue.peekFirst()); - queue.add("foo", 1); - Assert.assertEquals(0, queue.peekFirst().getFailCount()); - Assert.assertTrue(queue.failed()); - Assert.assertEquals("foo", queue.peekFirst().getProjectName()); - Assert.assertEquals(1, queue.peekFirst().getBuildNumber()); - Assert.assertEquals(1, queue.peekFirst().getFailCount()); - Assert.assertTrue(queue.failed()); - Assert.assertEquals("foo", queue.peekFirst().getProjectName()); - Assert.assertEquals(1, queue.peekFirst().getBuildNumber()); - Assert.assertEquals(2, queue.peekFirst().getFailCount()); - Assert.assertTrue(queue.failed()); - Assert.assertEquals("foo", queue.peekFirst().getProjectName()); - Assert.assertEquals(1, queue.peekFirst().getBuildNumber()); - Assert.assertEquals(3, queue.peekFirst().getFailCount()); - Assert.assertFalse(queue.failed()); - Assert.assertNull(queue.peekFirst()); - } - - @Test - public void testInvalidRemove() { - Assert.assertNull(queue.peekFirst()); - queue.add("foo", 1); - try { - queue.remove(); - Assert.fail("should have failed"); - } catch (IllegalStateException e) { - // expected - } - } - - @Test - public void testInvalidFailed() { - Assert.assertNull(queue.peekFirst()); - queue.add("foo", 1); - try { - queue.failed(); - Assert.fail("should have failed"); - } catch (IllegalStateException e) { - // expected - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/TestUtils.java b/src/test/java/com/hp/application/automation/tools/octane/tests/TestUtils.java deleted file mode 100644 index 42181c601b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/TestUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests; - -import com.hp.application.automation.tools.octane.tests.junit.JUnitTestResult; -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.Result; -import org.junit.Assert; - -import java.util.HashSet; -import java.util.Set; - -public class TestUtils { - - static Set helloWorldTests = new HashSet<>(); - - static { - helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testOne", TestResultStatus.PASSED)); - helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testTwo", TestResultStatus.FAILED)); - helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testThree", TestResultStatus.SKIPPED)); - } - - public static AbstractBuild runAndCheckBuild(AbstractProject project) throws Exception { - AbstractBuild build = (AbstractBuild) project.scheduleBuild2(0).get(); - if (!build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { // avoid expensive build.getLog() until condition is met - Assert.fail("Build status: " + build.getResult() + ", log follows:\n" + build.getLog()); - } - return build; - } - - private static String testSignature(JUnitTestResult testResult) { - return testSignature(testResult.getModuleName(), testResult.getPackageName(), testResult.getClassName(), - testResult.getTestName(), testResult.getResult()); - } - - static String testSignature(String moduleName, String packageName, String className, String testName, TestResultStatus status) { - return moduleName + "#" + packageName + "#" + className + "#" + testName + "#" + status.toPrettyName() + "#"; - } - - static void matchTests(TestResultIterable testResultIterable, String buildType, long started, Set... expectedTests) { - Set copy = new HashSet<>(); - for (Set expected : expectedTests) { - copy.addAll(expected); - } - TestResultIterator it = testResultIterable.iterator(); - Assert.assertEquals(buildType, it.getJobId()); - while (it.hasNext()) { - JUnitTestResult testResult = it.next(); - String testSignature = TestUtils.testSignature(testResult); - Assert.assertTrue("Not found: " + testSignature + " in " + copy, copy.remove(testSignature)); - Assert.assertEquals("Start time differs", started, testResult.getStarted()); - } - Assert.assertTrue("More tests expected: " + copy.toString(), copy.isEmpty()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java deleted file mode 100644 index be7d2067b6..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.build; - -import com.hp.application.automation.tools.octane.tests.CopyResourceSCM; -import com.hp.application.automation.tools.octane.tests.TestUtils; -import hudson.matrix.*; -import hudson.maven.MavenModuleSet; -import hudson.maven.MavenModuleSetBuild; -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; - -import java.util.HashMap; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701"}) -public class BuildHandlerUtilsTest { - - @ClassRule - public static final JenkinsRule jenkins = new JenkinsRule(); - - @Test - public void testMatrixBuildType() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class, "matrix-project"); - matrixProject.setAxes(new AxisList(new Axis("OS", "Linux", "Windows"))); - MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); - - BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); - Assert.assertEquals("matrix-project", descriptor.getJobId()); - Assert.assertEquals("", descriptor.getSubType()); - - Assert.assertEquals("matrix-project", BuildHandlerUtils.getProjectFullName(build)); - - HashMap expectedType = new HashMap<>(); - expectedType.put("OS=Linux", "matrix-project/OS=Linux"); - expectedType.put("OS=Windows", "matrix-project/OS=Windows"); - - for (MatrixRun run : build.getExactRuns()) { - descriptor = BuildHandlerUtils.getBuildType(run); - Assert.assertEquals("matrix-project", descriptor.getJobId()); - String fullName = expectedType.remove(descriptor.getSubType()); - Assert.assertEquals(fullName, BuildHandlerUtils.getProjectFullName(run)); - } - Assert.assertTrue(expectedType.isEmpty()); - } - - @Test - public void testMavenBuildType() throws Exception { - MavenModuleSet project = jenkins.createProject(MavenModuleSet.class, "maven-project"); - project.runHeadless(); - - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - project.setMaven(mavenInstallation.getName()); - project.setGoals("-s settings.xml test -Dmaven.test.failure.ignore=true"); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(project); - - BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); - Assert.assertEquals("maven-project", descriptor.getJobId()); - Assert.assertEquals("", descriptor.getSubType()); - - Assert.assertEquals("maven-project", BuildHandlerUtils.getProjectFullName(build)); - } - - @Test - public void testFallbackBuildType() throws Exception { - FreeStyleProject project = jenkins.createFreeStyleProject("freestyle-project"); - FreeStyleBuild build = (FreeStyleBuild) TestUtils.runAndCheckBuild(project); - BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); - Assert.assertEquals("freestyle-project", descriptor.getJobId()); - Assert.assertEquals("", descriptor.getSubType()); - Assert.assertEquals("freestyle-project", BuildHandlerUtils.getProjectFullName(build)); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java deleted file mode 100644 index 20c49e2536..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import com.hp.application.automation.tools.octane.tests.CopyResourceSCM; -import com.hp.application.automation.tools.octane.tests.ExtensionUtil; -import com.hp.application.automation.tools.octane.tests.TestUtils; -import com.hp.application.automation.tools.octane.tests.junit.JUnitExtension; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; -import org.mockito.Mockito; - -import java.io.File; -import java.io.FileReader; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ResultFieldsDetectionTest { - - @Rule - public final JenkinsRule rule = new JenkinsRule(); - - private static FreeStyleProject project; - - private static ResultFieldsDetectionService detectionService; - - @Before - public void setUp() throws Exception { - project = rule.createFreeStyleProject("junit - job"); - JUnitExtension junitExtension = ExtensionUtil.getInstance(rule, JUnitExtension.class); - detectionService = Mockito.mock(ResultFieldsDetectionService.class); - junitExtension._setResultFieldsDetectionService(detectionService); - - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - - project.getBuildersList().add(new Maven("-s settings.xml -U test", mavenInstallation.getName(), null, null, "-Dmaven.test.failure.ignore=true")); - project.setScm(new CopyResourceSCM("/helloWorldRoot")); - } - - @Test - public void testDetectionNotRun() throws Exception { - //there is no test publisher set up in this project, detection will not run - AbstractBuild build = TestUtils.runAndCheckBuild(project); - verify(detectionService, Mockito.never()).getDetectedFields(build); - } - - @Test - public void testDetectionRunOnce() throws Exception { - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - verify(detectionService, Mockito.times(1)).getDetectedFields(build); - } - - @Test - public void testDetectedFieldsInXml() throws Exception { - when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(new ResultFields("HOLA", "CIAO", "SALUT")); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - ResultFields resultFields = xmlReader.readXml().getResultFields(); - - Assert.assertNotNull(resultFields); - Assert.assertEquals("HOLA", resultFields.getFramework()); - Assert.assertEquals("CIAO", resultFields.getTestingTool()); - Assert.assertEquals("SALUT", resultFields.getTestLevel()); - } - - @Test - public void testNoDetectedFieldsInXml() throws Exception { - when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(null); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - ResultFields resultFields = xmlReader.readXml().getResultFields(); - ; - - Assert.assertNull(resultFields.getFramework()); - Assert.assertNull(resultFields.getTestingTool()); - Assert.assertNull(resultFields.getTestLevel()); - } - - @Test - public void testEmptyDetectedFieldsInXml() throws Exception { - when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(new ResultFields(null, null, null)); - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - ResultFields resultFields = xmlReader.readXml().getResultFields(); - ; - - Assert.assertNull(resultFields.getFramework()); - Assert.assertNull(resultFields.getTestingTool()); - Assert.assertNull(resultFields.getTestLevel()); - } - - /** - * We do not detect Junit yet. - */ - @Test - public void testNotDetectableConfigurationInXml() throws Exception { - project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - ResultFields resultFields = xmlReader.readXml().getResultFields(); - - Assert.assertNull(resultFields.getFramework()); - Assert.assertNull(resultFields.getTestingTool()); - Assert.assertNull(resultFields.getTestLevel()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsTest.java deleted file mode 100644 index 8b970a03e2..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import org.junit.Assert; -import org.junit.Test; - -public class ResultFieldsTest { - - @Test - public void testEquals() { - ResultFields x = new ResultFields("foo", "bar", null); - Assert.assertTrue(x.equals(x)); - Assert.assertTrue(!x.equals(null)); - - ResultFields y = new ResultFields("foo", "bar", null); - Assert.assertTrue(x.equals(y) && y.equals(x)); - Assert.assertTrue(x.hashCode() == y.hashCode()); - - ResultFields z = new ResultFields("foo", "bar", ""); - Assert.assertTrue(!x.equals(z) && !z.equals(x)); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java b/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java deleted file mode 100644 index f8d980cde6..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; -import java.io.Reader; -import java.util.LinkedList; -import java.util.List; - -public class ResultFieldsXmlReader { - - private Reader input; - private XMLEventReader eventReader; - private ResultFields resultFields; - private List testAttributes; - - public ResultFieldsXmlReader(Reader input) throws XMLStreamException { - this.input = input; - eventReader = XMLInputFactory.newInstance().createXMLEventReader(input); - resultFields = new ResultFields(); - testAttributes = new LinkedList(); - } - - public TestResultContainer readXml() { - boolean fieldsElement = false; - try { - while (eventReader.hasNext()) { - XMLEvent event = eventReader.nextEvent(); - if (event instanceof StartElement) { - StartElement element = (StartElement) event; - String localName = element.getName().getLocalPart(); - if ("test_fields".equals(localName)) { - fieldsElement = true; - } - if ("test_field".equals(localName)) { - if (!fieldsElement) { - Assert.fail(" element found, but surrounding element '' is missing in the XML file"); - } - String type = element.getAttributeByName(new QName("type")).getValue(); - String value = element.getAttributeByName(new QName("value")).getValue(); - if (type.equals("Framework")) { - resultFields.setFramework(value); - } else if (type.equals("Testing_Tool_Type")) { - resultFields.setTestingTool(value); - } else if (type.equals("Test_Level")) { - resultFields.setTestLevel(value); - } - } - if ("test_run".equals(localName)) { - String moduleName = element.getAttributeByName(new QName("module")).getValue(); - String packageName = element.getAttributeByName(new QName("package")).getValue(); - String className = element.getAttributeByName(new QName("class")).getValue(); - String testName = element.getAttributeByName(new QName("name")).getValue(); - testAttributes.add(new TestAttributes(moduleName, packageName, className, testName)); - } - } - } - IOUtils.closeQuietly(input); - eventReader.close(); - } catch (XMLStreamException e){ - throw new RuntimeException(e); - } - return new TestResultContainer(testAttributes, resultFields); - } - - public class TestResultContainer { - - private List testAttributes; - private ResultFields resultFields; - - public TestResultContainer(List testAttributes, ResultFields resultFields) { - this.testAttributes = testAttributes; - this.resultFields = resultFields; - } - - public List getTestAttributes() { - return testAttributes; - } - - public ResultFields getResultFields() { - return resultFields; - } - } - - public class TestAttributes { - private final String moduleName; - private final String packageName; - private final String className; - private final String testName; - - public TestAttributes(final String moduleName, final String packageName, final String className, final String testName) { - this.moduleName = moduleName; - this.packageName = packageName; - this.className = className; - this.testName = testName; - } - - public String getPackageName() { - return packageName; - } - - public String getModuleName() { - return moduleName; - } - - public String getClassName() { - return className; - } - - public String getTestName() { - return testName; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java deleted file mode 100644 index 152226e1ed..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import com.google.inject.Inject; -import com.hp.application.automation.tools.octane.tests.CopyResourceSCM; -import com.hp.application.automation.tools.octane.tests.TestUtils; -import hudson.FilePath; -import hudson.maven.MavenBuild; -import hudson.maven.MavenModule; -import hudson.maven.MavenModuleSet; -import hudson.maven.MavenModuleSetBuild; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import hudson.tasks.test.AbstractTestResultAction; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; - -import javax.xml.stream.XMLStreamException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.Map; -import java.util.UUID; - -@SuppressWarnings({"squid:S2698","squid:S2699","squid:S3658"}) -public class TestNGExtensionTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - @ClassRule - public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Inject - public TestNGExtension extension = new TestNGExtension(); - - private String mavenName; - - @Before - public void setUp() throws Exception { - mavenName = ToolInstallations.configureMaven3().getName(); - } - - @Test - public void testFreestyleProject() throws Exception { - String projectName = "testNG-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); - project.getBuildersList().add(new Maven("-s settings.xml test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("helloWorld/target/surefire-reports/TEST*.xml, helloWorld2/target/surefire-reports/TEST*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testFreestyleProjectOneModule() throws Exception { - String projectName = "testNG-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); - project.getBuildersList().add(new Maven("-s settings.xml test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("target/surefire-reports/TEST*.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testFreestyleProjectCustomLocation() throws Exception { - String projectName = "testNG-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); - project.getBuildersList().add(new Maven("-s settings.xml test -P custom-report-location", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.getPublishersList().add(new JUnitResultArchiver("**\\custom-report-location/**.xml")); - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testMavenOneModule() throws Exception { - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); - AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testMavenMultimodule() throws Exception { - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); - MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - - //test detection in all sub-modules that include tests - Map moduleLastBuilds = build.getModuleLastBuilds(); - for (MavenBuild mavenBuild : moduleLastBuilds.values()) { - AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); - if (action != null) { - fields = readResultFields(mavenBuild); - assertTestNGFields(fields); - } - } - } - - @Test - public void testMavenOneModuleCustomLocation() throws Exception { - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -P custom-report-location -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); - AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - //we do not support combination of custom test report location and not publishing tests - Assert.assertNull(fields.getFramework()); - Assert.assertNull(fields.getTestLevel()); - Assert.assertNull(fields.getTestingTool()); - } - - @Test - public void testMavenMultimoduleCustomLocation() throws Exception { - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -P custom-report-location -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - //we do not support combination of custom test report location and not publishing tests - Assert.assertNull(fields.getFramework()); - Assert.assertNull(fields.getTestLevel()); - Assert.assertNull(fields.getTestingTool()); - } - - @Test - public void testMavenMultimoduleCustomLocationPublished() throws Exception { - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -P custom-report-location -Dmaven.test.failure.ignore=true"); - mavenProject.getPublishersList().add(new JUnitResultArchiver("**/custom-report-location/**.xml")); - mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); - AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testMavenFailsafe() throws Exception { - String projectName = "testNG-job-maven-failsafe-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml verify"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldFailsafe")); - AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); - - ResultFields fields = readResultFields(build); - assertTestNGFields(fields); - } - - @Test - public void testFindingFiles() throws IOException, InterruptedException { - temporaryFolder.newFolder("src"); - temporaryFolder.newFolder("target"); - temporaryFolder.newFolder("target", "foo"); - temporaryFolder.newFolder("target", "bar"); - temporaryFolder.newFolder("target", "baz"); - temporaryFolder.newFolder("target", "baz", "qux"); - - String[] pathsToXmls = new String[]{ - "target/foo/TEST1.xml", - "target/foo/TEST2.xml", - "target/foo/TEST3.xml", - "target/bar/TEST4.xml", - "target/bar/TEST5.xml", - "target/baz/TEST1.xml", - "target/baz/TEST2.xml", - "target/baz/qux/TEST1.xml", - "target/baz/qux/TEST2.xml", - }; - - for (String filePath : pathsToXmls) { - temporaryFolder.newFile(filePath); - } - - TestNGExtension.TestNgResultsFileFinder testNgFinder = new TestNGExtension.TestNgResultsFileFinder(null); - boolean found = testNgFinder.findTestNgResultsFile(temporaryFolder.getRoot(), pathsToXmls); - Assert.assertFalse(found); - - temporaryFolder.newFile("target/baz/qux/testng-results.xml"); - found = testNgFinder.findTestNgResultsFile(temporaryFolder.getRoot(), pathsToXmls); - Assert.assertTrue(found); - } - - @Test - public void testFindingFilesMavenBuild() throws Exception { - //running Junit tests - there will be no testng results file - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldRoot/helloWorld")); - MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); - - //test detection in all sub-modules that include tests - Map moduleLastBuilds = build.getModuleLastBuilds(); - for (MavenBuild mavenBuild : moduleLastBuilds.values()) { - AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); - if (action != null) { - boolean found = extension.findTestNgResultsFile(mavenBuild); - Assert.assertFalse(found); - - //creating tesng result file manually - FilePath folder = mavenBuild.getWorkspace().child("target/surefire-reports/testng-results.xml"); - File report = new File(folder.toURI()); - report.createNewFile(); - found = extension.findTestNgResultsFile(mavenBuild); - Assert.assertTrue(found); - report.delete(); - } - } - } - - @Test - public void testFindingFilesMavenBuildFailsafe() throws Exception { - //running Junit tests - there will be no testng results file - String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); - MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); - mavenProject.runHeadless(); - mavenProject.setMaven(mavenName); - mavenProject.setGoals("-s settings.xml test -Dmaven.test.failure.ignore=true"); - mavenProject.setScm(new CopyResourceSCM("/helloWorldRoot/helloWorld")); - MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); - - //test detection in all sub-modules that include tests - Map moduleLastBuilds = build.getModuleLastBuilds(); - for (MavenBuild mavenBuild : moduleLastBuilds.values()) { - AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); - if (action != null) { - boolean found = extension.findTestNgResultsFile(mavenBuild); - Assert.assertFalse(found); - - //creating tesng result file manually - FilePath reports = mavenBuild.getWorkspace().child("target/failsafe-reports"); - File reportFolder = new File(reports.toURI()); - reportFolder.mkdirs(); - - File reportFile = new File(reports.child("testng-results.xml").toURI()); - reportFile.createNewFile(); - - found = extension.findTestNgResultsFile(mavenBuild); - Assert.assertTrue(found); - reportFile.delete(); - reportFolder.delete(); - } - } - } - - private void assertTestNGFields(ResultFields fields) { - Assert.assertNotNull(fields); - Assert.assertEquals("TestNG", fields.getFramework()); - Assert.assertNull(fields.getTestingTool()); - Assert.assertNull(fields.getTestLevel()); - } - - private ResultFields readResultFields(AbstractBuild build) throws FileNotFoundException, XMLStreamException { - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - return xmlReader.readXml().getResultFields(); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtensionTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtensionTest.java deleted file mode 100644 index a350d41771..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/detection/UFTExtensionTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.detection; - -import com.hp.application.automation.tools.run.RunFromAlmBuilder; -import com.hp.application.automation.tools.run.RunFromFileBuilder; -import com.hp.application.automation.tools.octane.tests.TestUtils; -import com.hp.application.automation.tools.octane.tests.detection.ResultFieldsXmlReader.TestAttributes; -import com.hp.application.automation.tools.octane.tests.detection.ResultFieldsXmlReader.TestResultContainer; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleProject; -import hudson.scm.SubversionSCM; -import hudson.tasks.Maven; -import hudson.tasks.junit.JUnitResultArchiver; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; -import org.mockito.Mockito; - -import java.io.File; -import java.io.FileReader; -import java.util.List; -import java.util.UUID; - -@SuppressWarnings("squid:S2699") -public class UFTExtensionTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - - private ResultFieldsDetectionService detectionService; - - @Before - public void before() { - detectionService = new ResultFieldsDetectionService(); - } - - @Test - public void testMockOneBuilder() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.getBuildersList().add(new RunFromFileBuilder("notExistingTest")); - - AbstractBuild buildMock = Mockito.mock(AbstractBuild.class); - Mockito.when(buildMock.getProject()).thenReturn(project); - - ResultFields fields = detectionService.getDetectedFields(buildMock); - assertUFTFields(fields); - } - - @Test - public void testMockMoreBuilders() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.getBuildersList().add(new Maven("test", ToolInstallations.configureMaven3().getName(), null, null, "-Dmaven.test.failure.ignore=true")); - project.getBuildersList().add(new RunFromAlmBuilder("notExistingServer", "notExistingUser", "password", "domain", "project", "notExistingTests", "", "", "", "")); - - AbstractBuild buildMock = Mockito.mock(AbstractBuild.class); - Mockito.when(buildMock.getProject()).thenReturn(project); - - ResultFields fields = detectionService.getDetectedFields(buildMock); - assertUFTFields(fields); - } - - @Test - public void testFileBuilder() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - project.getBuildersList().add(new RunFromFileBuilder("")); - - //UFT plugin will not find any test -> that will cause failing the scheduled build - //but as detection runs after completion of run, we are sure, that it did not fail because of detection service - AbstractBuild build = project.scheduleBuild2(0).get(); - - ResultFields fields = detectionService.getDetectedFields(build); - assertUFTFields(fields); - } - - @Ignore - @Test - public void testUFTEndToEnd() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - //TODO solve storing of example test - SubversionSCM scm = new SubversionSCM("http://localhost:8083/svn/selenium/branches/uft"); - project.setScm(scm); - project.getBuildersList().add(new RunFromFileBuilder("Calculator")); - project.getPublishersList().add(new JUnitResultArchiver("Results*.xml")); - //this will actually run the UFT test - AbstractBuild build = TestUtils.runAndCheckBuild(project); - - File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); - ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); - TestResultContainer container = xmlReader.readXml(); - assertUFTFields(container.getResultFields()); - assertUFTTestAttributes(container.getTestAttributes()); - } - - private void assertUFTFields(ResultFields fields) { - Assert.assertNotNull(fields); - Assert.assertEquals("UFT", fields.getFramework()); - Assert.assertEquals("UFT", fields.getTestingTool()); - Assert.assertNull(fields.getTestLevel()); - } - - private void assertUFTTestAttributes(List testAttributes) { - for (TestAttributes test : testAttributes) { - Assert.assertTrue(test.getModuleName().isEmpty()); - Assert.assertTrue(test.getPackageName().isEmpty()); - Assert.assertTrue(test.getClassName().isEmpty()); - Assert.assertTrue(!test.getTestName().isEmpty()); - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java deleted file mode 100644 index a55a3b014b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.gherkin; - -import com.hp.application.automation.tools.octane.ResultQueue; -import com.hp.application.automation.tools.octane.actions.cucumber.CucumberTestResultsActionPublisher; -import com.hp.application.automation.tools.octane.tests.*; -import hudson.matrix.*; -import hudson.maven.MavenModuleSet; -import hudson.model.*; -import hudson.tasks.Maven; -import org.junit.*; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.ToolInstallations; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.*; - -/** - * Created by franksha on 05/01/2017. - */ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) -public class GherkinResultsTest { - - @ClassRule - public static final JenkinsRule rule = new JenkinsRule(); - private static String mavenName; - - private TestQueue queue; - - private static Set tests = new HashSet<>(); - static { - tests.add("My Amazing Feature"); - tests.add("My Fancy Feature"); - } - - @BeforeClass - public static void prepareClass() throws Exception { - rule.jenkins.setNumExecutors(10); - Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven3(); - mavenName = mavenInstallation.getName(); - } - - @Before - public void prepareTest() { - TestListener testListener = ExtensionUtil.getInstance(rule, TestListener.class); - queue = new TestQueue(); - testListener._setTestResultQueue(queue); - } - - @Test - public void testGherkinResultsDirectlyOnWorkspace() throws Exception { - gherkinResults("*Gherkin*.xml", true); - } - - @Test - public void testGherkinResultsDirectlyOnWorkspaceEmptyGlob() throws Exception { - gherkinResults("", true); - } - - @Test - public void testGherkinResultsDirectlyOnWorkspaceNegative() throws Exception { - gherkinResults("abcd.xml", false); - } - - @Test - public void testGherkinResultsInSubFolder() throws Exception { - gherkinResultsInSubFolder("subFolder/*Gherkin*.xml", true); - } - - @Test - public void testGherkinResultsInSubFolderEmptyGlob() throws Exception { - gherkinResultsInSubFolder("", true); - } - @Test - public void testGherkinResultsInSubFolderNegative() throws Exception { - gherkinResultsInSubFolder("*Gherkin*.xml", false); - } - - @Test - public void testGherkinResultsDirectlyOnWorkspaceLegacy() throws Exception { - gherkinResultsLegacy("*Gherkin*.xml", true); - } - @Test - public void testGherkinResultsDirectlyOnWorkspaceLegacyEmptyGlob() throws Exception { - gherkinResultsLegacy("", true); - } - - @Test - public void testGherkinResultsDirectlyOnWorkspaceLegacyNegative() throws Exception { - gherkinResultsLegacy("abcd.xml", false); - } - - @Test - public void testGherkinResultsInSubFolderLegacy() throws Exception { - gherkinResultsLegacyWithSubFolder("subFolder/*Gherkin*.xml", true); - } - - @Test - public void testGherkinResultsInSubFolderLegacyEmptyGlob() throws Exception { - gherkinResultsLegacyWithSubFolder("", true); - } - - @Test - public void testGherkinResultsInSubFolderLegacyNegative() throws Exception { - gherkinResultsLegacyWithSubFolder("*Gherkin*.xml", false); - } - - @Test - public void testGherkinResultsMatrixProject() throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MatrixProject matrixProject = rule.createProject(MatrixProject.class, projectName); - matrixProject.setAxes(new AxisList(new Axis("osType", "Linux", "Windows"))); - - matrixProject.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - matrixProject.getPublishersList().add(new CucumberTestResultsActionPublisher("")); - matrixProject.setScm(new CopyResourceSCM("/helloCucumberWorld")); - - MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); - for (MatrixRun run : build.getExactRuns()) { - assertTestResultsEqual(tests, new File(run.getRootDir(), "mqmTests.xml")); - } - Assert.assertEquals(new HashSet<>(Arrays.asList(projectName + "/osType=Windows#1", projectName + "/osType=Linux#1")), getQueuedItems()); - Assert.assertFalse(new File(build.getRootDir(), "mqmTests.xml").exists()); - } - - @Test - public void testGherkinResultsWrongFile() throws Exception { - gherkinResults("pom.xml", false); - } - - @Test - public void testGherkinResultsWrongLongFile() throws Exception { - gherkinResults("settings.xml", false); - } - - private void gherkinResults(String glob, boolean buildShouldSucceed) throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s settings.xml clean test", mavenName, null, null, "-Dmaven.test.failure.ignore=true")); - project.setScm(new CopyResourceSCM("/helloCucumberWorld")); - - project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); - - assertProject(project, buildShouldSucceed); - } - - private void gherkinResultsInSubFolder(String glob, boolean buildShouldSucceed) throws Exception { - String projectName = "root-job-" + UUID.randomUUID().toString(); - FreeStyleProject project = rule.createFreeStyleProject(projectName); - - project.getBuildersList().add(new Maven("-s subFolder/settings.xml clean test", mavenName, "subFolder/pom.xml", null, "-Dmaven.test.failure.ignore=true")); - project.setScm(new CopyResourceSCM("helloCucumberWorld", "subFolder")); - - project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); - - assertProject(project, buildShouldSucceed); - } - - private void gherkinResultsLegacy(String glob, boolean buildShouldSucceed) throws Exception { - MavenModuleSet project = prepareLegacyProject(false); - project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); - assertProject(project, buildShouldSucceed); - } - - private void gherkinResultsLegacyWithSubFolder(String glob, boolean buildShouldSucceed) throws Exception { - MavenModuleSet project = prepareLegacyProject(true); - project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); - assertProject(project, buildShouldSucceed); - } - - private MavenModuleSet prepareLegacyProject(boolean subfolder) throws IOException { - String projectName = "root-job-" + UUID.randomUUID().toString(); - MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); - project.runHeadless(); - - project.setMaven(mavenName); - project.setGoals("-s settings.xml clean test -Dmaven.test.failure.ignore=true"); - if(subfolder) { - project.setRootPOM("subFolder/pom.xml"); - project.setScm(new CopyResourceSCM("/helloCucumberWorld", "subFolder")); - } else { - project.setScm(new CopyResourceSCM("/helloCucumberWorld")); - } - return project; - } - - private void assertProject(AbstractProject project, boolean buildShouldSucceed) throws Exception { - if(buildShouldSucceed) { - AbstractBuild build = TestUtils.runAndCheckBuild(project); - assertTestResultsEqual(tests, new File(build.getRootDir(), "mqmTests.xml")); - Assert.assertEquals(Collections.singleton(project.getName() + "#1"), getQueuedItems()); - } else { - AbstractBuild build = (AbstractBuild) project.scheduleBuild2(0).get(); - Assert.assertEquals("Build should fail", Result.FAILURE, build.getResult()); - Assert.assertEquals("Expects empty queue", 0, getQueuedItems().size()); - } - } - - private void assertTestResultsEqual(Set expected, File actual) throws ParserConfigurationException, IOException, SAXException { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document actualDoc = dBuilder.parse(actual); - - NodeList actualTests = actualDoc.getElementsByTagName("gherkin_test_run"); - Assert.assertEquals("Number of tests should be equal", expected.size(), actualTests.getLength()); - - NodeList automatedTests = actualDoc.getElementsByTagName("test_run"); - Assert.assertEquals("There should be no automated tests", 0, automatedTests.getLength()); - - int i=0; - for (String expectedName : expected) { - Node actualTest = actualTests.item(i++); - Assert.assertEquals("Test name should be equal", expectedName, getAttr(actualTest, "name")); - Assert.assertEquals("Test status should be equal", "Passed", getAttr(actualTest, "status")); - } - } - - private String getAttr(Node node, String attrName) { - return node.getAttributes().getNamedItem(attrName).getNodeValue(); - } - - private Set getQueuedItems() { - Set ret = new HashSet<>(); - ResultQueue.QueueItem item; - while ((item = queue.peekFirst()) != null) { - ret.add(item.getProjectName() + "#" + item.getBuildNumber()); - queue.remove(); - } - return ret; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollectorTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollectorTest.java deleted file mode 100644 index 5f4e6ae16c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/gherkin/GherkinTestResultsCollectorTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.gherkin; - -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import org.junit.Assert; -import org.junit.Test; -import org.xml.sax.SAXException; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.List; -import java.util.Map; - -public class GherkinTestResultsCollectorTest { - String defaultResourceRelativePath = "f1"; - String defaultResourceName = "OctaneGherkinResults0.xml"; - - private String getDefaultRootResourceFolder(){ - return getRootResourceFolder(defaultResourceRelativePath,defaultResourceName); - } - - private String getRootResourceFolder(String resourceRelativePath,String resourceName){ - String resource; - if(resourceRelativePath.isEmpty()){ - resource = resourceName; - } else { - resource = resourceRelativePath + "/" + resourceName; - } - URL url = getClass().getResource(resource); - String path = url.getPath(); - return path.substring(0,path.lastIndexOf(resourceName)-1); - } - - @Test - public void testConstruct() throws InterruptedException, ParserConfigurationException, IOException, SAXException, TransformerException { - GherkinTestResultsCollector.collectGherkinTestsResults(new File(getDefaultRootResourceFolder())); - } - - @Test - public void testGetResults() throws InterruptedException, ParserConfigurationException, IOException, SAXException, TransformerException { - List gherkinTestsResults = GherkinTestResultsCollector.collectGherkinTestsResults(new File(getDefaultRootResourceFolder())); - Assert.assertEquals(3,gherkinTestsResults.size()); - validateGherkinTestResult((GherkinTestResult)gherkinTestsResults.get(0),"test Feature1",21, TestResultStatus.FAILED); - validateGherkinTestResult((GherkinTestResult)gherkinTestsResults.get(1),"test Feature10",21,TestResultStatus.FAILED); - validateGherkinTestResult((GherkinTestResult)gherkinTestsResults.get(2),"test Feature2",21,TestResultStatus.PASSED); - } - - @Test (expected=IllegalArgumentException.class) - public void testXmlHasNoVersion() throws InterruptedException, ParserConfigurationException, IOException, SAXException, TransformerException { - GherkinTestResultsCollector.collectGherkinTestsResults(new File(getRootResourceFolder("f2",defaultResourceName))); - } - - @Test (expected=IllegalArgumentException.class) - public void testXmlHasHigherVersion() throws InterruptedException, ParserConfigurationException, IOException, SAXException, TransformerException { - GherkinTestResultsCollector.collectGherkinTestsResults(new File(getRootResourceFolder("f3",defaultResourceName))); - } - - private void validateGherkinTestResult(GherkinTestResult gherkinTestResult, String name, long duration, TestResultStatus status){ - validateAttributes(gherkinTestResult, name, duration, status); - Assert.assertNotNull(gherkinTestResult.getXmlElement()); - } - - private void validateAttributes(GherkinTestResult gherkinTestResult, String name, long duration, TestResultStatus status){ - Map attributes = gherkinTestResult.getAttributes(); - Assert.assertEquals(name,attributes.get("name")); - Assert.assertEquals(String.valueOf(duration),attributes.get("duration")); - Assert.assertEquals(status.toPrettyName(),attributes.get("status")); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java b/src/test/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java deleted file mode 100644 index 323ebf551f..0000000000 --- a/src/test/java/com/hp/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.octane.tests.xml; - -import com.hp.application.automation.tools.octane.tests.TestResultContainer; -import com.hp.application.automation.tools.octane.tests.TestResultIterable; -import com.hp.application.automation.tools.octane.tests.junit.JUnitTestResult; -import com.hp.application.automation.tools.octane.tests.TestResultIterator; -import com.hp.application.automation.tools.octane.tests.TestUtils; -import com.hp.application.automation.tools.octane.tests.detection.ResultFields; -import com.hp.application.automation.tools.octane.tests.junit.TestResultStatus; -import com.hp.application.automation.tools.octane.tests.testResult.TestResult; -import hudson.FilePath; -import hudson.matrix.Axis; -import hudson.matrix.AxisList; -import hudson.matrix.MatrixBuild; -import hudson.matrix.MatrixProject; -import hudson.model.AbstractBuild; -import hudson.model.FreeStyleBuild; -import hudson.model.FreeStyleProject; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -import javax.xml.stream.XMLStreamException; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings({"squid:S2698","squid:S2699"}) -public class TestResultXmlWriterTest { - - @ClassRule - public static final JenkinsRule jenkins = new JenkinsRule(); - - private TestResultContainer container; - - @Before - public void initialize() throws IOException { - List testResults = new ArrayList<>(); - testResults.add(new JUnitTestResult("module", "package", "class", "testName", TestResultStatus.PASSED, 1l, 2l, null, null)); - container = new TestResultContainer(testResults.iterator(), new ResultFields()); - } - - @Test - public void testNonEmptySubType() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class, "matrix-project"); - - matrixProject.setAxes(new AxisList(new Axis("OS", "Linux"))); - MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); - Assert.assertEquals(1, build.getExactRuns().size()); - assertBuildType(build.getExactRuns().get(0), "matrix-project", "OS=Linux"); - } - - @Test - public void testEmptySubType() throws Exception { - FreeStyleProject project = jenkins.createFreeStyleProject("freestyle-project"); - FreeStyleBuild build = (FreeStyleBuild) TestUtils.runAndCheckBuild(project); - assertBuildType(build, "freestyle-project", null); - } - - private void assertBuildType(AbstractBuild build, String buildType, String subType) throws IOException, XMLStreamException, InterruptedException { - FilePath testXml = new FilePath(build.getWorkspace(), "test.xml"); - TestResultXmlWriter xmlWriter = new TestResultXmlWriter(testXml, build); - xmlWriter.writeResults(container); - xmlWriter.close(); - - TestResultIterator iterator = new TestResultIterable(new File(testXml.getRemote())).iterator(); - Assert.assertEquals(buildType, iterator.getJobId()); - Assert.assertEquals(subType, iterator.getSubType()); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/pc/MockPcModel.java b/src/test/java/com/hp/application/automation/tools/pc/MockPcModel.java deleted file mode 100644 index 850b0f4621..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/MockPcModel.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import com.hp.application.automation.tools.model.PcModel; -import com.hp.application.automation.tools.model.PostRunAction; -import com.hp.application.automation.tools.model.SecretContainer; -import com.hp.application.automation.tools.model.SecretContainerTest; - -public class MockPcModel extends PcModel { - - - public MockPcModel(String pcServerName, String almUserName, String almPassword, String almDomain, - String almProject, String testId, String testInstanceId, String timeslotDurationHours, - String timeslotDurationMinutes, PostRunAction postRunAction, boolean vudsMode, String description) { - super(pcServerName, almUserName, almPassword, almDomain, almProject, testId, testInstanceId, timeslotDurationHours, - timeslotDurationMinutes, postRunAction, vudsMode, description, false, null); - } - - @Override - protected SecretContainer setPassword(String almPassword) { - - SecretContainer secretContainer = new SecretContainerTest(); - secretContainer.initialize(almPassword); - - return secretContainer; - } - - - -} diff --git a/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxy.java b/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxy.java deleted file mode 100644 index 8583dcee85..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; - -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.HttpVersion; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.FileEntity; -import org.apache.http.entity.StringEntity; -import org.apache.http.message.BasicHttpResponse; - -import com.hp.application.automation.tools.common.PcException; -import com.hp.application.automation.tools.run.PcBuilder; - -import static com.hp.application.automation.tools.pc.PcTestBase.*; -import static com.hp.application.automation.tools.pc.RunState.*; - -public class MockPcRestProxy extends PcRestProxy { - - private static Iterator runState = initializeRunStateIterator(); - - public MockPcRestProxy(String pcServerName, String almDomain, String almProject) { - super(pcServerName, almDomain, almProject); - } - - @Override - protected HttpResponse executeRequest(HttpRequestBase request) throws PcException, ClientProtocolException, - IOException { - HttpResponse response = null; - String requestUrl = request.getURI().toString(); - if (requestUrl.equals(String.format(AUTHENTICATION_LOGIN_URL, PC_SERVER_NAME)) - || requestUrl.equals(String.format(AUTHENTICATION_LOGOUT_URL, PC_SERVER_NAME)) - || requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, RUN_ID, STOP_MODE))) { - response = getOkResponse(); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s", RUNS_RESOURCE_NAME)) - || requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, RUN_ID))) { - response = getOkResponse(); - response.setEntity(new StringEntity(PcTestBase.runResponseEntity)); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, RUN_ID_WAIT))) { - response = getOkResponse(); - response.setEntity(new StringEntity(PcTestBase.runResponseEntity.replace("*", runState.next().value()))); - if (!runState.hasNext()) - runState = initializeRunStateIterator(); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, RUN_ID, - RESULTS_RESOURCE_NAME))) { - response = getOkResponse(); - response.setEntity(new StringEntity(PcTestBase.runResultsEntity)); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s/%s/data", RUNS_RESOURCE_NAME, RUN_ID, - RESULTS_RESOURCE_NAME, REPORT_ID))) { - response = getOkResponse(); - response.setEntity(new FileEntity( - new File(getClass().getResource(PcBuilder.pcReportArchiveName).getPath()), ContentType.DEFAULT_BINARY)); - } - if (response == null) - throw new PcException(String.format("%s %s is not recognized by PC Rest Proxy", request.getMethod(), requestUrl)); - return response; - } - - private HttpResponse getOkResponse(){ - - return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - } - - private static Iterator initializeRunStateIterator(){ - - return Arrays.asList(INITIALIZING,RUNNING,COLLATING_RESULTS,CREATING_ANALYSIS_DATA,FINISHED).iterator(); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxyBadResponses.java b/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxyBadResponses.java deleted file mode 100644 index dc7d7dd948..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/MockPcRestProxyBadResponses.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; - -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.HttpVersion; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.entity.StringEntity; -import org.apache.http.message.BasicHttpResponse; - -import com.hp.application.automation.tools.common.PcException; -import static com.hp.application.automation.tools.pc.PcTestBase.*; -import static com.hp.application.automation.tools.pc.RunState.*; - -public class MockPcRestProxyBadResponses extends PcRestProxy { - - private static Iterator runState = initializeRunStateIterator(); - - public MockPcRestProxyBadResponses(String pcServerName, String almDomain, String almProject) { - super(pcServerName, almDomain, almProject); - } - - @Override - protected HttpResponse executeRequest(HttpRequestBase request) throws PcException, ClientProtocolException, - IOException { - HttpResponse response = null; - String requestUrl = request.getURI().toString(); - if (requestUrl.equals(String.format(AUTHENTICATION_LOGIN_URL, PC_SERVER_NAME))) { - throw new PcException(pcAuthenticationFailureMessage); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s", RUNS_RESOURCE_NAME))){ - throw new PcException(pcNoTimeslotExceptionMessage); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, RUN_ID_WAIT))) { - response = getOkResponse(); - response.setEntity(new StringEntity(PcTestBase.runResponseEntity.replace("*", runState.next().value()))); - if (!runState.hasNext()) - runState = initializeRunStateIterator(); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, RUN_ID, - RESULTS_RESOURCE_NAME))) { - response = getOkResponse(); - response.setEntity(new StringEntity(PcTestBase.emptyResultsEntity)); - } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, RUN_ID, STOP_MODE))) { - throw new PcException(pcStopNonExistRunFailureMessage); - } - if (response == null) - throw new PcException(String.format("%s %s is not recognized by PC Rest Proxy", request.getMethod(), requestUrl)); - return response; - } - - private HttpResponse getOkResponse(){ - - return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); - } - - private static Iterator initializeRunStateIterator() { - - return Arrays.asList(INITIALIZING, RUNNING, RUN_FAILURE).iterator(); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/pc/PcTestBase.java b/src/test/java/com/hp/application/automation/tools/pc/PcTestBase.java deleted file mode 100644 index 945382c47a..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/PcTestBase.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import com.hp.application.automation.tools.model.PostRunAction; - -public interface PcTestBase { - - public static final String PC_SERVER_NAME = "pcServer.hp.com"; - public static final String ALM_USER_NAME = "sa"; - public static final String ALM_PASSWORD = "pwd"; - public static final String ALM_DOMAIN = "ALMDOM"; - public static final String ALM_PROJECT = "ALMPROJ"; - public static final String TEST_ID = "1"; - public static final String TEST_INSTANCE_ID = "2"; - public static final String TIMESLOT_DURATION_HOURS = "0"; - public static final String TIMESLOT_DURATION_MINUTES = "34"; - public static final String TIMESLOT_ID = "56"; - public static final PostRunAction POST_RUN_ACTION = PostRunAction.COLLATE_AND_ANALYZE; - public static final boolean VUDS_MODE = false; - public static final String DESCRIPTION = "Testing HP Performance Center Jenkins plugin"; - public static final String RUN_ID = "7"; - public static final String RUN_ID_WAIT = "8"; - public static final String REPORT_ID = "9"; - public static final String STOP_MODE = "stop"; - - public static final MockPcModel pcModel = new MockPcModel(PC_SERVER_NAME, ALM_USER_NAME, - ALM_PASSWORD, ALM_DOMAIN, ALM_PROJECT, - TEST_ID, TEST_INSTANCE_ID, - TIMESLOT_DURATION_HOURS, - TIMESLOT_DURATION_MINUTES, POST_RUN_ACTION, - VUDS_MODE, DESCRIPTION); - - public static final String runResponseEntity = "" + - "" + TEST_ID + "" + - "" + TEST_INSTANCE_ID + "" + - "" + POST_RUN_ACTION.getValue() + "" + - "1076" + - "false" + - "" + RUN_ID + "" + - "" + TIMESLOT_DURATION_MINUTES + "" + - "*" + - "" + - ""; - - public static final String emptyResultsEntity = ""; - - public static final String runResultsEntity = "" + - "" + - "1302" + - "output.mdb.zip" + - "Output Log" + - "" + RUN_ID + "" + - "" + - "" + - "1303" + - "RawResults.zip" + - "Raw Results" + - "" + RUN_ID + "" + - "" + - "" + - "1304" + - "Results.zip" + - "Analyzed Result" + - "" + RUN_ID + "" + - "" + - "" + - "" + REPORT_ID + "" + - "Reports.zip" + - "HTML Report" + - "" + RUN_ID + "" + - "" + - "" + - "1306" + - "HighLevelReport_7.xls" + - "Rich Report" + - "" + RUN_ID + "" + - "" + - ""; - - public static final String pcAuthenticationFailureMessage = "Exception of type 'HP.PC.API.Model.Exceptions.InvalidAuthenticationDataException' was thrown. Error code: 1100"; - - public static final String pcNoTimeslotExceptionMessage = "Failed to retrieve reservation information for reservation " + TIMESLOT_ID + ". Error code: 1202"; - - public static final String pcStopNonExistRunFailureMessage = "Failed to retrieve run " + RUN_ID + " information from domain " + ALM_DOMAIN + ", project " + ALM_PROJECT + ". Error code: 1300"; - -} diff --git a/src/test/java/com/hp/application/automation/tools/pc/TestPcClient.java b/src/test/java/com/hp/application/automation/tools/pc/TestPcClient.java deleted file mode 100644 index 852e28e20f..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/TestPcClient.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import hudson.FilePath; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.hp.application.automation.tools.run.PcBuilder; - -@SuppressWarnings({"squid:S2699","squid:S3658"}) -public class TestPcClient { - - private static PcClient pcClient; - public final String RESOURCES_DIR = getClass().getResource("").getPath(); - - @BeforeClass - public static void setUp() { - try { - PcRestProxy resetProxy = new MockPcRestProxy(PcTestBase.PC_SERVER_NAME, PcTestBase.ALM_DOMAIN, - PcTestBase.ALM_PROJECT); - pcClient = new PcClient(PcTestBase.pcModel, System.out, resetProxy); - } catch (Exception e) { - e.printStackTrace(System.out); - } - } - - @Test - public void testLogin(){ - System.out.println("Testing Login to HP PC server"); - Assert.assertTrue("Failed to login with pcClient", pcClient.login()); - } - - @Test - public void testStartRun(){ - System.out.println("Testing Start Run with PC client"); - try { - Assert.assertTrue("Failed to start run with pcClient", pcClient.startRun() > 0); - } catch (Exception e) { - Assert.fail(e.toString()); - } - } - - @Test (timeout=5000) - public void testWaitForRunCompletion(){ - - System.out.println("Testing Wait for Run Completion with PC client"); - try { - PcRunResponse response = pcClient.waitForRunCompletion(Integer.parseInt(PcTestBase.RUN_ID_WAIT), 200); - Assert.assertEquals(response.getRunState(), RunState.FINISHED.value()); - } catch (InterruptedException e) { - Assert.fail("pcClient did not return from waitForRunCompletion (test run has timed out)"); - }catch (Exception e) { - Assert.fail(e.toString()); - } - } - - @Test - public void testPublishRunReport(){ - - System.out.println("Testing Publish PC Run Report to Jenkins server with PC client"); - try { - - FilePath reportHtml = pcClient.publishRunReport(Integer.parseInt(PcTestBase.RUN_ID), - String.format(PcBuilder.getRunReportStructure(), RESOURCES_DIR, PcBuilder.getArtifactsDirectoryName(), PcTestBase.RUN_ID)); - Assert.assertTrue("Failed to publish PC run report", reportHtml.exists()); - try { - // Test cleanup - reportHtml.getParent().getParent().getParent().deleteRecursive(); - } catch (Exception e) { - } - } catch (Exception e) { - Assert.fail(e.toString()); - } - } - - @Test - public void testLogout() { - System.out.println("Testing Logout from HP PC server"); - Assert.assertTrue("Failed to logout with pcClient", pcClient.logout()); - } - - @Test - public void testStopRun() { - System.out.println("Testing Stop Run with PC client"); - Assert.assertTrue("Failed to stop run with pcClient", pcClient.stopRun(Integer.parseInt(PcTestBase.RUN_ID))); - } - - -} - diff --git a/src/test/java/com/hp/application/automation/tools/pc/TestPcClientNegativeScenrios.java b/src/test/java/com/hp/application/automation/tools/pc/TestPcClientNegativeScenrios.java deleted file mode 100644 index 6530b9bee7..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pc/TestPcClientNegativeScenrios.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pc; - -import hudson.FilePath; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import com.hp.application.automation.tools.run.PcBuilder; - -@SuppressWarnings({"squid:S2699","squid:S3658"}) -public class TestPcClientNegativeScenrios { - - private static PcClient pcClient; - public final String RESOURCES_DIR = getClass().getResource("").getPath(); - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @BeforeClass - public static void setUp() { - System.out.println("Starting HP Performance Center client negative testing scenarios:"); - try { - PcRestProxy resetProxy = new MockPcRestProxyBadResponses(PcTestBase.PC_SERVER_NAME, PcTestBase.ALM_DOMAIN, - PcTestBase.ALM_PROJECT); - pcClient = new PcClient(PcTestBase.pcModel, new PrintStream(new OutputStream() { - - @Override - public void write(int b) throws IOException {} - - }), resetProxy); - } catch (Exception e) { - e.printStackTrace(System.out); - } - } - - @AfterClass - public static void tearDown() { - System.out.println("End of HP Performance Center client negative testing scenarios"); - } - - @Test - public void testLoginWithWrongCredentials() { - - System.out.println("Testing Login to HP PC server with wrong credentials"); - Assert.assertFalse("Login to PC server with wrong creadentials should have failed", pcClient.login()); - } - - @Test(timeout = 5000) - public void testHandleRunFailureWhileWaitingForRunCompletion() { - - System.out.println("Testing Wait For Run Completion with PC client while run fails"); - try { - PcRunResponse response = pcClient.waitForRunCompletion(Integer.parseInt(PcTestBase.RUN_ID_WAIT), 200); - Assert.assertEquals(response.getRunState(), RunState.RUN_FAILURE.value()); - } catch (InterruptedException e) { - Assert.fail("pcClient did not return from waitForRunCompletion (test run has timed out)"); - } catch (Exception e) { - Assert.fail(e.toString()); - } - } - - @Test - public void testPublishRunReportWithEmptyResults() { - - System.out.println("Testing Publish PC Run Report to while run results are empty"); - try { - - FilePath reportHtml = pcClient.publishRunReport(Integer.parseInt(PcTestBase.RUN_ID), String.format( - PcBuilder.getRunReportStructure(), RESOURCES_DIR, PcBuilder.getArtifactsDirectoryName(), - PcTestBase.RUN_ID)); - Assert.assertNull("pcClient.publishRunReport should have returned null due to empty run results", - reportHtml); - } catch (Exception e) { - Assert.fail("pcClient.publishRunReport threw an exception (should have returned null due to empty run results): " - + e.toString()); - } - } - - @Test - public void testStopNonExistingRun() { - - System.out.println("Testing stopping a non-exising run with PC client"); - Assert.assertFalse("Stopping a non-existing run should have failed", pcClient.stopRun(Integer.parseInt(PcTestBase.RUN_ID))); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java b/src/test/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java deleted file mode 100644 index ef0f855b74..0000000000 --- a/src/test/java/com/hp/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.pipelineSteps; - -import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; -import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; - -/** -* LoadRunnerTestStep Tester. -* -* @author -* @since
      ??? 28, 2016
      -* @version 1.0 -*/ -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701"}) -public class LrScenarioLoadStepTest { - - @Rule - public JenkinsRule jenkinsRule = new JenkinsRule(); - - - @Before - public void before() throws Exception { - } - - @After - public void after() throws Exception { - } - - /** - * Method: runLoadRunnerScenario - */ - @Test - public void testLrScenarioRun() throws Exception { - // Setup the job - WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "foo"); - job.setDefinition(new CpsFlowDefinition("node {}")); // insert here the pipeline code to run - - //run the build nad wait for successful result - WorkflowRun workflowRun = jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0).get()); - - //now we need to check the results. - - } -} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/NUnitReport.xml b/src/test/java/com/hp/application/automation/tools/results/parser/NUnitReport.xml deleted file mode 100644 index 7818ae420c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/NUnitReport.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java b/src/test/java/com/hp/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java deleted file mode 100644 index f8e5aa68f0..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import org.junit.Assert; - -import org.junit.Test; - -import com.hp.application.automation.tools.results.parser.antjunit.AntJUnitReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -@SuppressWarnings("squid:S2698") -public class TestAntJUnitReportParserImpl { - - //@Test - public void testParseTestSets() throws Exception { - InputStream in = TestAntJUnitReportParserImpl.class.getResourceAsStream("AntTESTS-TestSuites.xml"); - AntJUnitReportParserImpl parser = new AntJUnitReportParserImpl(); - List testsets = parser.parseTestSets(in, "JUnit", "Ant"); - Assert.assertEquals(testsets.size(), 1); - Assert.assertEquals("TestProg1Prj1Test1", testsets.get(0).getName() ); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java b/src/test/java/com/hp/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java deleted file mode 100644 index 11034f5997..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.results.parser.jenkinsjunit.JenkinsJUnitReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872"}) -public class TestJenkinsJunitReportParserImpl { - - //@Test - public void testParseTestSets() throws Exception { - InputStream in = TestJenkinsJunitReportParserImpl.class.getResourceAsStream("junitResult.xml"); - JenkinsJUnitReportParserImpl parser = new JenkinsJUnitReportParserImpl(); - List testsets = parser.parseTestSets(in, "JUnit", "LeanFT"); - Assert.assertEquals(1, testsets.size()); - Assert.assertEquals("prog1prj1.TestProg1Prj1Test1", testsets.get(0).getName()); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java b/src/test/java/com/hp/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java deleted file mode 100644 index 1930230d2f..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import org.junit.Assert; - -import org.junit.Test; - -import com.hp.application.automation.tools.results.parser.mavensurefire.MavenSureFireReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; - - -public class TestMavenSureFireReportParserImpl { - - //@Test - public void testParseTestSets()throws Exception { - InputStream in = TestMavenSureFireReportParserImpl.class.getResourceAsStream("MAVENTEST-com.demoapp.demo.AppTest.xml"); - MavenSureFireReportParserImpl parser = new MavenSureFireReportParserImpl(); - List testsets = parser.parseTestSets(in, "JUnit", "Maven"); - assert (testsets.size () == 1); - AlmTestSet testset = testsets.get(0); - Assert.assertEquals("com.demoapp.demo.AppTest", testset.getName()); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/TestNUnitReportParserImpl.java b/src/test/java/com/hp/application/automation/tools/results/parser/TestNUnitReportParserImpl.java deleted file mode 100644 index 9ac5cbe843..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/TestNUnitReportParserImpl.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import org.junit.Assert; - -import org.junit.Test; - -import com.hp.application.automation.tools.results.parser.nunit.NUnitReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; - -@SuppressWarnings({"squid:S2699","squid:S3658"}) -public class TestNUnitReportParserImpl { - - //@Test - public void testParseTestSets() throws Exception{ - InputStream in = TestNUnitReportParserImpl.class.getResourceAsStream("NUnitReport.xml"); - NUnitReportParserImpl parser = new NUnitReportParserImpl(); - List testsets = parser.parseTestSets(in, "NUnit", "Selenium"); - Assert.assertEquals(1, testsets.size()); - Assert.assertEquals("NUnit_Test1.dll_ExampleTestOfNUnit", testsets.get(0).getName()); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java b/src/test/java/com/hp/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java deleted file mode 100644 index d33bc53f78..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.parser; - -import java.io.InputStream; -import java.util.List; - -import org.junit.Assert; - -import org.junit.Test; - -import com.hp.application.automation.tools.results.parser.testngxml.TestNGXmlReportParserImpl; -import com.hp.application.automation.tools.results.service.almentities.AlmTestSet; - -@SuppressWarnings("squid:S2698") -public class TestTestNGXmlReportParserImpl { - - //@Test - public void testParseTestSets() throws Exception { - - InputStream in = TestTestNGXmlReportParserImpl.class.getResourceAsStream("testng-results.xml"); - TestNGXmlReportParserImpl parser = new TestNGXmlReportParserImpl(); - List testsets = parser.parseTestSets(in, "TestNG", "jenkins"); - - Assert.assertEquals(1, testsets.size()); - Assert.assertEquals("Suite1", testsets.get(0).getName()); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/junitResult.xml b/src/test/java/com/hp/application/automation/tools/results/parser/junitResult.xml deleted file mode 100644 index d20ce28d63..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/junitResult.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - C:\QC\Jenkins\workspace\test1\prog1prj1\output\TEST-prog1prj1.TestProg1Prj1Test1.xml - prog1prj1.TestProg1Prj1Test1 - - - 0.064 - 2015-05-12T12:23:27 - - - 0.002 - prog1prj1.TestProg1Prj1Test1 - testMethod1 - false - 0 - - - 0.001 - prog1prj1.TestProg1Prj1Test1 - testMethod2 - false - 0 - - - 0.061 - prog1prj1.TestProg1Prj1Test1 - testMethod3 - false - junit.framework.AssertionFailedError: Not yet implemented - at prog1prj1.TestProg1Prj1Test1.testMethod3(Unknown Source) - - Not yet implemented - 0 - - - - - 0.064 - false - \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/testng-results.xml b/src/test/java/com/hp/application/automation/tools/results/parser/testng-results.xml deleted file mode 100644 index 885daef19c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/parser/testng-results.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/java/com/hp/application/automation/tools/results/service/NUnitReport.xml b/src/test/java/com/hp/application/automation/tools/results/service/NUnitReport.xml deleted file mode 100644 index 7818ae420c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/service/NUnitReport.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java b/src/test/java/com/hp/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java deleted file mode 100644 index 85957c176c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.results.service; - - -public class TestDefaultExternalEntityUploadServiceImpl { - - - private static void testJunit(int i) throws Exception{ - AlmRestInfo loginInfo = new AlmRestInfo( - "http://localhost:8085/qcbin", - "DEFAULT", - "testexternal1", - "sa", - "", - "" - ); - AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); - - IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u,new SystemOutLogger()); - String reportFilePath = TestDefaultExternalEntityUploadServiceImpl.class.getResource("junitResult.xml").getPath(); - String testingFramework = "JUnit"; - String testingTool = "Jenkins"; - String subversion = "1"; - String testFolderPath = "Import\\New Test Folder\\junit" + i; - String testsetFolderPath = "Import\\New Test Set Folder\\junit" +i; - long start = System.currentTimeMillis(); - service.UploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); - long end = System.currentTimeMillis(); - System.out.println("total time:" + (end -start)); - - } - - private static void testtestNG(int i) throws Exception{ - AlmRestInfo loginInfo = new AlmRestInfo( - "http://localhost:8085/qcbin", - "DEFAULT", - "testexternal1", - "sa", - "", - "" - ); - AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); - - IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, new SystemOutLogger()); - - String reportFilePath = TestDefaultExternalEntityUploadServiceImpl.class.getResource("testng-results.xml").getPath(); - String testingFramework = "TestNG"; - String testingTool = "Jenkins testng"; - String subversion = "1"; - String testFolderPath = "Import\\New Test Folder\\testng"+i; - String testsetFolderPath = "Import\\New Test Set Folder\\testng"+i; - long start = System.currentTimeMillis(); - service.UploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); - long end = System.currentTimeMillis(); - System.out.println("total time:" + (end -start)); - } - - private static void testnunit(int i) throws Exception{ - AlmRestInfo loginInfo = new AlmRestInfo( - "http://localhost:8085/qcbin", - "DEFAULT", - "testexternal1", - "sa", - "", - "" - ); - AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); - - IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, new SystemOutLogger()); - - String reportFilePath = TestDefaultExternalEntityUploadServiceImpl.class.getResource("NUnitReport.xml").getPath(); - - String testingFramework = "NUNit"; - String testingTool = "Jenkins nunit"; - String subversion = "1"; - String testFolderPath = "Import\\New Test Folder\\nunit"+i; - String testsetFolderPath = "Import\\New Test Set Folder\\nunit"+i; - long start = System.currentTimeMillis(); - service.UploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); - long end = System.currentTimeMillis(); - System.out.println("total time:" + (end -start)); - } - - public static void main(String[] argc) throws Exception{ - testJunit(109); - //testtestNG(107); - //testnunit(108); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/results/service/junitResult.xml b/src/test/java/com/hp/application/automation/tools/results/service/junitResult.xml deleted file mode 100644 index d20ce28d63..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/service/junitResult.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - C:\QC\Jenkins\workspace\test1\prog1prj1\output\TEST-prog1prj1.TestProg1Prj1Test1.xml - prog1prj1.TestProg1Prj1Test1 - - - 0.064 - 2015-05-12T12:23:27 - - - 0.002 - prog1prj1.TestProg1Prj1Test1 - testMethod1 - false - 0 - - - 0.001 - prog1prj1.TestProg1Prj1Test1 - testMethod2 - false - 0 - - - 0.061 - prog1prj1.TestProg1Prj1Test1 - testMethod3 - false - junit.framework.AssertionFailedError: Not yet implemented - at prog1prj1.TestProg1Prj1Test1.testMethod3(Unknown Source) - - Not yet implemented - 0 - - - - - 0.064 - false - \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/service/testng-results.xml b/src/test/java/com/hp/application/automation/tools/results/service/testng-results.xml deleted file mode 100644 index 885daef19c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/results/service/testng-results.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/java/com/hp/application/automation/tools/sse/common/ConsoleLogger.java b/src/test/java/com/hp/application/automation/tools/sse/common/ConsoleLogger.java deleted file mode 100644 index 729a1857cd..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/common/ConsoleLogger.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.common; - -import com.hp.application.automation.tools.sse.sdk.Logger; - -public class ConsoleLogger implements Logger { - - @Override - public void log(String message) { - - System.out.println(message); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/common/RestClient4Test.java b/src/test/java/com/hp/application/automation/tools/sse/common/RestClient4Test.java deleted file mode 100644 index 24f7df66ad..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/common/RestClient4Test.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.common; - -import com.hp.application.automation.tools.rest.RestClient; - -public class RestClient4Test extends RestClient { - private final static String AUTH_INFO_FRONT = ""; - private final static String AUTH_INFO_BACK = ""; - - public RestClient4Test(String url, String domain, String project, String username) { - super(url, domain, project, username); - } - - public byte[] getExpectAuthInfo() { - - String authInfo = AUTH_INFO_FRONT + getUsername() + AUTH_INFO_BACK; - - return authInfo.getBytes(); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientPC.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientPC.java deleted file mode 100644 index aeba865b7b..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientPC.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import java.net.HttpURLConnection; -import java.util.Map; - -import com.hp.application.automation.tools.sse.common.RestClient4Test; - -public class MockRestClientPC extends RestClient4Test { - - public MockRestClientPC(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { - - Response ret = new Response(); - if (url.contains("rest/is-authenticated")) { - ret = new Response(null, getExpectAuthInfo(), null, HttpURLConnection.HTTP_OK); - } else if (url.contains("runs/")) { - ret.setData("12013-04-0931N/A9RuntimeOperations/RunStart.aspx?pcRunID=363&qcRunID=42sa15:52:53NRun Failure421009AdhocRun_2013-04-09 15:52:51N1_4252013-04-09 15:52:5141722013-04-09 15:52:53hp.pc.run.performance-testN0".getBytes()); - } - ret.setStatusCode(200); - - return ret; - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - Response ret = new Response(); - if (url.contains("startrun")) { - ret.setData("11005".getBytes()); - } - ret.setStatusCode(201); - - return ret; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockSseModel.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/MockSseModel.java deleted file mode 100644 index 83b9909f7c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockSseModel.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.model.ProxySettings; -import com.hp.application.automation.tools.model.SecretContainer; -import com.hp.application.automation.tools.model.SecretContainerTest; -import com.hp.application.automation.tools.model.SseModel; - -public class MockSseModel extends SseModel { - - public MockSseModel( - String almServerName, - String almUserName, - String almPassword, - String almDomain, - String almProject, - String runType, - String almEntityId, - String timeslotDuration, - String description, - String postRunAction, - String environmentConfigurationId, - CdaDetails cdaDetails, - ProxySettings proxySettings) { - - super( - almServerName, - almUserName, - almPassword, - almDomain, - almProject, - runType, - almEntityId, - timeslotDuration, - description, - postRunAction, - environmentConfigurationId, - cdaDetails, - null); - } - - @Override - protected SecretContainer setPassword(String almPassword) { - - SecretContainer secretContainer = new SecretContainerTest(); - secretContainer.initialize(almPassword); - - return secretContainer; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestBvsRunHandler.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestBvsRunHandler.java deleted file mode 100644 index 3f99529283..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestBvsRunHandler.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - -import java.net.HttpURLConnection; -import java.util.Map; - -/** - * @author Effi Bar-She'an - */ -@Ignore -@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607"}) -public class TestBvsRunHandler extends TestCase { - - @Test - public void testStart() { - - Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); - Response response = - new RunHandlerFactory().create(client, "BVS", ENTITY_ID).start( - DURATION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - null); - Assert.assertTrue(response.isOk()); - } - - private class MockRestStartClient extends RestClient4Test { - - public MockRestStartClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } - - @Test - public void testStop() { - - Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); - Response response = new RunHandlerFactory().create(client, "BVS", "23").stop(); - Assert.assertTrue(response.isOk()); - } - - @Test - public void testReportUrl() { - - RunHandler handler = - new RunHandlerFactory().create( - new RestClient(URL, DOMAIN, PROJECT, USER), - "BVS", - "1001"); - handler.setRunId("1"); - Assert.assertTrue(String.format( - "%s/webui/alm/%s/%s/lab/index.jsp?processRunId=1", - URL, - DOMAIN, - PROJECT).equals( - handler.getReportUrl(createArgs()))); - - } - - private class MockRestStopClient extends RestClient4Test { - - public MockRestStopClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPCRunHandler.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPCRunHandler.java deleted file mode 100644 index b28aa04d5a..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPCRunHandler.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; -import org.junit.Assert; -import org.junit.Test; - -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Map; - -/** - * @author Effi Bar-She'an - * @author Dani Schreiber - */ -@SuppressWarnings({"squid:S2699","squid:S3658"}) -public class TestPCRunHandler extends TestCase { - - @Test - public void testStart() { - - Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); - Response response = - new RunHandlerFactory().create(client, "PC", ENTITY_ID).start( - DURATION, - POST_RUN_ACTION, - "", - null); - Assert.assertTrue(response.isOk()); - } - - private class MockRestStartClient extends RestClient4Test { - - public MockRestStartClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } - - @Test - public void testStop() { - - Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); - Response response = new RunHandlerFactory().create(client, "PC", "23").stop(); - Assert.assertTrue(response.isOk()); - } - - @Test - public void testReportUrl() { - RunHandler handler = - new RunHandlerFactory().create( - new RestClient(URL, DOMAIN, PROJECT, USER), - "PC", - "1001"); - handler.setRunId("1"); - - try { - Assert.assertTrue(String.format( - "td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", - PROJECT, - DOMAIN, - new URL(URL).getHost(), - "1").equals( - handler.getReportUrl(createArgs()))); - } catch (MalformedURLException e) { - Assert.fail(); - } - - } - - private class MockRestStopClient extends RestClient4Test { - - public MockRestStopClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPostRequest.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPostRequest.java deleted file mode 100644 index 1e55309c47..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPostRequest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.StringUtils; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.request.PostRequest; - -@SuppressWarnings("squid:S2699") -public class TestPostRequest extends TestCase { - - @Test - public void testPostRequestException() { - - Response response = - new MockPostRequest(new MockRestClientPostRequestException( - URL, - DOMAIN, - PROJECT, - USER), RUN_ID).execute(); - Assert.assertTrue(PostRequestException.class.equals(response.getFailure().getClass())); - } - - private class MockRestClientPostRequestException extends RestClient4Test { - - public MockRestClientPostRequestException( - String url, - String domain, - String project, - String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost( - String url, - byte[] data, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - throw new PostRequestException(); - } - } - - private class PostRequestException extends NullPointerException { - - private static final long serialVersionUID = 1L; - - } - - private class MockPostRequest extends PostRequest { - - protected MockPostRequest(Client client, String runId) { - - super(client, runId); - } - - @Override - protected String getSuffix() { - - return StringUtils.EMPTY_STRING; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestAuthenticator.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestAuthenticator.java deleted file mode 100644 index a8229bdaa2..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestAuthenticator.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import java.net.HttpURLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.sse.common.ConsoleLogger; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; - -@SuppressWarnings("squid:S2698") -public class TestRestAuthenticator extends TestCase { - - @Test - public void testLogin_alreadyAuthenticated() { - - Client client = new MockRestClientAlreadyAuthenticated(URL, DOMAIN, PROJECT, USER); - boolean ok = new RestAuthenticator().login(client, "tester", "blabla", new ConsoleLogger()); - Assert.assertTrue(ok); - } - - public class MockRestClientAlreadyAuthenticated extends RestClient4Test { - - public MockRestClientAlreadyAuthenticated( - String url, - String domain, - String project, - String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, getExpectAuthInfo(), null, HttpURLConnection.HTTP_OK); - } - } - - @Test - public void testLogin_notAuthenticated() { - - Client client = new MockRestClientNotAuthenticated(URL, DOMAIN, PROJECT, USER); - boolean ok = new RestAuthenticator().login(client, "tester", "blabla", new ConsoleLogger()); - Assert.assertTrue(ok); - } - - public class MockRestClientNotAuthenticated extends RestClient4Test { - - private int _time = 0; - private final String _isAuthenticatedUrl; - private final String _authenticationUrl; - - private MockRestClientNotAuthenticated( - String url, - String domain, - String project, - String username) { - - super(url, domain, project, username); - _isAuthenticatedUrl = build(RestAuthenticator.IS_AUTHENTICATED); - _authenticationUrl = build("authentication-point/authenticate"); - } - - @Override - public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { - - Response ret = null; - if (++_time == 1) { - Assert.assertEquals(_isAuthenticatedUrl, url); - ret = - new Response( - getAuthenticationHeaders(), - null, - null, - HttpURLConnection.HTTP_UNAUTHORIZED); - } else if (_time == 2) { - Assert.assertEquals(_authenticationUrl, url); - ret = new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - Assert.assertTrue("More than 2 calls to httpGet", _time < 3); - - return ret; - } - - private Map> getAuthenticationHeaders() { - - Map> ret = new HashMap>(1); - List values = new ArrayList(); - values.add(String.format("LWSSO realm=\"%s\"", build("authentication-point"))); - ret.put(RestAuthenticator.AUTHENTICATE_HEADER, values); - - return ret; - } - } - - @Test - public void testLogin_failedToLogin() { - - Client client = new MockRestClientFailedToLogin(URL, DOMAIN, PROJECT, USER); - boolean ok = new RestAuthenticator().login(client, "tester", "blabla", new ConsoleLogger()); - Assert.assertFalse(ok); - } - - public class MockRestClientFailedToLogin extends RestClient4Test { - - private int _time = 0; - private final String _isAuthenticatedUrl; - private final String _authenticationUrl; - - private MockRestClientFailedToLogin( - String url, - String domain, - String project, - String username) { - - super(url, domain, project, username); - _isAuthenticatedUrl = build(RestAuthenticator.IS_AUTHENTICATED); - _authenticationUrl = build("authentication-point/authenticate"); - } - - @Override - public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { - - Response ret = null; - if (++_time == 1) { - Assert.assertEquals(_isAuthenticatedUrl, url); - ret = - new Response( - getAuthenticationHeaders(), - null, - null, - HttpURLConnection.HTTP_UNAUTHORIZED); - } else if (_time == 2) { - Assert.assertEquals(_authenticationUrl, url); - ret = new Response(null, null, null, HttpURLConnection.HTTP_UNAUTHORIZED); - } - Assert.assertTrue("More than 2 calls to httpGet", _time < 3); - - return ret; - } - - private Map> getAuthenticationHeaders() { - - Map> ret = new HashMap>(1); - List values = new ArrayList(); - values.add(String.format("LWSSO realm=\"%s\"", build("authentication-point"))); - ret.put(RestAuthenticator.AUTHENTICATE_HEADER, values); - - return ret; - } - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestClient.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestClient.java deleted file mode 100644 index 491f0fb68e..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRestClient.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.common.TestCase; - -@SuppressWarnings("squid:S2699") -public class TestRestClient extends TestCase { - - @Test - public void testBuild() { - - final String SUFFIX = "mysuffix"; - String url = new RestClient(URL, null, null, USER).build(SUFFIX); - - Assert.assertEquals(String.format("%s/%s", URL, SUFFIX), url); - } - - @Test - public void testBuildRequest() { - - final String SUFFIX = "mysuffix"; - String url = new RestClient(URL, DOMAIN, PROJECT, USER).buildRestRequest(SUFFIX); - - Assert.assertEquals( - String.format("%s/rest/domains/%s/projects/%s/%s", URL, DOMAIN, PROJECT, SUFFIX), - url); - } - - @Test - public void testBuildRequestWithSlash() { - final String URL = "http://16.55.245.168:8081/qcbin/"; - final String SUFFIX = "mysuffix"; - String url = new RestClient(URL, DOMAIN, PROJECT, USER).buildRestRequest(SUFFIX); - - Assert.assertEquals( - String.format("%srest/domains/%s/projects/%s/%s", URL, DOMAIN, PROJECT, SUFFIX), - url); - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunHandlerFactory.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunHandlerFactory.java deleted file mode 100644 index 03c9da4910..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunHandlerFactory.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.common.SSEException; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.BvsRunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; -import com.hp.application.automation.tools.sse.sdk.handler.TestSetRunHandler; - -@SuppressWarnings("squid:S2699") -public class TestRunHandlerFactory extends TestCase { - - @Test - public void testRunHandlerBVS() { - - RunHandler runHandler = - new RunHandlerFactory().create(new MockRestClientFunctional( - URL, - DOMAIN, - PROJECT, - USER), SseModel.BVS, "1001"); - Assert.assertNotNull(runHandler); - Assert.assertTrue(runHandler.getClass() == BvsRunHandler.class); - } - - @Test - public void testRunHandlerTestSet() { - - RunHandler runHandler = - new RunHandlerFactory().create(new MockRestClientFunctional( - URL, - DOMAIN, - PROJECT, - USER), SseModel.TEST_SET, "1001"); - Assert.assertNotNull(runHandler); - Assert.assertTrue(runHandler.getClass() == TestSetRunHandler.class); - } - - @Test(expected = SSEException.class) - public void testRunHandlerUnrecognized() { - - new RunHandlerFactory().create( - new MockRestClientFunctional(URL, DOMAIN, PROJECT, USER), - "Custom", - "1001"); - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManager.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManager.java deleted file mode 100644 index 395d157c0a..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManager.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.ArgsFactory; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; -import com.hp.application.automation.tools.sse.result.model.junit.Testcase; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; - -@SuppressWarnings({"squid:S2698","squid:S2699"}) -public class TestRunManager extends TestCase { - - @Test - public void testEndToEndBVS() throws InterruptedException { - - SseModel model = createBvsModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFunctional( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNotNull(testsuites); - Assert.assertTrue(verifyTestsuitesFunctional(testsuites, "bvs")); - } - - @Test - public void testEndToEndBVSWithCDA() throws InterruptedException { - - SseModel model = createBvsModelWithCDA(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFunctional( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - Assert.assertNotNull(testsuites); - Assert.assertTrue(verifyTestsuitesFunctional(testsuites, "bvs")); - } - - @Test - public void testEndToEndBVSWithEmptyCDA() throws InterruptedException { - - SseModel model = createBvsModelWithEmptyCDA(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFunctional( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - Assert.assertNotNull(testsuites); - Assert.assertTrue(verifyTestsuitesFunctional(testsuites, "bvs")); - } - - @Test - public void testEndToEndTestSet() throws InterruptedException { - - SseModel model = createTestSetModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFunctional( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNotNull(testsuites); - Assert.assertTrue(verifyTestsuitesFunctional(testsuites, "testset")); - } - - @Test - public void testEndToEndPC() throws InterruptedException { - - SseModel model = createPCModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientPC( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNotNull(testsuites); - Assert.assertTrue(verifyTestsuitesPC(testsuites, "testset")); - } - - @Test - public void testBadRunEntity() throws InterruptedException { - - SseModel model = createBvsModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientBadRunEntity( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - RunManager runManager = new RunManager(); - Testsuites testsuites = runManager.execute(connection, args, new ConsoleLogger()); - - Assert.assertNull(testsuites); - - } - - @Test - public void testLoginFailed() throws InterruptedException { - - SseModel model = createBvsModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFailedLogin( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNull(testsuites); - } - - @Test - public void testBadDomain() throws InterruptedException { - - SseModel model = createBvsModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientFailedLogin( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNull(testsuites); - } - - @Test - public void testBadRunResponse() { - - SseModel model = createTestSetModel(); - model.setAlmServerUrl(URL); - Args args = new ArgsFactory().create(model); - RestClient connection = - new MockRestClientBadRunResponse( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - boolean thrown = false; - try { - new RunManager().execute(connection, args, new ConsoleLogger()); - } catch (Throwable cause) { - thrown = true; - } - - Assert.assertTrue(thrown); - } - - private MockSseModel createBvsModel() { - - return new MockSseModel( - SERVERNAME, - USER, - PASS, - DOMAIN, - PROJECT, - "BVS", - "1041", - DURATION, - DESCRIPTION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - null, - null); - } - - private MockSseModel createBvsModelWithCDA() { - - return new MockSseModel( - SERVERNAME, - USER, - PASS, - DOMAIN, - PROJECT, - "BVS", - "1041", - DURATION, - DESCRIPTION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - CDA_DETAILS, - null); - } - - private MockSseModel createBvsModelWithEmptyCDA() { - - return new MockSseModel( - SERVERNAME, - USER, - PASS, - DOMAIN, - PROJECT, - "BVS", - "1041", - DURATION, - DESCRIPTION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - new CdaDetails("", "", ""), - null); - } - - private MockSseModel createTestSetModel() { - - return new MockSseModel( - SERVERNAME, - USER, - PASS, - DOMAIN, - PROJECT, - "TEST_SET", - "1041", - DURATION, - DESCRIPTION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - null, - null); - } - - private MockSseModel createPCModel() { - - return new MockSseModel( - SERVERNAME, - USER, - PASS, - DOMAIN, - PROJECT, - "PC", - "1041", - DURATION, - DESCRIPTION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - null, - null); - } - - private boolean verifyTestsuitesFunctional(Testsuites testsuites, String runType) { - - boolean ret = true; - Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); - ret = - (testcase.getStatus().equals(JUnitTestCaseStatus.PASS)) - && (testcase.getName().equals("vapi1 (Test instance run ID: 7)")) - && (testcase.getClassname().equals(String.format( - "%s1 (RunId:1005).testset1", - runType))) && (testcase.getTime().equals("0.0")); - - return ret; - } - - private boolean verifyTestsuitesPC(Testsuites testsuites, String runType) { - - boolean ret = true; - Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); - ret = - (testcase.getStatus().equals("error")) - && (testcase.getName().equals("Unnamed test (No test instance run ID)")) - && (testcase.getClassname().equals("PC Test ID: 5, Run ID: 42, Test Set ID: 1.(Unnamed test set)")) - && (testcase.getTime().equals("0.0")); - - return ret; - } -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java deleted file mode 100644 index 438971f566..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.model.SseModel; -import com.hp.application.automation.tools.rest.RestClient; -import com.hp.application.automation.tools.sse.ArgsFactory; -import com.hp.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; -import com.hp.application.automation.tools.sse.result.model.junit.Testcase; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; - -/** - * - * @author Amir Zahavi - * - */ -@Ignore -@SuppressWarnings("squid:S2699") -public class TestRunManagerSystemTests { - - private static final String SERVER_NAME = "zahavia1.emea.hpqcorp.net"; - private static final int PORT = 8080; - private static final String PROJECT = "Project1"; - private static int TEST_SET_ID = 2; - private static int BVS_ID = 1084; - - @Test - public void testEndToEndTestSet() throws InterruptedException { - - SseModel model = createModel(SseModel.TEST_SET, SERVER_NAME, PROJECT, PORT, TEST_SET_ID); - Args args = new ArgsFactory().create(model); - RestClient connection = - new RestClient( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - assertTestsuitesPassed(testsuites); - } - - @Test - public void testEndToEndBVS() throws InterruptedException { - - SseModel model = createModel(SseModel.BVS, SERVER_NAME, PROJECT, PORT, BVS_ID); - Args args = new ArgsFactory().create(model); - RestClient connection = - new RestClient( - args.getUrl(), - args.getDomain(), - args.getProject(), - args.getUsername()); - Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); - - Assert.assertNotNull(testsuites); - assertTestsuitesPassed(testsuites); - } - - private void assertTestsuitesPassed(Testsuites testsuites) { - - Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); - Assert.assertNotNull(testcase); - Assert.assertTrue( - "Test did not run successfully", - testcase.getStatus().equals(JUnitTestCaseStatus.PASS)); - } - - /** - * - * @param entityType - * "BVS" or "TEST_SET" - */ - private SseModel createModel( - String entityType, - String serverName, - String projectName, - int port, - int testSetID) { - - final String userName = "sa"; - String description = ""; - final String password = ""; - String domain = "DEFAULT"; - String timeslotDuration = "30"; - String postRunAction = "Collate"; - String environmentConfigurationId = ""; - CdaDetails cdaDetails = null; - SseModel ret = - new MockSseModel( - serverName, - userName, - password, - domain, - projectName, - entityType, - String.valueOf(testSetID), - timeslotDuration, - description, - postRunAction, - environmentConfigurationId, - cdaDetails, - null); - ret.setAlmServerUrl(String.format("http://%s:%d/qcbin", serverName, port)); - - return ret; - } - -} diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandler.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandler.java deleted file mode 100644 index 430a271401..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - -import java.net.HttpURLConnection; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; -import com.hp.application.automation.tools.sse.sdk.handler.TestSetRunHandler; - -/** - * @author Effi Bar-She'an - */ -@SuppressWarnings("squid:S2699") -public class TestTestSetRunHandler extends TestCase { - - @Test - public void testStart() { - - Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); - Response response = - new RunHandlerFactory().create(client, "TEST_SET", ENTITY_ID).start( - DURATION, - POST_RUN_ACTION, - ENVIRONMENT_CONFIGURATION_ID, - null); - Assert.assertTrue(response.isOk()); - } - - private class MockRestStartClient extends RestClient4Test { - - public MockRestStartClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } - - @Test - public void testStop() { - - Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); - Response response = new TestSetRunHandler(client, "23").stop(); - Assert.assertTrue(response.isOk()); - } - - private class MockRestStopClient extends RestClient4Test { - - public MockRestStopClient(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, null, null, HttpURLConnection.HTTP_OK); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java b/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java deleted file mode 100644 index 666bff7a0c..0000000000 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - */ - -package com.hp.application.automation.tools.sse.sdk; - - -import java.net.HttpURLConnection; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; - -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandler; -import com.hp.application.automation.tools.sse.sdk.handler.RunHandlerFactory; - -/** - * @author Effi Bar-She'an - */ -@SuppressWarnings("squid:S2699") -public class TestTestSetRunHandlerGetReportUrl extends TestCase { - - private static final String _dataFormat = "\n" + - "12.50.39 (Patch 1)\n" + - "%s\n" + - "%s\n" + - "0\n" + - "1\n" + - "1\n" + - ""; - - @Test - public void testBuildNewUrl() { - - RunHandler runHandler = new RunHandlerFactory().create(new MockClient(URL, DOMAIN, PROJECT, USER, String.format(_dataFormat, "12", "5")), "TEST_SET", ENTITY_ID); - runHandler.setRunId(RUN_ID); - String url = runHandler.getReportUrl(createArgs()); - Assert.assertTrue(String.format("URL does not contains ui. URL: %s", url), url.contains("/ui/")); - Assert.assertTrue(String.format("URL does not ends with Run ID: %s, URL: %s", RUN_ID, url) , url.endsWith(RUN_ID)); - } - - @Test - public void testBuildOldUrl() { - - RunHandler runHandler = new RunHandlerFactory().create(new MockClient(URL, DOMAIN, PROJECT, USER, String.format(_dataFormat, "12", "0")), "TEST_SET", ENTITY_ID); - runHandler.setRunId(RUN_ID); - String url = runHandler.getReportUrl(createArgs()); - Assert.assertTrue(String.format("URL does not contains webui. URL: %s", url), url.contains("/webui/")); - Assert.assertTrue(String.format("URL does not ends with Run ID: %s, URL: %s", RUN_ID, url) , url.endsWith(RUN_ID)); - } - - @Test - public void testBuildHttpCallThrowsException() { - - RunHandler runHandler = new RunHandlerFactory().create(new MockClientThrowsException(URL, DOMAIN, PROJECT, USER), "TEST_SET", ENTITY_ID); - runHandler.setRunId(RUN_ID); - Assert.assertEquals("NA", runHandler.getReportUrl(createArgs())); - } - - private class MockClient extends RestClient4Test { - - private final String _data; - - public MockClient(String url, String domain, String project, String username, String data) { - - super(url, domain, project, username); - _data = data; - } - - @Override - public Response httpGet( - String url, - String queryString, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - return new Response(null, _data.getBytes(), null, HttpURLConnection.HTTP_OK); - } - } - - private class MockClientThrowsException extends RestClient4Test { - - public MockClientThrowsException(String url, String domain, String project, String username) { - - super(url, domain, project, username); - } - - @Override - public Response httpGet( - String url, - String queryString, - Map headers, - ResourceAccessLevel resourceAccessLevel) { - - throw new RuntimeException("catch me if you can :)"); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/common/HealthAnalyzerCommonTest.java b/src/test/java/com/microfocus/application/automation/tools/common/HealthAnalyzerCommonTest.java new file mode 100644 index 0000000000..a4ceac35a0 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/common/HealthAnalyzerCommonTest.java @@ -0,0 +1,142 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +import com.microfocus.application.automation.tools.common.utils.HealthAnalyzerCommon; +import com.microfocus.application.automation.tools.common.utils.OperatingSystem; +import hudson.AbortException; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.microfocus.application.automation.tools.common.OperatingSystemTest.initializeOperatingSystemOs; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.fail; + +public class HealthAnalyzerCommonTest { + private final static String DUMMY_PRODUCT_NAME = "productName"; + private final static String NON_EXISTING_REGISTRY = "non\\existing\\registry\\value"; + private static HealthAnalyzerCommon healthAnalyzerCommon; + private static String os; + + @BeforeClass + public static void setup() { + healthAnalyzerCommon = new HealthAnalyzerCommon(DUMMY_PRODUCT_NAME); + os = System.getProperty("os.name"); + } + + @After + public void tearDown() throws Exception { + initializeOperatingSystemOs(os); + } + + @Test + public void isCheckedPerformWindowsInstallationCheck_throwsException_ifValueDoesNotExistsAndToCheckIsTrue() + throws Exception { + boolean returnValue = healthAnalyzerCommon.isRegistryExist(NON_EXISTING_REGISTRY); + assertEquals("Operating system mismatch", false, returnValue); + } + + @Test + public void runningMethodOnNonWindows_throwsException() throws Exception { + initializeOperatingSystemOs("Linux"); + boolean returnValue = healthAnalyzerCommon.isRegistryExist(NON_EXISTING_REGISTRY); + assertEquals("Operating system mismatch", false, returnValue); + initializeOperatingSystemOs(System.getProperty("os.name")); + } + + @Test + public void runningMethodOnWindowsWhenRegistryNotExists_throwsException() throws Exception { + if (OperatingSystem.isWindows()) { + boolean returnValue = healthAnalyzerCommon.isRegistryExist(NON_EXISTING_REGISTRY); + assertEquals("Operating system mismatch", false, returnValue); + } + } + + @Test + public void isRegistryExists_shouldReturnTrue_ifValueExists() throws Exception { + if (OperatingSystem.isWindows()) { + String existingRegistryValue = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"; + try { + healthAnalyzerCommon.isRegistryExist(existingRegistryValue); + } catch (AbortException e) { + fail("Should not have thrown AbortException"); + } + } + } + + @Test + public void ifCheckedPerformFilesExistenceCheck_throwsException_ifFileDoesNotExist() throws Exception { + String file = "C:\\non\\existing\\jenkins\\plugin\\path"; + boolean returnValue = healthAnalyzerCommon.isFileExist(file); + assertEquals("Operating system mismatch", false, returnValue); + } + + @Test(expected = AbortException.class) + public void ifCheckedPerformFilesExistenceCheck_throwsException_ifDirectory() throws Exception { + if (OperatingSystem.isWindows()) { + String file = "C:\\Users"; + healthAnalyzerCommon.isFileExist(file); + } + } + + @Test + public void ifCheckedPerformFilesExistenceCheck_notThrowing_ifFileExist() { + String file = null; + + if (OperatingSystem.isWindows()) { + file = "C:\\Windows\\regedit.exe"; + } else if (OperatingSystem.isMac()) { + file = "//bin"; + } else if (OperatingSystem.isLinux()) { + file = "//proc"; + } + + try { + healthAnalyzerCommon.isFileExist(file); + } catch (AbortException e) { + fail("Should not have thrown AbortException: The file doesn't exist"); + } + } + + @Test + public void ifCheckedPerformFilesExistenceCheck_shouldReturnTrue_ifNoFilesExist() { + try { + healthAnalyzerCommon.isFileExist(null); + String file = ""; + healthAnalyzerCommon.isFileExist(file); + } catch (AbortException e) { + fail("Should not have thrown AbortException"); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/common/OperatingSystemTest.java b/src/test/java/com/microfocus/application/automation/tools/common/OperatingSystemTest.java new file mode 100644 index 0000000000..4f47e3546b --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/common/OperatingSystemTest.java @@ -0,0 +1,128 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +import com.microfocus.application.automation.tools.common.utils.OperatingSystem; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import static junit.framework.TestCase.assertEquals; + +public class OperatingSystemTest { + private static String os; + + public static void initializeOperatingSystemOs(final String os) throws NoSuchFieldException, IllegalAccessException { + changeStaticFinalField(os, "os"); + + if (os.toLowerCase().contains("windows")) { + setAllBooleanStaticFinalFields(true, false, false); + } else if (os.toLowerCase().contains("linux")) { + setAllBooleanStaticFinalFields(false, false, true); + } else if (os.toLowerCase().contains("mac")) { + setAllBooleanStaticFinalFields(false, true, false); + } else { + setAllBooleanStaticFinalFields(false, false, false); + } + } + + private static void setAllBooleanStaticFinalFields(boolean isWindows, boolean isMac, boolean isLinux) + throws NoSuchFieldException, IllegalAccessException { + changeBooleanStaticFinalField(isWindows, "windows"); + changeBooleanStaticFinalField(isMac, "mac"); + changeBooleanStaticFinalField(isLinux, "linux"); + } + + private static void changeStaticFinalField(String value, String declaredField) + throws NoSuchFieldException, IllegalAccessException { + Field field = OperatingSystem.class.getDeclaredField(declaredField); + field.setAccessible(true); + Field modifiers = Field.class.getDeclaredField("modifiers"); + modifiers.setAccessible(true); + modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, value.toLowerCase()); + } + + private static void changeBooleanStaticFinalField(boolean value, String declaredField) + throws NoSuchFieldException, IllegalAccessException { + Field field = OperatingSystem.class.getDeclaredField(declaredField); + field.setAccessible(true); + Field modifiers = Field.class.getDeclaredField("modifiers"); + modifiers.setAccessible(true); + modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, value); + } + + @BeforeClass + public static void setup() { + os = System.getProperty("os.name"); + } + + + @AfterClass + public static void tearDown() throws Exception { + initializeOperatingSystemOs(os); + } + + + @Test + public void equalsCurrentOs_windows() throws NoSuchFieldException, IllegalAccessException { + initializeOperatingSystemOs("Windows 7"); + Assert.assertTrue(OperatingSystem.WINDOWS.equalsCurrentOs()); + } + + @Test + public void equalsCurrentOs_linux() throws NoSuchFieldException, IllegalAccessException { + String os = "Linux"; + initializeOperatingSystemOs(os); + assertEquals("Operating system should be " + os, true, OperatingSystem.isLinux()); + } + + @Test + public void equalsCurrentOs_mac() throws NoSuchFieldException, IllegalAccessException { + String os = "Mac OS X"; + initializeOperatingSystemOs(os); + assertEquals("Operating system should be " + os, true, OperatingSystem.isMac()); + } + + @Test + public void equalsCurrentOs_invalidOsReturnsFalse() throws NoSuchFieldException, IllegalAccessException { + String os = "Invalid OS"; + initializeOperatingSystemOs("Invalid OS"); + assertEquals("Operating system should be " + os, false, OperatingSystem.isWindows()); + } +} \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/common/TestALMRESTVersionUtils.java b/src/test/java/com/microfocus/application/automation/tools/common/TestALMRESTVersionUtils.java new file mode 100644 index 0000000000..bf451126f8 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/common/TestALMRESTVersionUtils.java @@ -0,0 +1,64 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.common; + +import com.microfocus.application.automation.tools.model.ALMVersion; +import org.junit.Assert; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; + +/** + * @author Effi Bar-She'an + */ +@SuppressWarnings("squid:S2699") +public class TestALMRESTVersionUtils { + + @Test + public void testToModel() throws UnsupportedEncodingException { + + final String MAJOR = "12"; + final String MINOR = "5"; + final String _dataFormat = "\n" + + "12.50.39 (Patch 1)\n" + + "%s\n" + + "%s\n" + + "0\n" + + "1\n" + + "1\n" + + ""; + ALMVersion version = ALMRESTVersionUtils.toModel(String.format(_dataFormat, MAJOR, MINOR).getBytes("UTF-8")); + Assert.assertEquals(MAJOR, version.getMajorVersion()); + Assert.assertEquals(MINOR, version.getMinorVersion()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/model/SecretContainerTest.java b/src/test/java/com/microfocus/application/automation/tools/model/SecretContainerTest.java new file mode 100644 index 0000000000..0db7b4a31d --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/model/SecretContainerTest.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.model; + +public class SecretContainerTest implements SecretContainer { + + private String _secret; + + public void initialize(String secret) { + + _secret = secret; + } + + @Override + public String toString() { + + return _secret; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/EnumsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/EnumsTest.java new file mode 100644 index 0000000000..06bcd960b1 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/EnumsTest.java @@ -0,0 +1,126 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.hp.octane.integrations.dto.causes.CIEventCauseType; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.scm.SCMType; +import com.hp.octane.integrations.dto.snapshots.CIBuildResult; +import com.hp.octane.integrations.dto.snapshots.CIBuildStatus; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 21:32 + * To change this template use File | Settings | File Templates. + */ +@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) +public class EnumsTest { + + @Test + public void testCIEventCauseType() { + assertEquals(CIEventCauseType.values().length, 5); + assertEquals(CIEventCauseType.SCM.value(), "scm"); + assertEquals(CIEventCauseType.USER.value(), "user"); + assertEquals(CIEventCauseType.TIMER.value(), "timer"); + assertEquals(CIEventCauseType.UPSTREAM.value(), "upstream"); + assertEquals(CIEventCauseType.UNDEFINED.value(), "undefined"); + assertEquals(CIEventCauseType.fromValue("scm"), CIEventCauseType.SCM); + } + + @Test + public void testCIEventType() { + assertEquals(CIEventType.values().length, 9); + assertEquals(CIEventType.QUEUED.value(), "queued"); + assertEquals(CIEventType.SCM.value(), "scm"); + assertEquals(CIEventType.STARTED.value(), "started"); + assertEquals(CIEventType.FINISHED.value(), "finished"); + assertEquals(CIEventType.fromValue("queued"), CIEventType.QUEUED); + assertEquals(CIEventType.DELETED.value(),"deleted" ); + assertEquals(CIEventType.RENAMED.value(),"renamed" ); + assertEquals(CIEventType.REMOVED_FROM_QUEUE.value(),"removed_from_queue" ); + assertEquals(CIEventType.CHANGE_EXEC_STATE.value(),"change_exec_state" ); + + } + + @Test + public void testParameterType() { + assertEquals(CIParameterType.values().length, 7); + assertEquals(CIParameterType.UNKNOWN.value(), "unknown"); + assertEquals(CIParameterType.PASSWORD.value(), "password"); + assertEquals(CIParameterType.BOOLEAN.value(), "boolean"); + assertEquals(CIParameterType.STRING.value(), "string"); + assertEquals(CIParameterType.NUMBER.value(), "number"); + assertEquals(CIParameterType.FILE.value(), "file"); + assertEquals(CIParameterType.AXIS.value(), "axis"); + assertEquals(CIParameterType.fromValue("unavailable"), CIParameterType.UNKNOWN); + } + + @Test + public void testSnapshotResult() { + assertEquals(CIBuildResult.values().length, 5); + assertEquals(CIBuildResult.UNAVAILABLE.value(), "unavailable"); + assertEquals(CIBuildResult.UNSTABLE.value(), "unstable"); + assertEquals(CIBuildResult.ABORTED.value(), "aborted"); + assertEquals(CIBuildResult.FAILURE.value(), "failure"); + assertEquals(CIBuildResult.SUCCESS.value(), "success"); + assertEquals(CIBuildResult.fromValue("unavailable"), CIBuildResult.UNAVAILABLE); + } + + @Test + public void testSnapshotStatus() { + assertEquals(CIBuildStatus.values().length, 4); + assertEquals(CIBuildStatus.UNAVAILABLE.value(), "unavailable"); + assertEquals(CIBuildStatus.QUEUED.value(), "queued"); + assertEquals(CIBuildStatus.RUNNING.value(), "running"); + assertEquals(CIBuildStatus.FINISHED.value(), "finished"); + assertEquals(CIBuildStatus.fromValue("unavailable"), CIBuildStatus.UNAVAILABLE); + } + + @Test + public void testSCMType() { + assertEquals(SCMType.values().length, 6); + assertEquals(SCMType.UNKNOWN.value(), "unknown"); + assertEquals(SCMType.GIT.value(), "git"); + assertEquals(SCMType.SVN.value(), "svn"); + assertEquals(SCMType.STARTEAM.value(), "starteam"); + assertEquals(SCMType.ACCUREV.value(), "accurev"); + assertEquals(SCMType.DIMENSIONS_CM.value(), "dimensions_cm"); + assertEquals(SCMType.fromValue("unknown"), SCMType.UNKNOWN); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/OctanePluginTestBase.java b/src/test/java/com/microfocus/application/automation/tools/octane/OctanePluginTestBase.java new file mode 100644 index 0000000000..e71095fd75 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/OctanePluginTestBase.java @@ -0,0 +1,68 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import hudson.util.Secret; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.jvnet.hudson.test.JenkinsRule; + +import java.util.UUID; + +public abstract class OctanePluginTestBase { + protected static final DTOFactory dtoFactory = DTOFactory.getInstance(); + protected static String instanceId; + protected static String ssp; + + @ClassRule + public static final JenkinsRule rule = new JenkinsRule(); + public static final JenkinsRule.WebClient client = rule.createWebClient(); + + @BeforeClass + public static void init() { + + instanceId = UUID.randomUUID().toString(); + ssp = UUID.randomUUID().toString(); + + OctaneServerSettingsModel model = new OctaneServerSettingsModel( + "http://localhost:8008/ui/?p=" + ssp, + "username", + Secret.fromString("password"), + ""); + model.setIdentity(instanceId); + ConfigurationService.configurePlugin(model); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/OctaneServerMock.java b/src/test/java/com/microfocus/application/automation/tools/octane/OctaneServerMock.java new file mode 100644 index 0000000000..a81a26d7ce --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/OctaneServerMock.java @@ -0,0 +1,185 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane; + +import com.microfocus.application.automation.tools.octane.events.EventsTest; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.AbstractHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.GZIPInputStream; + +/** + * Purpose of this class is to provide Octane Server Mock for the tests of the Octane Plugin + * The server will run on port that will be taken from configuration or default + * The server will serve ALL of the tests, so each suite should carefully configure it to respond ot itself an not mess up with other suites + */ + +public final class OctaneServerMock { + private static final Logger logger = Logger.getLogger(EventsTest.class.getName()); + private static final OctaneServerMock INSTANCE = new OctaneServerMock(); + + private final int DEFAULT_TESTING_SERVER_PORT = 9999; + private int testingServerPort = DEFAULT_TESTING_SERVER_PORT; + private boolean isRunning = false; + + private final List testSpecificHandlers = new LinkedList<>(); + + private OctaneServerMock() { + logger.log(Level.INFO, "starting initialization..."); + String p = System.getProperty("testingServerPort"); + try { + if (p != null) { + testingServerPort = Integer.parseInt(p); + } + } catch (NumberFormatException nfe) { + logger.log(Level.WARNING, "bad port number found in the system properties, default port will be used"); + } + + try { + Server server = new Server(testingServerPort); + server.setHandler(new OctaneServerMockHandler()); + server.start(); + isRunning = true; + logger.log(Level.INFO, "SUCCESSFULLY started, listening on port " + testingServerPort); + } catch (Throwable t) { + logger.log(Level.SEVERE, "FAILED to start", t); + } + } + + public static OctaneServerMock getInstance() { + return INSTANCE; + } + + public boolean isRunning() { + return isRunning; + } + + public int getPort() { + return testingServerPort; + } + + public void addTestSpecificHandler(TestSpecificHandler testSpecificHandler) { + if (testSpecificHandler == null) { + throw new IllegalArgumentException("test specific handler for Octane Mock Server MUST NOT be null"); + } + + testSpecificHandlers.add(testSpecificHandler); + } + + public void removeTestSpecificHandler(TestSpecificHandler testSpecificHandler) { + testSpecificHandlers.remove(testSpecificHandler); + } + + abstract public static class TestSpecificHandler extends AbstractHandler { + abstract public boolean ownsUrlToProcess(String url); + + protected String getBodyAsString(Request request) throws IOException { + StringBuilder body = new StringBuilder(); + byte[] buffer = new byte[1024]; + int len; + + GZIPInputStream gzip = new GZIPInputStream(request.getInputStream()); + while ((len = gzip.read(buffer, 0, 1024)) > 0) { + body.append(new String(buffer, 0, len)); + } + + return body.toString(); + } + } + + private final class OctaneServerMockHandler extends AbstractHandler { + + @Override + public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException { + logger.log(Level.INFO, "accepted request " + request.getMethod() + " " + request.getPathInfo()); + for (TestSpecificHandler testSpecificHandler : testSpecificHandlers) { + if (testSpecificHandler.ownsUrlToProcess(request.getPathInfo())) { + logger.log(Level.INFO, request.getMethod() + " " + request.getPathInfo() + " picked up by " + testSpecificHandler); + testSpecificHandler.handle(s, request, httpServletRequest, response); + request.setHandled(true); + break; + } + } + if (!request.isHandled()) { + logger.log(Level.INFO, "none of test specific handlers matched for " + request.getMethod() + " " + request.getPathInfo()); + if (request.getMethod().equals("POST") && request.getPathInfo().equals("/authentication/sign_in")) { + logger.log(Level.INFO, "found POST 'authentication/sign_in' request, will respond with default Mock handler"); + response.setStatus(HttpServletResponse.SC_OK); + response.addCookie(new Cookie("LWSSO_COOKIE_KEY", "some_dummy_security_token")); + request.setHandled(true); + } else if (request.getMethod().equals("GET") && request.getPathInfo().endsWith("tasks")) { + defaultGetTasksHandler(request, response); + } else if (request.getMethod().equals("GET") && request.getPathInfo().startsWith("/internal-api/shared_spaces/") && request.getPathInfo().endsWith("/workspaceId")) { + defaultGetWorkspaceFoLogsHandler(request, response); + } else if (request.getMethod().equals("GET") && request.getPathInfo().endsWith("connectivity/status")) { + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write("{\"octaneVersion\":\"15.1.20.9999\",\"supportedSdkVersion\":\"1.4.17\"}"); + response.getWriter().flush(); + response.getWriter().close(); + request.setHandled(true); + } else { + logger.info("will respond with 200 and empty content"); + response.setStatus(HttpServletResponse.SC_OK); + request.setHandled(true); + } + } + } + + private void defaultGetTasksHandler(Request request, HttpServletResponse response) { + logger.log(Level.INFO, "found GET 'tasks' request, will respond with default Mock handler"); + try { + Thread.sleep(10 * 1000); + } catch (InterruptedException ie) { + logger.log(Level.FINE, "interrupted while delaying default GET tasks response"); + } + response.setStatus(HttpServletResponse.SC_OK); + request.setHandled(true); + } + + private void defaultGetWorkspaceFoLogsHandler(Request request, HttpServletResponse response) { + logger.log(Level.INFO, "found GET 'workspaceId' for build logs request, will respond with default Mock handler"); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + request.setHandled(true); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/Configuration.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/Configuration.java new file mode 100644 index 0000000000..f6cfa995b2 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/Configuration.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 12:05 + * To change this template use File | Settings | File Templates. + */ + +public class Configuration { + public static enum OS { + WINDOWS("windows"), + LINUX("linux"); + + private String value; + private static OS current; + + private OS(String v) { + value = v; + } + + public static OS getCurrent() { + String tmpVal; + if (current == null) { + tmpVal = System.getProperty("os.name").toLowerCase(); + if (tmpVal.indexOf("windows") == 0) current = WINDOWS; + else if (tmpVal.indexOf("linux") == 0) current = LINUX; + else current = LINUX; + } + return current; + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/Utils.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/Utils.java new file mode 100644 index 0000000000..79a9bac7fe --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/Utils.java @@ -0,0 +1,70 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions; + +import hudson.model.AbstractProject; +import hudson.tasks.BatchFile; +import hudson.tasks.CommandInterpreter; +import hudson.tasks.Shell; +import org.jvnet.hudson.test.JenkinsRule; +import org.xml.sax.SAXException; + +import java.io.IOException; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 13:55 + * To change this template use File | Settings | File Templates. + */ + +public class Utils { + public static CommandInterpreter getSleepScript(int seconds) { + if (Configuration.OS.getCurrent() == Configuration.OS.WINDOWS) { + return new BatchFile("ping -n " + seconds + " 127.0.0.1 >nul"); + } else if (Configuration.OS.getCurrent() == Configuration.OS.LINUX) { + return new Shell("sleep " + seconds); + } else { + return null; + } + } + + public static void buildProject(JenkinsRule.WebClient client, AbstractProject project) throws IOException, SAXException { + client.goTo("job/" + project.getName() + "/build", ""); + } + + public static void buildProjectWithParams(JenkinsRule.WebClient client, AbstractProject project, String params) throws IOException, SAXException { + client.goTo("job/" + project.getName() + "/buildWithParameters?" + params, ""); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/plugin/PluginActionsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/plugin/PluginActionsTest.java new file mode 100644 index 0000000000..cbdcb840c4 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/plugin/PluginActionsTest.java @@ -0,0 +1,168 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.plugin; + +import com.gargoylesoftware.htmlunit.Page; +import com.hp.octane.integrations.dto.general.CIJobsList; +import com.hp.octane.integrations.dto.general.CIProviderSummaryInfo; +import com.hp.octane.integrations.dto.general.CIServerTypes; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.actions.PluginActions; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.model.*; +import jenkins.model.Jenkins; +import org.junit.Ignore; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 07/01/15 + * Time: 22:09 + * To change this template use File | Settings | File Templates. + */ + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701", "squid:S3578", "squid:S2698"}) +public class PluginActionsTest extends OctanePluginTestBase { + + @Test + public void testPluginActionsMethods() { + PluginActions pluginActions = new PluginActions(); + assertNull(pluginActions.getIconFileName()); + assertNull(pluginActions.getDisplayName()); + assertEquals("nga", pluginActions.getUrlName()); + } + + @Ignore("temp ignore") + @Test + public void testPluginActions_REST_Status() throws IOException, SAXException { + Page page = client.goTo("nga/api/v1/status", "application/json"); + System.out.println(page.getWebResponse().getContentAsString()); + CIProviderSummaryInfo status = dtoFactory.dtoFromJson(page.getWebResponse().getContentAsString(), CIProviderSummaryInfo.class); + + assertNotNull(status); + + assertNotNull(status.getServer()); + assertEquals(CIServerTypes.JENKINS.value(), status.getServer().getType()); + assertEquals(Jenkins.VERSION, status.getServer().getVersion()); + assertEquals(rule.getInstance().getRootUrl(), status.getServer().getUrl() + "/"); + assertNotNull(status.getServer().getSendingTime()); + + assertNotNull(status.getPlugin()); + assertEquals(ConfigurationService.getPluginVersion(), status.getPlugin().getVersion()); + } + + @Test + public void testPluginActions_REST_Jobs_NoParams() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + + String taskUrl = "nga/api/v1/jobs"; + CIJobsList response = TestUtils.sendTask(taskUrl, CIJobsList.class); + + assertNotNull(response); + assertNotNull(response.getJobs()); + assertEquals(rule.getInstance().getTopLevelItemNames().size(), response.getJobs().length); + + rule.createFreeStyleProject(projectName); + response = TestUtils.sendTask(taskUrl, CIJobsList.class); + + assertNotNull(response); + assertNotNull(response.getJobs()); + for (PipelineNode ciJob : response.getJobs()) { + if (projectName.equals(ciJob.getName())) { + assertNotNull(ciJob.getParameters()); + assertEquals(0, ciJob.getParameters().size()); + } + } + } + + @Test + public void testPluginActions_REST_Jobs_WithParams() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject fsp; + + String taskUrl = "nga/api/v1/jobs"; + CIJobsList response = TestUtils.sendTask(taskUrl, CIJobsList.class); + + assertNotNull(response); + assertNotNull(response.getJobs()); + assertEquals(0, response.getJobs().length); + + fsp = rule.createFreeStyleProject(projectName); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), + (ParameterDefinition) new FileParameterDefinition("ParamC", "file param") + )); + fsp.addProperty(params); + response = TestUtils.sendTask(taskUrl, CIJobsList.class); + + assertNotNull(response); + assertNotNull(response.getJobs()); + assertEquals(1, response.getJobs().length); + assertEquals(projectName, response.getJobs()[0].getName()); + assertNotNull(response.getJobs()[0].getParameters()); + assertEquals(3, response.getJobs()[0].getParameters().size()); + + // Test ParamA + assertNotNull(response.getJobs()[0].getParameters().get(0)); + assertEquals("ParamA", response.getJobs()[0].getParameters().get(0).getName()); + assertEquals(CIParameterType.BOOLEAN, response.getJobs()[0].getParameters().get(0).getType()); + assertEquals("bool", response.getJobs()[0].getParameters().get(0).getDescription()); + assertEquals(true, response.getJobs()[0].getParameters().get(0).getDefaultValue()); + + // Test ParamB + assertNotNull(response.getJobs()[0].getParameters().get(1)); + assertEquals("ParamB", response.getJobs()[0].getParameters().get(1).getName()); + assertEquals(CIParameterType.STRING, response.getJobs()[0].getParameters().get(1).getType()); + assertEquals("string", response.getJobs()[0].getParameters().get(1).getDescription()); + assertEquals("str", response.getJobs()[0].getParameters().get(1).getDefaultValue()); + + // Test ParamC + assertNotNull(response.getJobs()[0].getParameters().get(2)); + assertEquals("ParamC", response.getJobs()[0].getParameters().get(2).getName()); + assertEquals(CIParameterType.FILE, response.getJobs()[0].getParameters().get(2).getType()); + assertEquals("file param", response.getJobs()[0].getParameters().get(2).getDescription()); + assertEquals("", response.getJobs()[0].getParameters().get(2).getDefaultValue()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/CustomProject.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/CustomProject.java new file mode 100644 index 0000000000..0949683a2a --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/CustomProject.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.project; + +import hudson.Extension; +import hudson.model.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 12/01/15 + * Time: 17:55 + * To change this template use File | Settings | File Templates. + */ + +@Extension +final public class CustomProject extends Project implements TopLevelItem { + + @Extension(ordinal = 1000) + public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); + + public static final class DescriptorImpl extends AbstractProject.AbstractProjectDescriptor { + public String getDisplayName() { + return "Custom Project"; + } + + public CustomProject newInstance(ItemGroup itemGroup, String name) { + return new CustomProject(itemGroup, name); + } + } + + public CustomProject() { + super(null, null); + } + + public CustomProject(ItemGroup group, String name) { + super(group, name); + } + + @Override + public TopLevelItemDescriptor getDescriptor() { + return DESCRIPTOR; + } + + @Override + protected Class getBuildClass() { + return FreeStyleBuild.class; + } +} \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginFreeStyleTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginFreeStyleTest.java new file mode 100644 index 0000000000..50138770c9 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginFreeStyleTest.java @@ -0,0 +1,338 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.project; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.matrix.MatrixProject; +import hudson.maven.MavenModuleSet; +import hudson.model.*; +import hudson.plugins.parameterizedtrigger.*; +import hudson.tasks.BuildTrigger; +import hudson.tasks.Fingerprinter; +import hudson.tasks.Shell; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 11:39 + * To change this template use File | Settings | File Templates. + */ +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701"}) +public class PluginFreeStyleTest extends OctanePluginTestBase { + // Structure test: free-style, no params, no children + // + @Test + public void testStructureFreeStyleNoParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + rule.createFreeStyleProject(projectName); + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(0, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + } + + // Structure test: free-style, with params, no children + // + @Test + public void testStructureFreeStyleWithParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject p = rule.createFreeStyleProject(projectName); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), + (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), + (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"one", "two", "three"}, "choice"), + (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") + )); + p.addProperty(params); + + CIParameter tmpParam; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(5, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(2); + assertEquals("ParamC", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("text", tmpParam.getDescription()); + assertEquals("txt", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(3); + assertEquals("ParamD", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("choice", tmpParam.getDescription()); + assertEquals("one", tmpParam.getDefaultValue()); + assertNotNull(tmpParam.getChoices()); + assertEquals(3, tmpParam.getChoices().length); + assertEquals("one", tmpParam.getChoices()[0]); + assertEquals("two", tmpParam.getChoices()[1]); + assertEquals("three", tmpParam.getChoices()[2]); + + tmpParam = pipeline.getParameters().get(4); + assertEquals("ParamE", tmpParam.getName()); + assertEquals(CIParameterType.FILE, tmpParam.getType()); + assertEquals("file param", tmpParam.getDescription()); + assertEquals("", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + } + + // Structure test: free-style, with params, with children + // + @Test + public void testStructureFreeStyleWithParamsWithChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject p = rule.createFreeStyleProject(projectName); + FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); + MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); + FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); + MavenModuleSet p4 = rule.createProject(MavenModuleSet.class, "jobD"); + CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") + )); + p.addProperty(params); + p.getBuildersList().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getBuildersList().add(new Shell("")); + p.getBuildersList().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB, jobE", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); + p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Collections.singletonList( + new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) + ))); + p.getPublishersList().add(new Fingerprinter("")); + + + CIParameter tmpParam; + List tmpPhases; + PipelineNode tmpNode; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(2, pipeline.getParameters().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + // Phases Internal + // + tmpPhases = pipeline.getPhasesInternal(); + assertEquals(4, tmpPhases.size()); + + // Phase 0 + assertEquals("", tmpPhases.get(0).getName()); + assertEquals(true, tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 2 + assertEquals("", tmpPhases.get(2).getName()); + assertEquals(true, tmpPhases.get(2).isBlocking()); + assertEquals(3, tmpPhases.get(2).getJobs().size()); + + tmpNode = tmpPhases.get(2).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(2).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(2).getJobs().get(2); + assertEquals("jobE", tmpNode.getJobCiId()); + assertEquals("jobE", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 3 + assertEquals("", tmpPhases.get(3).getName()); + assertEquals(false, tmpPhases.get(3).isBlocking()); + assertEquals(2, tmpPhases.get(3).getJobs().size()); + + tmpNode = tmpPhases.get(3).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(3).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phases Post build + // + tmpPhases = pipeline.getPhasesPostBuild(); + assertEquals(2, tmpPhases.size()); + + // Phase 0 + assertEquals("downstream", tmpPhases.get(0).getName()); + assertEquals(false, tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMatrixTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMatrixTest.java new file mode 100644 index 0000000000..f75be4b318 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMatrixTest.java @@ -0,0 +1,293 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.project; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.matrix.MatrixProject; +import hudson.maven.MavenModuleSet; +import hudson.model.*; +import hudson.plugins.parameterizedtrigger.*; +import hudson.tasks.BuildTrigger; +import hudson.tasks.Fingerprinter; +import hudson.tasks.Shell; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 11:41 + * To change this template use File | Settings | File Templates. + */ + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701"}) +public class PluginMatrixTest extends OctanePluginTestBase { + // Structure test: matrix, no params, no children + // + @Test + public void testStructureMatrixNoParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + rule.createProject(MatrixProject.class, projectName); + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(0, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + } + + // Structure test: matrix, with params, no children + // + @Test + public void testStructureMatrixWithParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MatrixProject p = rule.createProject(MatrixProject.class, projectName); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), + (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), + (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"1", "2", "3"}, "choice"), + (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") + )); + p.addProperty(params); + + CIParameter tmpParam; + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(5, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(2); + assertEquals("ParamC", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("text", tmpParam.getDescription()); + assertEquals("txt", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(3); + assertEquals("ParamD", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("choice", tmpParam.getDescription()); + assertEquals("1", tmpParam.getDefaultValue()); + assertNotNull(tmpParam.getChoices()); + assertEquals(3, tmpParam.getChoices().length); + assertEquals("1", tmpParam.getChoices()[0]); + assertEquals("2", tmpParam.getChoices()[1]); + assertEquals("3", tmpParam.getChoices()[2]); + + tmpParam = pipeline.getParameters().get(4); + assertEquals("ParamE", tmpParam.getName()); + assertEquals(CIParameterType.FILE, tmpParam.getType()); + assertEquals("file param", tmpParam.getDescription()); + assertEquals("", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + } + + // Structure test: matrix, with params, with children + // + @Test + public void testStructureMatrixWithParamsWithChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MatrixProject p = rule.createProject(MatrixProject.class, projectName); + FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); + MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); + FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); + MavenModuleSet p4 = rule.createProject(MavenModuleSet.class, "jobD"); + CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") + )); + p.addProperty(params); + p.getBuildersList().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getBuildersList().add(new Shell("")); + p.getPublishersList().add(new Fingerprinter("")); + p.getPublishersList().add(new BuildTrigger("jobA, jobB, JobE", Result.SUCCESS)); + p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( + new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) + ))); + + List tmpPhases; + PipelineNode tmpNode; + CIParameter tmpParam; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(2, pipeline.getParameters().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + // Phases Internal + // + tmpPhases = pipeline.getPhasesInternal(); + assertEquals(2, tmpPhases.size()); + + // Phase 0 + assertEquals("", tmpPhases.get(0).getName()); + assertEquals(true, tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phases Post build + // + tmpPhases = pipeline.getPhasesPostBuild(); + assertEquals(2, tmpPhases.size()); + + // Phase 0 + assertEquals("downstream", tmpPhases.get(0).getName()); + assertEquals(false, tmpPhases.get(0).isBlocking()); + assertEquals(3, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(2); + assertEquals("jobE", tmpNode.getJobCiId()); + assertEquals("jobE", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMavenTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMavenTest.java new file mode 100644 index 0000000000..f0dd34f1d7 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMavenTest.java @@ -0,0 +1,348 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.project; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.matrix.MatrixProject; +import hudson.maven.MavenModuleSet; +import hudson.model.*; +import hudson.plugins.parameterizedtrigger.*; +import hudson.tasks.BuildTrigger; +import hudson.tasks.Fingerprinter; +import hudson.tasks.Shell; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 11:42 + * To change this template use File | Settings | File Templates. + */ + +public class PluginMavenTest extends OctanePluginTestBase { + // Structure test: maven, no params, no children + @Test + public void testStructureMavenNoParamsNoChildren() throws IOException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); + project.runHeadless(); + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(0, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + } + + @Test + public void testDoRun() throws IOException, InterruptedException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + int retries = 0; + MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); + p.runHeadless(); + + String taskUrl = "nga/api/v1/jobs/" + projectName + "/run"; + TestUtils.sendTask(taskUrl, null); + + while ((p.getLastBuild() == null || p.getLastBuild().isBuilding()) && ++retries < 20) { + Thread.sleep(1000); + } + assertEquals(p.getBuilds().toArray().length, 1); + } + + @Test + public void testStructureMavenWithParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); + p.runHeadless(); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), + (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), + (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"one", "two", "three"}, "choice"), + (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") + )); + p.addProperty(params); + + + CIParameter tmpParam; + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(5, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(2); + assertEquals("ParamC", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("text", tmpParam.getDescription()); + assertEquals("txt", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(3); + assertEquals("ParamD", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("choice", tmpParam.getDescription()); + assertEquals("one", tmpParam.getDefaultValue()); + assertNotNull(tmpParam.getChoices()); + assertEquals(3, tmpParam.getChoices().length); + assertEquals("one", tmpParam.getChoices()[0]); + assertEquals("two", tmpParam.getChoices()[1]); + assertEquals("three", tmpParam.getChoices()[2]); + + tmpParam = pipeline.getParameters().get(4); + assertEquals("ParamE", tmpParam.getName()); + assertEquals(CIParameterType.FILE, tmpParam.getType()); + assertEquals("file param", tmpParam.getDescription()); + assertEquals("", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + } + + // Structure test: maven, with params, with children + // + @Test + public void testStructureMavenWithParamsWithChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet p = rule.createProject(MavenModuleSet.class, projectName); + p.runHeadless(); + FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); + MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); + FreeStyleProject p3 = rule.createFreeStyleProject("jobC"); + MatrixProject p4 = rule.createProject(MatrixProject.class, "jobD"); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") + )); + p.addProperty(params); + p.getPrebuilders().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC, jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getPrebuilders().add(new Shell("")); + p.getPostbuilders().add(new Shell("")); + p.getPostbuilders().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC, jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); + p.getPublishersList().add(new Fingerprinter("")); + p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Arrays.asList( + new BuildTriggerConfig("jobC, jobD", ResultCondition.ALWAYS, false, null) + ))); + + List tmpPhases; + PipelineNode tmpNode; + CIParameter tmpParam; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(2, pipeline.getParameters().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + // Phases Internal + // + tmpPhases = pipeline.getPhasesInternal(); + assertEquals(4, tmpPhases.size()); + + // Phase 0 + assertEquals("pre-maven", tmpPhases.get(0).getName()); + assertEquals(true, tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("pre-maven", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 2 + assertEquals("post-maven", tmpPhases.get(2).getName()); + assertEquals(true, tmpPhases.get(2).isBlocking()); + assertEquals(2, tmpPhases.get(2).getJobs().size()); + + tmpNode = tmpPhases.get(2).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(2).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 3 + assertEquals("post-maven", tmpPhases.get(3).getName()); + assertEquals(false, tmpPhases.get(3).isBlocking()); + assertEquals(2, tmpPhases.get(3).getJobs().size()); + + tmpNode = tmpPhases.get(3).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(3).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phases Post build + // + tmpPhases = pipeline.getPhasesPostBuild(); + assertEquals(2, tmpPhases.size()); + + // Phase 0 + assertEquals("downstream", tmpPhases.get(0).getName()); + assertEquals(false, tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertEquals(false, tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMultiJobTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMultiJobTest.java new file mode 100644 index 0000000000..11ea515687 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/actions/project/PluginMultiJobTest.java @@ -0,0 +1,359 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.actions.project; + +import com.hp.octane.integrations.dto.parameters.CIParameter; +import com.hp.octane.integrations.dto.parameters.CIParameterType; +import com.hp.octane.integrations.dto.pipelines.PipelineNode; +import com.hp.octane.integrations.dto.pipelines.PipelinePhase; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import com.tikal.jenkins.plugins.multijob.MultiJobBuilder; +import com.tikal.jenkins.plugins.multijob.MultiJobProject; +import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig; +import hudson.matrix.MatrixProject; +import hudson.model.*; +import hudson.plugins.parameterizedtrigger.*; +import hudson.tasks.BuildTrigger; +import hudson.tasks.Fingerprinter; +import hudson.tasks.Shell; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 11:44 + * To change this template use File | Settings | File Templates. + */ + +public class PluginMultiJobTest extends OctanePluginTestBase { + // Structure test: multi-job, no params, no children + @Test + public void testStructureMultiJobNoParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + rule.getInstance().createProject(MultiJobProject.class, projectName); + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(0, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + } + + // Structure test: multi-job, with params, no children + // + @Test + public void testStructureMultiJobWithParamsNoChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MultiJobProject p = rule.getInstance().createProject(MultiJobProject.class, projectName); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string"), + (ParameterDefinition) new TextParameterDefinition("ParamC", "txt", "text"), + (ParameterDefinition) new ChoiceParameterDefinition("ParamD", new String[]{"A", "B", "C"}, "choice"), + (ParameterDefinition) new FileParameterDefinition("ParamE", "file param") + )); + p.addProperty(params); + + CIParameter tmpParam; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(5, pipeline.getParameters().size()); + assertEquals(0, pipeline.getPhasesInternal().size()); + assertEquals(0, pipeline.getPhasesPostBuild().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(2); + assertEquals("ParamC", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("text", tmpParam.getDescription()); + assertEquals("txt", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(3); + assertEquals("ParamD", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("choice", tmpParam.getDescription()); + assertEquals("A", tmpParam.getDefaultValue()); + assertNotNull(tmpParam.getChoices()); + assertEquals(3, tmpParam.getChoices().length); + assertEquals("A", tmpParam.getChoices()[0]); + assertEquals("B", tmpParam.getChoices()[1]); + assertEquals("C", tmpParam.getChoices()[2]); + + tmpParam = pipeline.getParameters().get(4); + assertEquals("ParamE", tmpParam.getName()); + assertEquals(CIParameterType.FILE, tmpParam.getType()); + assertEquals("file param", tmpParam.getDescription()); + assertEquals("", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + } + + // Structure test: multi-job, with params, with children + // + @Test + public void testStructureMultiJobWithParamsWithChildren() throws IOException, SAXException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MultiJobProject p = rule.getInstance().createProject(MultiJobProject.class, projectName); + FreeStyleProject p1 = rule.createFreeStyleProject("jobA"); + MatrixProject p2 = rule.createProject(MatrixProject.class, "jobB"); + MultiJobProject p3 = rule.getInstance().createProject(MultiJobProject.class, "jobC"); + MatrixProject p4 = rule.createProject(MatrixProject.class, "jobD"); + CustomProject p5 = rule.getInstance().createProject(CustomProject.class, "jobE"); + ParametersDefinitionProperty params = new ParametersDefinitionProperty(Arrays.asList( + (ParameterDefinition) new BooleanParameterDefinition("ParamA", true, "bool"), + (ParameterDefinition) new StringParameterDefinition("ParamB", "str", "string") + )); + p.addProperty(params); + p.getBuildersList().add(new TriggerBuilder(Arrays.asList( + new BlockableBuildTriggerConfig("jobA, jobB", new BlockingBehaviour( + Result.FAILURE, + Result.UNSTABLE, + Result.FAILURE + ), Arrays.asList(new AbstractBuildParameters[0])), + new BlockableBuildTriggerConfig("jobC,jobD", null, Arrays.asList(new AbstractBuildParameters[0])) + ))); + p.getBuildersList().add(new MultiJobBuilder( + "Build", + //PhaseJobsConfig(String jobName, String jobAlias, String jobProperties, boolean currParams, List configs, + // PhaseJobsConfig.KillPhaseOnJobResultCondition killPhaseOnJobResultCondition, boolean disableJob, boolean enableRetryStrategy, + // String parsingRulesPath, int maxRetries, boolean enableCondition, boolean abortAllJob, String condition, boolean buildOnlyIfSCMChanges, + // boolean applyConditionOnlyIfNoSCMChanges) { + Arrays.asList( + createPhaseJobsConfig("jobA"), + createPhaseJobsConfig("jobB"), + createPhaseJobsConfig("jobE") + ), + MultiJobBuilder.ContinuationCondition.SUCCESSFUL, + MultiJobBuilder.ExecutionType.SEQUENTIALLY + )); + p.getBuildersList().add(new Shell("")); + p.getBuildersList().add(new MultiJobBuilder( + "Test", + Arrays.asList( + createPhaseJobsConfig("jobC"), + createPhaseJobsConfig("jobD") + ), + MultiJobBuilder.ContinuationCondition.SUCCESSFUL, + MultiJobBuilder.ExecutionType.SEQUENTIALLY + )); + p.getPublishersList().add(new BuildTrigger("jobA, jobB", Result.SUCCESS)); + p.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(Collections.singletonList( + new BuildTriggerConfig("jobC,jobD", ResultCondition.ALWAYS, false, null) + ))); + p.getPublishersList().add(new Fingerprinter("")); + + List tmpPhases; + PipelineNode tmpNode; + CIParameter tmpParam; + + String taskUrl = "nga/api/v1/jobs/" + projectName; + PipelineNode pipeline = TestUtils.sendTask(taskUrl, PipelineNode.class); + assertEquals(projectName, pipeline.getJobCiId()); + assertEquals(projectName, pipeline.getName()); + assertEquals(2, pipeline.getParameters().size()); + + tmpParam = pipeline.getParameters().get(0); + assertEquals("ParamA", tmpParam.getName()); + assertEquals(CIParameterType.BOOLEAN, tmpParam.getType()); + assertEquals("bool", tmpParam.getDescription()); + assertEquals(true, tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + tmpParam = pipeline.getParameters().get(1); + assertEquals("ParamB", tmpParam.getName()); + assertEquals(CIParameterType.STRING, tmpParam.getType()); + assertEquals("string", tmpParam.getDescription()); + assertEquals("str", tmpParam.getDefaultValue()); + assertNull(tmpParam.getChoices()); + + // Phases Internal + // + tmpPhases = pipeline.getPhasesInternal(); + assertEquals(4, tmpPhases.size()); + + // Phase 0 + assertEquals("", tmpPhases.get(0).getName()); + assertTrue(tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertFalse(tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 2 + assertEquals("Build", tmpPhases.get(2).getName()); + assertTrue(tmpPhases.get(2).isBlocking()); + assertEquals(3, tmpPhases.get(2).getJobs().size()); + + tmpNode = tmpPhases.get(2).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(2).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(2).getJobs().get(2); + assertEquals("jobE", tmpNode.getJobCiId()); + assertEquals("jobE", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 3 + assertEquals("Test", tmpPhases.get(3).getName()); + assertTrue(tmpPhases.get(3).isBlocking()); + assertEquals(2, tmpPhases.get(3).getJobs().size()); + + tmpNode = tmpPhases.get(3).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(3).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phases Post build + // + tmpPhases = pipeline.getPhasesPostBuild(); + assertEquals(2, tmpPhases.size()); + + // Phase 0 + assertEquals("downstream", tmpPhases.get(0).getName()); + assertFalse(tmpPhases.get(0).isBlocking()); + assertEquals(2, tmpPhases.get(0).getJobs().size()); + + tmpNode = tmpPhases.get(0).getJobs().get(0); + assertEquals("jobA", tmpNode.getJobCiId()); + assertEquals("jobA", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(0).getJobs().get(1); + assertEquals("jobB", tmpNode.getJobCiId()); + assertEquals("jobB", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + + // Phase 1 + assertEquals("", tmpPhases.get(1).getName()); + assertFalse(tmpPhases.get(1).isBlocking()); + assertEquals(2, tmpPhases.get(1).getJobs().size()); + + tmpNode = tmpPhases.get(1).getJobs().get(0); + assertEquals("jobC", tmpNode.getJobCiId()); + assertEquals("jobC", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + tmpNode = tmpPhases.get(1).getJobs().get(1); + assertEquals("jobD", tmpNode.getJobCiId()); + assertEquals("jobD", tmpNode.getName()); + assertEquals(0, tmpNode.getParameters().size()); + assertEquals(0, tmpNode.getPhasesInternal().size()); + assertEquals(0, tmpNode.getPhasesPostBuild().size()); + } + + private PhaseJobsConfig createPhaseJobsConfig(String jobName){ + return new PhaseJobsConfig(jobName, "", null, false, null, + PhaseJobsConfig.KillPhaseOnJobResultCondition.NEVER, false, false, null, 1, + false, false, null, false, false); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigApiTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigApiTest.java new file mode 100644 index 0000000000..bd8b816721 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigApiTest.java @@ -0,0 +1,162 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.HttpMethod; +import com.gargoylesoftware.htmlunit.Page; +import com.gargoylesoftware.htmlunit.WebRequest; +import com.gargoylesoftware.htmlunit.html.HtmlForm; +import com.gargoylesoftware.htmlunit.html.HtmlPage; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import hudson.util.Secret; +import net.jcip.annotations.NotThreadSafe; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.UUID; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701", "squid:S2698"}) +@NotThreadSafe +@Ignore("temporary ignore till sonar issue is fixed") +public class ConfigApiTest extends OctanePluginTestBase { + + @Before + public void initTest() throws Exception { + HtmlPage configPage = client.goTo("configure"); + HtmlForm form = configPage.getFormByName("config"); + ssp = UUID.randomUUID().toString(); + form.getInputByName("_.uiLocation").setValueAttribute("http://localhost:8008/ui/?p=" + ssp + "/1002"); + form.getInputByName("_.username").setValueAttribute("username"); + form.getInputByName("_.password").setValueAttribute("password"); + rule.submit(form); + } + + + @Test + public void testRead() throws Exception { + Page page = client.goTo("nga/configuration/read", "application/json"); + String configsAsString = page.getWebResponse().getContentAsString(); + JSONArray configs = JSONObject.fromObject(configsAsString).getJSONArray("configurations"); + for (int i = 0; i < configs.size(); i++) { + JSONObject config = configs.getJSONObject(i); + Assert.assertEquals("http://localhost:8008", config.getString("location")); + Assert.assertEquals(ssp, config.getString("sharedSpace")); + Assert.assertEquals("username", config.getString("username")); + String instanceId = config.getString("serverIdentity"); + Assert.assertTrue(instanceId != null && !instanceId.isEmpty()); + } + } + + @Test + public void testSave() throws Exception { + // basic scenario: location, shared space and credentials + JSONObject config = new JSONObject(); + config.put("location", "http://localhost:8088"); + String sharedSP = UUID.randomUUID().toString(); + config.put("sharedSpace", sharedSP); + config.put("username", "username1"); + config.put("password", "password1"); + WebRequest req = new WebRequest(client.createCrumbedUrl("nga/configuration/save"), HttpMethod.POST); + req.setEncodingType(null); + req.setRequestBody(config.toString()); + Page page = client.getPage(req); + config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); + checkConfig(config, "http://localhost:8088", sharedSP, "username1", Secret.fromString("password1")); + + String instanceId = config.getString("serverIdentity"); + Assert.assertTrue(instanceId != null && !instanceId.isEmpty()); + + // location, shared space, no credentials + config = new JSONObject(); + config.put("location", "http://localhost:8888"); + String sharedSP1 = UUID.randomUUID().toString(); + config.put("sharedSpace", sharedSP1); + req.setRequestBody(config.toString()); + page = client.getPage(req); + config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); + checkConfig(config, "http://localhost:8888", sharedSP1, "", Secret.fromString("")); +// Assert.assertEquals(instanceId, config.getString("serverIdentity")); + + // location, shared space and username without password + config = new JSONObject(); + config.put("location", "http://localhost:8882"); + String sharedSP2 = UUID.randomUUID().toString(); + config.put("sharedSpace", sharedSP2); + config.put("username", "username3"); + config.put("password", "password3"); + req.setRequestBody(config.toString()); + page = client.getPage(req); + config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); + checkConfig(config, "http://localhost:8882", sharedSP2, "username3", Secret.fromString("password3")); +// Assert.assertEquals(instanceId, config.getString("serverIdentity")); + + // uiLocation and identity + config = new JSONObject(); + String sharedSP3 = UUID.randomUUID().toString(); + config.put("uiLocation", "http://localhost:8881/ui?p=" + sharedSP3 + "/1002"); +// config.put("serverIdentity", "2d2fa955-1d13-4d8c-947f-ab11c72bf850"); + req.setRequestBody(config.toString()); + page = client.getPage(req); + config = JSONObject.fromObject(page.getWebResponse().getContentAsString()); + checkConfig(config, "http://localhost:8881", sharedSP3, "", Secret.fromString("")); +// Assert.assertEquals("2d2fa955-1d13-4d8c-947f-ab11c72bf850", config.getString("serverIdentity")); + + // requires POST + req.setHttpMethod(HttpMethod.GET); + try { + client.getPage(req); + Assert.fail("Only POST should be allowed"); + } catch (FailingHttpStatusCodeException ex) { + // expected + } + } + + private void checkConfig(JSONObject config, String location, String sharedSpace, String username, Secret password) { + // check values returned + Assert.assertEquals(location, config.getString("location")); + Assert.assertEquals(sharedSpace, config.getString("sharedSpace")); + Assert.assertEquals(username, config.getString("username")); + // check values stored + OctaneServerSettingsModel serverConfiguration = ConfigurationService.getSettings(config.getString("serverIdentity")); + Assert.assertEquals(location, serverConfiguration.getLocation()); + Assert.assertEquals(sharedSpace, serverConfiguration.getSharedSpace()); + Assert.assertEquals(username, serverConfiguration.getUsername()); + Assert.assertEquals(password, serverConfiguration.getPassword()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java new file mode 100644 index 0000000000..e790c9de45 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationActionFactoryTest.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.octane.tests.ExtensionUtil; +import hudson.matrix.Axis; +import hudson.matrix.AxisList; +import hudson.matrix.MatrixConfiguration; +import hudson.matrix.MatrixProject; +import hudson.model.FreeStyleProject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +import java.io.IOException; + +public class ConfigurationActionFactoryTest { + + @ClassRule + static final public JenkinsRule jenkins = new JenkinsRule(); + + private ConfigurationActionFactory configurationActionFactory; + + @Before + public void initialize() { + configurationActionFactory = ExtensionUtil.getInstance(jenkins, ConfigurationActionFactory .class); + } + + @Test + public void testMatrixJob() throws IOException { + + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class, "ConfigurationActionFactoryTest.testMatrixJob"); + //jenkins.createMatrixProject("ConfigurationActionFactoryTest.testMatrixJob"); + matrixProject.setAxes(new AxisList(new Axis("OS", "Linux", "Windows"))); + + Assert.assertEquals(1, configurationActionFactory.createFor(matrixProject).size()); + for (MatrixConfiguration configuration: matrixProject.getItems()) { + Assert.assertEquals(0, configurationActionFactory.createFor(configuration).size()); + } + } + + @Test + public void testFreeStyleJob() throws IOException { + FreeStyleProject project = jenkins.createFreeStyleProject("ConfigurationActionFactoryTest.testFreeStyleJob"); + Assert.assertEquals(1, configurationActionFactory.createFor(project).size()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListenerTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListenerTest.java new file mode 100644 index 0000000000..3ebbccec96 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationListenerTest.java @@ -0,0 +1,113 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.ExtensionUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.jvnet.hudson.test.TestExtension; + +import java.util.ArrayList; +import java.util.List; + +public class ConfigurationListenerTest extends OctanePluginTestBase { + + private TestConfigurationListener listener; + + @Before + public void initialize() { + listener = ExtensionUtil.getInstance(rule, TestConfigurationListener.class); + Assert.assertEquals("Listener count doesn't match 1", 1, listener.getCount()); + + List confs = listener.getConfigurationsChange(); + Assert.assertNotNull("Configuration is null", confs); + Assert.assertEquals("Config size doesn't match 2", 2, confs.size()); + Assert.assertEquals("location doesn't match localhost:8008", "http://localhost:8008", confs.get(0).getLocation()); + Assert.assertEquals("username doesn't match username", "username", confs.get(0).getUsername()); + Assert.assertNull(confs.get(1)); + } + + @Test + public void testConfigurationListener() throws Exception { + OctaneServerSettingsModel oldModel = ConfigurationService.getAllSettings().get(0); + OctaneServerSettingsModel newModel = new OctaneServerSettingsModel(oldModel.getUiLocation(), oldModel.getUsername(), oldModel.getPassword(), ""); + newModel.setIdentity(oldModel.getIdentity()); + newModel.setLocation(oldModel.getUiLocation()); + newModel.setInternalId(oldModel.getInternalId()); + // not increased on re-submit + ConfigurationService.configurePlugin(newModel); + Assert.assertEquals("Listener count doesn't match 1", 1, listener.getCount()); + + oldModel = ConfigurationService.getAllSettings().get(0); + newModel = new OctaneServerSettingsModel(oldModel.getUiLocation(),"username2", oldModel.getPassword(), ""); + newModel.setIdentity(oldModel.getIdentity()); + newModel.setInternalId(oldModel.getInternalId()); + // increased when configuration changes + ConfigurationService.configurePlugin(newModel); + Assert.assertEquals("Listener count doesn't match 2", 2, listener.getCount()); + + List confs = listener.getConfigurationsChange(); + Assert.assertNotNull("Configuration is null", confs); + Assert.assertEquals("Config count doesn't match 2", 2, confs.size()); + Assert.assertEquals("http://localhost:8008", confs.get(0).getLocation()); + Assert.assertEquals("username2", confs.get(0).getUsername()); + Assert.assertEquals("http://localhost:8008", confs.get(1).getLocation()); + Assert.assertEquals("username", confs.get(1).getUsername()); + } + + @TestExtension + public static class TestConfigurationListener implements ConfigurationListener { + + private int count; + private List newAndOld; + + @Override + public void onChanged(OctaneServerSettingsModel newConf, OctaneServerSettingsModel oldConf) { + ++count; + newAndOld = new ArrayList<>(); + newAndOld.add(newConf); + newAndOld.add(oldConf); + } + + public int getCount() { + return count; + } + + public List getConfigurationsChange() { + return newAndOld; + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationServiceTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationServiceTest.java new file mode 100644 index 0000000000..74114d746d --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/configuration/ConfigurationServiceTest.java @@ -0,0 +1,215 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.configuration; + +import com.gargoylesoftware.htmlunit.html.*; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.Messages; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.OctaneServerMock; +import com.microfocus.application.automation.tools.octane.tests.ExtensionUtil; +import hudson.util.FormValidation; +import hudson.util.Secret; +import org.eclipse.jetty.server.Request; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.*; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701", "squid:S2698"}) +@Ignore("temporary ignore till sonar issue is fixed") +public class ConfigurationServiceTest extends OctanePluginTestBase { + private static final Logger logger = Logger.getLogger(ConfigurationServiceTest.class.getName()); + + private Secret password; + + @Before + public void initBefore() { + logger.log(Level.FINE, "initializing configuration for test"); + password = Secret.fromString("password"); + } + + @Test + public void testGetServerConfiguration() { + OctaneServerSettingsModel configuration = ConfigurationService.getAllSettings().get(0); +// assertEquals("http://localhost:8008", configuration.getLocation()); + assertEquals(OctanePluginTestBase.ssp, configuration.getSharedSpace()); + assertEquals("username", configuration.getUsername()); + assertEquals(password, configuration.getPassword()); + } + + @Test + public void testConfigManipulation() throws Exception { + HtmlPage configPage = client.goTo("configure"); + HtmlForm updateConfigForm = configPage.getFormByName("config"); + + + //update identity for existing server config + ((HtmlCheckBoxInput) updateConfigForm.getElementsByAttribute("input", "name", "showIdentity").get(0)).setChecked(true); + String newInstanceId = UUID.randomUUID().toString(); + OctaneServerSettingsModel oldModel = ConfigurationService.getSettings(instanceId); + String oldIdentity = oldModel.getIdentity(); + String oldModelInternalId = oldModel.getInternalId(); + ((HtmlInput) findInputText(updateConfigForm, "_.identity", instanceId)).setDefaultValue(newInstanceId); + + rule.submit(updateConfigForm); + OctaneServerSettingsModel newModel = ConfigurationService.getSettings(newInstanceId); + String newIdentity = newModel.getIdentity(); + String newModelInternalId = newModel.getInternalId(); + + assertEquals(newModelInternalId, oldModelInternalId); + assertNotEquals(oldIdentity, newIdentity); + assertEquals(newInstanceId, newIdentity); + + //add new configuration + configPage = client.goTo("configure"); + HtmlForm addConfigForm = configPage.getFormByName("config"); + HtmlElement addButton = findButton(addConfigForm, "Add ALM Octane server"); + configPage = (HtmlPage) HtmlElementUtil.click(addButton); + addConfigForm = configPage.getFormByName("config"); + + + ssp = UUID.randomUUID().toString(); + ((HtmlInput) findInputText(addConfigForm, "_.uiLocation", null)).setValueAttribute("http://localhost:8008/ui/?p=" + ssp + "/1002"); + ((HtmlInput) findInputText(addConfigForm, "_.username", null)).setValueAttribute("username"); + ((HtmlInput) findInputText(addConfigForm, "_.password", null)).setValueAttribute("password"); + + rule.submit(addConfigForm); + assertEquals(2, ConfigurationService.getAllSettings().size()); + + //remove configuration + configPage = client.goTo("configure"); + HtmlForm deleteConfigForm = configPage.getFormByName("config"); + HtmlElement deleteButton = findButton(deleteConfigForm, "Delete ALM Octane server"); + configPage = (HtmlPage) HtmlElementUtil.click(deleteButton); + deleteConfigForm = configPage.getFormByName("config"); + + rule.submit(deleteConfigForm); + assertEquals(1, ConfigurationService.getAllSettings().size()); + } + + + @Test + public void testConfigurationRoundTrip() throws Exception { + HtmlForm formIn = client.goTo("configure").getFormByName("config"); + HtmlForm formOut = client.goTo("configure").getFormByName("config"); + assertEquals(formIn.getInputByName("_.uiLocation").getValueAttribute(), formOut.getInputByName("_.uiLocation").getValueAttribute()); + assertEquals(formIn.getInputByName("_.username").getValueAttribute(), formOut.getInputByName("_.username").getValueAttribute()); + // NOTE: password is actually empty (bug or security feature?) + assertEquals(formIn.getInputByName("_.password").getValueAttribute(), formOut.getInputByName("_.password").getValueAttribute()); + } + + @Test + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + public void testCheckConfiguration() { + // prepare work with Octane Server Mock + OctaneServerMock serverMock = OctaneServerMock.getInstance(); + assertTrue(serverMock.isRunning()); + + ConfigurationTestHandler testHandler = new ConfigurationTestHandler(); + serverMock.addTestSpecificHandler(testHandler); + + // valid configuration + testHandler.desiredStatus = HttpServletResponse.SC_OK; + FormValidation validation = ConfigurationValidator.checkConfigurationAndWrapWithFormValidation("http://localhost:" + serverMock.getPort(), "1001", "username1", password); + assertEquals(FormValidation.Kind.OK, validation.kind); + assertTrue(validation.getMessage().contains("Connection successful")); + + // authentication failed + testHandler.desiredStatus = HttpServletResponse.SC_UNAUTHORIZED; + validation = ConfigurationValidator.checkConfigurationAndWrapWithFormValidation("http://localhost:" + serverMock.getPort(), "1001", "username1", password); + assertEquals(FormValidation.Kind.ERROR, validation.kind); + assertTrue(validation.getMessage().contains(Messages.AuthenticationFailure())); + + // authorization failed + testHandler.desiredStatus = HttpServletResponse.SC_FORBIDDEN; + validation = ConfigurationValidator.checkConfigurationAndWrapWithFormValidation("http://localhost:" + serverMock.getPort(), "1001", "username1", password); + assertEquals(FormValidation.Kind.ERROR, validation.kind); + assertTrue(validation.getMessage().contains(Messages.AuthorizationFailure())); + + // domain project does not exists + testHandler.desiredStatus = HttpServletResponse.SC_NOT_FOUND; + validation = ConfigurationValidator.checkConfigurationAndWrapWithFormValidation("http://localhost:" + serverMock.getPort(), "1001", "username1", password); + assertEquals(FormValidation.Kind.ERROR, validation.kind); + assertTrue(validation.getMessage().contains(Messages.ConnectionSharedSpaceInvalid())); + + serverMock.removeTestSpecificHandler(testHandler); + } + + private HtmlElement findButton(HtmlElement form, String buttonText) { + List list = new LinkedList<>(); + for (HtmlElement htmlElement : form.getElementsByTagName("button")) { + if (buttonText.equals(htmlElement.getFirstChild().asText())) { + list.add(htmlElement); + } + } + return list.size() > 0 ? list.get(0) : null; + } + + private HtmlElement findInputText(HtmlElement form, String inputName, String value) { + for (HtmlElement htmlElement : ((HtmlForm) form).getInputsByName(inputName)) + if (value == null || value.isEmpty()) { + if (htmlElement.getAttribute("value").isEmpty()) { + return htmlElement; + } + } else { + if (value.equals(htmlElement.getAttribute("value"))) { + return htmlElement; + } + } + return null; + } + + private static final class ConfigurationTestHandler extends OctaneServerMock.TestSpecificHandler { + private int desiredStatus = HttpServletResponse.SC_OK; + + @Override + public boolean ownsUrlToProcess(String url) { + return "/authentication/sign_in".equals(url); + } + + @Override + public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) { + response.setStatus(desiredStatus); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/detection/ResultFieldsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/detection/ResultFieldsTest.java new file mode 100644 index 0000000000..d79a37df3b --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/detection/ResultFieldsTest.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.detection; + +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFields; +import org.junit.Assert; +import org.junit.Test; + +public class ResultFieldsTest { + + @Test + public void testEquals() { + ResultFields x = new ResultFields("foo", "bar", null); + Assert.assertTrue(x.equals(x)); + Assert.assertTrue(!x.equals(null)); + + ResultFields y = new ResultFields("foo", "bar", null); + Assert.assertTrue(x.equals(y) && y.equals(x)); + Assert.assertTrue(x.hashCode() == y.hashCode()); + + ResultFields z = new ResultFields("foo", "bar", ""); + Assert.assertTrue(!x.equals(z) && !z.equals(x)); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/events/EventsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/events/EventsTest.java new file mode 100644 index 0000000000..6b2ffbfefa --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/events/EventsTest.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.events; + +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.events.CIEvent; +import com.hp.octane.integrations.dto.events.CIEventsList; +import com.hp.octane.integrations.services.WorkerPreflight; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.hp.octane.integrations.dto.events.CIEventType; +import com.microfocus.application.automation.tools.octane.OctaneServerMock; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import hudson.model.FreeStyleProject; +import hudson.util.Secret; +import org.eclipse.jetty.server.Request; +import org.junit.*; +import org.jvnet.hudson.test.JenkinsRule; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Logger; + +import static org.junit.Assert.*; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 13/01/15 + * Time: 22:05 + * To change this template use File | Settings | File Templates. + */ +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701", "squid:S2698"}) +public class EventsTest { + private static final Logger logger = Logger.getLogger(EventsTest.class.getName()); + private static final DTOFactory dtoFactory = DTOFactory.getInstance(); + + private static final String projectName = "root-job-events-case"; + private static final String sharedSpaceId = "1007"; + private static final String username = "some"; + private static final String password = "pass"; + private static final EventsTestHandler eventsTestHandler = new EventsTestHandler(); + + private static String instanceId; + + @ClassRule + public static final JenkinsRule rule = new JenkinsRule(); + + @BeforeClass + public static void beforeClass() { + // ensure server mock is up + OctaneServerMock serverMock = OctaneServerMock.getInstance(); + assertTrue(serverMock.isRunning()); + serverMock.addTestSpecificHandler(eventsTestHandler); + + // configure plugin for the server + OctaneServerSettingsModel model = new OctaneServerSettingsModel( + "http://127.0.0.1:" + serverMock.getPort() + "/ui?p=" + sharedSpaceId, + username, + Secret.fromString(password), + ""); + ConfigurationService.configurePlugin(model); + instanceId = model.getIdentity(); + } + + @Test + public void testEventsA() throws Exception { + FreeStyleProject p = rule.createFreeStyleProject(projectName); + + assertEquals(0, p.getBuilds().toArray().length); + p.scheduleBuild2(0); + while (p.getLastBuild() == null || p.getLastBuild().isBuilding()) { + Thread.sleep(1000); + } + assertEquals(1, p.getBuilds().toArray().length); + Thread.sleep(5000); + + List eventsOrder = new ArrayList<>(Arrays.asList(CIEventType.STARTED, CIEventType.FINISHED)); + CIEventsList eventsLists = eventsTestHandler.eventsLists; + logger.info(eventsLists.toString()); + logger.info("EVENTS TEST: server mock received " + eventsLists.getEvents().size() + " list/s of events"); + + assertNotNull(eventsLists.getServer()); + assertTrue(rule.getInstance().getRootUrl() != null && rule.getInstance().getRootUrl().startsWith(eventsLists.getServer().getUrl())); + assertEquals("jenkins", eventsLists.getServer().getType()); + assertEquals(instanceId, eventsLists.getServer().getInstanceId()); + + assertNotNull(eventsLists.getEvents()); + assertFalse(eventsLists.getEvents().isEmpty()); + for (CIEvent event : eventsLists.getEvents()) { + System.out.println(event.getEventType() + "-" + event.getProject() + "-" + event.getBuildCiId()); + if (projectName.equals(event.getProject())) { + assertEquals(eventsOrder.get(0), event.getEventType()); + eventsOrder.remove(0); + } + } + assertEquals(0, eventsOrder.size()); + } + + private static final class EventsTestHandler extends OctaneServerMock.TestSpecificHandler { + private final CIEventsList eventsLists = dtoFactory.newDTO(CIEventsList.class) + .setEvents(new LinkedList<>()); + + @Override + public boolean ownsUrlToProcess(String url) { + return ("/internal-api/shared_spaces/" + sharedSpaceId + "/analytics/ci/events").equals(url); + } + + @Override + public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { + String requestBody = getBodyAsString(baseRequest); + CIEventsList tmp = dtoFactory.dtoFromJson(requestBody, CIEventsList.class); + eventsLists.setServer(tmp.getServer()); + eventsLists.getEvents().addAll(tmp.getEvents()); + logger.info("EVENTS TEST: server mock events list length " + eventsLists.getEvents().size()); + response.setStatus(HttpServletResponse.SC_OK); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/identity/ServerIdentityTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/identity/ServerIdentityTest.java new file mode 100644 index 0000000000..19d20dae42 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/identity/ServerIdentityTest.java @@ -0,0 +1,49 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.identity; + +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import org.junit.Assert; +import org.junit.Test; + +public class ServerIdentityTest extends OctanePluginTestBase { + + @Test + public void testIdentity() { + ConfigurationService.getAllSettings().forEach(settings -> { + Assert.assertNotNull(settings.getIdentity()); + Assert.assertFalse(settings.getIdentity().isEmpty()); + }); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/model/WorkspaceJenkinsUserTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/model/WorkspaceJenkinsUserTest.java new file mode 100644 index 0000000000..f32b18710c --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/model/WorkspaceJenkinsUserTest.java @@ -0,0 +1,88 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.model; + +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationValidator; +import com.microfocus.application.automation.tools.octane.exceptions.AggregatedMessagesException; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +public class WorkspaceJenkinsUserTest { + + + @Test + public void testParseWorkspace2ImpersonatedUserConf() { + String payload = "1001:user1" + System.lineSeparator() + //legal line + "#1002:user2" + System.lineSeparator() + //comment line + "1003:user1003:user1004" + System.lineSeparator() + //Expected error : Workspace configuration is not valid, valid format is 'Workspace ID:jenkins user': 1003:user1003:user1004 + "user1004:1004" + System.lineSeparator() + //Expected error : Workspace configuration is not valid, workspace ID must be numeric: user1004:1004 + "abc:abc" + System.lineSeparator() + //Expected error : Workspace configuration is not valid, workspace ID must be numeric: abc:abc + "1005:" + System.lineSeparator() + //Expected error : Workspace configuration is not valid, user value is empty: 1005: + "1001:user1a" + System.lineSeparator() + //Expected error : Duplicated workspace configuration: 1001:user1a + + "1010:user10" + System.lineSeparator(); //legal line + + //iteration 1 - ignore errors + Map output = OctaneServerSettingsModel.parseWorkspace2ImpersonatedUserConf(payload, true); + Assert.assertEquals(3, output.size()); + Assert.assertTrue(output.containsKey(1001L)); + Assert.assertEquals("user1", output.get(1001L)); + + Assert.assertTrue(output.containsKey(1010L)); + Assert.assertEquals("user10", output.get(1010L)); + + //iteration 1 - get errors + try { + OctaneServerSettingsModel.parseWorkspace2ImpersonatedUserConf(payload, false); + Assert.fail("Exception expected"); + } catch (Exception e) { + if (e instanceof AggregatedMessagesException) { + List messages = ((AggregatedMessagesException) e).getMessages(); + Assert.assertEquals(4, messages.size()); + //Assert.assertTrue(messages.contains("Workspace configuration is not valid, valid format is 'Workspace ID:jenkins user': 1003:user1003:user1004")); + Assert.assertTrue(messages.contains("Workspace configuration is not valid, workspace ID must be numeric: user1004:1004")); + Assert.assertTrue(messages.contains("Workspace configuration is not valid, workspace ID must be numeric: abc:abc")); + Assert.assertTrue(messages.contains("Workspace configuration is not valid, user value is empty: 1005:")); + Assert.assertTrue(messages.contains("Duplicated workspace configuration: 1001:user1a")); + } else { + Assert.fail("Wrong type of exception : " + e.getClass().getName()); + } + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/CopyResourceSCM.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/CopyResourceSCM.java new file mode 100644 index 0000000000..e04b86b1aa --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/CopyResourceSCM.java @@ -0,0 +1,79 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests;// (C) Copyright 2003-2015 Hewlett-Packard Development Company, L.P. + +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.scm.NullSCM; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.io.File; +import java.io.IOException; + +public class CopyResourceSCM extends NullSCM { + + private String path; + private String targetPath; + + public CopyResourceSCM(String path) { + this(path, ""); + } + + public CopyResourceSCM(String path, String targetPath) { + this.path = path; + this.targetPath = targetPath; + } + + @Override + public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { + if (workspace.exists()) { + listener.getLogger().println("Deleting existing workspace " + workspace.getRemote()); + workspace.deleteRecursive(); + } + Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:" + path + "/**"); + for (Resource resource : resources) { + if (resource.exists() && resource.isReadable()) { + String urlString = resource.getURL().toExternalForm(); + String targetName = urlString.substring(urlString.indexOf(path) + path.length()); + byte[] fileContent = IOUtils.toByteArray(resource.getInputStream()); + FileUtils.writeByteArrayToFile(new File(new File(workspace.getRemote(), targetPath), targetName), fileContent); + } + } + return true; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/ExtensionUtil.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/ExtensionUtil.java new file mode 100644 index 0000000000..a31b950f2b --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/ExtensionUtil.java @@ -0,0 +1,46 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.ExtensionList; +import org.junit.Assert; +import org.jvnet.hudson.test.JenkinsRule; + +public class ExtensionUtil { + + public static E getInstance(JenkinsRule rule, Class clazz) { + ExtensionList items = rule.getInstance().getExtensionList(clazz); + Assert.assertEquals(1, items.size()); + return items.get(0); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/JUnitResultsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/JUnitResultsTest.java new file mode 100644 index 0000000000..fd3729fbea --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/JUnitResultsTest.java @@ -0,0 +1,230 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.junit.TestResultStatus; +import hudson.matrix.*; +import hudson.maven.MavenModuleSet; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.tasks.Maven; +import hudson.tasks.junit.JUnitResultArchiver; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.jvnet.hudson.test.ToolInstallations; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701", "squid:S2698"}) +public class JUnitResultsTest extends OctanePluginTestBase { + + private static Set helloWorld2Tests = new HashSet<>(); + + static { + helloWorld2Tests.add(TestUtils.testSignature("helloWorld2", "hello", "HelloWorld2Test", "testOnce", + TestResultStatus.PASSED)); + helloWorld2Tests.add(TestUtils.testSignature("helloWorld2", "hello", "HelloWorld2Test", "testDoce", TestResultStatus.PASSED)); + } + + private static Set subFolderHelloWorldTests = new HashSet<>(); + + static { + subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testOne", TestResultStatus.PASSED)); + subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testTwo", TestResultStatus.FAILED)); + subFolderHelloWorldTests.add(TestUtils.testSignature("subFolder/helloWorld", "hello", "HelloWorldTest", "testThree", TestResultStatus.SKIPPED)); + } + + private static String mavenName; + + @BeforeClass + public static void prepareClass() throws Exception { + rule.jenkins.setNumExecutors(10); + Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven35(); + mavenName = mavenInstallation.getName(); + } + + @Test + public void testJUnitResults() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); + } + + @Test + public void testJUnitResultsPom() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, "subFolder/helloWorld/pom.xml", null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot", "subFolder")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, subFolderHelloWorldTests); + } + + @Test + public void testJUnitResultsTwoPoms() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, "pom.xml", null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); + } + + @Test + public void testJUnitResultsLegacy() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); + project.runHeadless(); + + project.setMaven(mavenName); + project.setGoals(String.format("clean test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=%s\\m2-temp -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(), System.getenv("TEMP"))); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); + } + + //temporary disable as it failed in CI + //@Test + public void testJUnitResultsLegacyWithoutJUnitArchiver() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); + project.runHeadless(); + + project.setMaven(mavenName); + project.setGoals(String.format("clean test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=%s\\m2-temp -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(), System.getenv("TEMP"))); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); + } + + @Test + public void testJUnitResultsLegacySubfolder() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); + project.runHeadless(); + + project.setMaven(mavenName); + project.setRootPOM("subFolder/helloWorld/pom.xml"); + project.setGoals(String.format("clean test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=%s\\m2-temp -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(), System.getenv("TEMP"))); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot", "subFolder")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, subFolderHelloWorldTests); + } + + @Test + public void testJUnitResultsWorkspaceStripping() throws Exception { + Set uftTests = new HashSet<>(); + uftTests.add(TestUtils.testSignature("", "All-Tests", "", "subfolder" + File.separator + "CalculatorPlusNextGen", TestResultStatus.FAILED)); + + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.getPublishersList().add(new TestCustomJUnitArchiver("UFT_results.xml")); + project.setScm(new CopyResourceSCM("/UFT")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, uftTests); + } + + @Test + public void testJUnitResultsFreeStyleModule() throws Exception { + // this scenario simulates FreeStyle project with maven executed via shell (by not using Maven builder directly) + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + matchTests(build, projectName, TestUtils.helloWorldTests, helloWorld2Tests); + } + + @Test + public void testJUnitResultsMatrixProject() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + String axisParamName = "osType"; + String[] subtypes = new String[]{"Linux", "Windows"}; + MatrixProject matrixProject = rule.createProject(MatrixProject.class, projectName); + matrixProject.setAxes(new AxisList(new Axis(axisParamName, subtypes))); + + matrixProject.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.test.failure.ignore=true -Dmaven.repo.local=%s\\m2-temp -X", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName)); + + matrixProject.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + matrixProject.setScm(new CopyResourceSCM("/helloWorldRoot")); + MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); + + for (MatrixRun run : build.getExactRuns()) { + matchTests( + run, + projectName + "/" + axisParamName + "=" + subtypes[build.getExactRuns().indexOf(run)], + TestUtils.helloWorldTests, helloWorld2Tests); + } + Assert.assertFalse(new File(build.getRootDir(), "mqmTests.xml").exists()); + } + + private void matchTests(AbstractBuild build, String projectName, Set... expectedTests) throws FileNotFoundException { + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + TestUtils.matchTests(new TestResultIterable(mqmTestsXml), projectName, build.getStartTimeInMillis(), expectedTests); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestApiTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestApiTest.java new file mode 100644 index 0000000000..a248ace7f4 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestApiTest.java @@ -0,0 +1,210 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gargoylesoftware.htmlunit.Page; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.tests.TestsResult; +import com.hp.octane.integrations.services.WorkerPreflight; +import com.hp.octane.integrations.services.rest.RestService; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.OctaneServerMock; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.tasks.Maven; +import hudson.tasks.junit.JUnitResultArchiver; +import hudson.util.Secret; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.eclipse.jetty.server.Request; +import org.junit.*; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.ToolInstallations; +import org.xml.sax.SAXException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.*; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2698"}) +public class TestApiTest { + private static DTOFactory dtoFactory = DTOFactory.getInstance(); + private static AbstractBuild build; + private static JenkinsRule.WebClient client; + private static int octaneServerMockPort; + private static TestApiPreflightHandler testApiPreflightHandler = new TestApiPreflightHandler(); + private static TestApiPushTestsResultHandler testApiPushTestsResultHandler = new TestApiPushTestsResultHandler(); + private static TestApiPushTestsLogHandler testApiPushTestsLogHandler = new TestApiPushTestsLogHandler(); + private static String sharedSpaceId = TestApiTest.class.getSimpleName(); + private static String testsJobName = "test-api-test"; + private static Long pushTestResultId = 10001L; + + @ClassRule + final public static JenkinsRule rule = new JenkinsRule(); + + @BeforeClass + public static void init() throws Exception { + + // prepare client for verifications + client = rule.createWebClient(); + + // prepare Octane Server Mock + OctaneServerMock octaneServerMock = OctaneServerMock.getInstance(); + octaneServerMockPort = octaneServerMock.getPort(); + octaneServerMock.addTestSpecificHandler(testApiPreflightHandler); + octaneServerMock.addTestSpecificHandler(testApiPushTestsResultHandler); + octaneServerMock.addTestSpecificHandler(testApiPushTestsLogHandler); + + // configure plugin for the server + OctaneServerSettingsModel model = new OctaneServerSettingsModel( + "http://127.0.0.1:" + octaneServerMockPort + "/ui?p=" + sharedSpaceId, + "username", + Secret.fromString("password"), + ""); + ConfigurationService.configurePlugin(model); + + // run the actual pipeline producing the tests + FreeStyleProject project = rule.createFreeStyleProject(testsJobName); + Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven35(); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" test -Dmaven.repo.local=\"%s\\m2-temp\"", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenInstallation.getName(), "helloWorld/pom.xml", null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + build = TestUtils.runAndCheckBuild(project); + } + + @AfterClass + public static void cleanup() { + OctaneServerMock octaneServerMock = OctaneServerMock.getInstance(); + octaneServerMock.removeTestSpecificHandler(testApiPreflightHandler); + octaneServerMock.removeTestSpecificHandler(testApiPushTestsResultHandler); + octaneServerMock.removeTestSpecificHandler(testApiPushTestsLogHandler); + } + + @Test + public void testXml() throws Exception { + Page testResults = client.goTo("job/" + testsJobName + "/" + build.getNumber() + "/nga/tests/xml", "application/xml"); + String testResultsBody = testResults.getWebResponse().getContentAsString(); + TestsResult testsResultOrigin = dtoFactory.dtoFromXml(testResultsBody, TestsResult.class); + TestsResult testsResultTarget = dtoFactory.dtoFromXml(testApiPushTestsResultHandler.testResults.get(0), TestsResult.class); + assertNotNull(testsResultOrigin); + assertNotNull(testsResultTarget); + assertNotNull(testsResultOrigin.getBuildContext()); + assertNotNull(testsResultTarget.getBuildContext()); + //assertEquals(testsResultOrigin.getBuildContext().getServerId(), testsResultTarget.getBuildContext().getServerId()); + assertEquals(testsResultOrigin.getBuildContext().getJobId(), testsResultTarget.getBuildContext().getJobId()); + assertEquals(testsResultOrigin.getBuildContext().getBuildId(), testsResultTarget.getBuildContext().getBuildId()); + assertEquals(testsResultOrigin.getTestRuns().size(), testsResultTarget.getTestRuns().size()); + // TODO: add deeper verification + TestUtils.matchTests(new TestResultIterable(new StringReader(testResultsBody)), testsJobName, build.getStartTimeInMillis(), TestUtils.helloWorldTests); + } + + @Test + @Ignore + public void testAudit() throws Exception { + Page auditLog = client.goTo("job/" + testsJobName + "/" + build.getNumber() + "/nga/tests/audit", "application/json"); + JSONArray audits = JSONArray.fromObject(auditLog.getWebResponse().getContentAsString()); + assertEquals(1, audits.size()); + JSONObject audit = audits.getJSONObject(0); + assertEquals((long) pushTestResultId, audit.getLong("id")); + assertTrue(audit.getBoolean("pushed")); + assertEquals("http://127.0.0.1:" + octaneServerMockPort, audit.getString("location")); + assertEquals(sharedSpaceId, audit.getString("sharedSpace")); + assertNotNull(audit.getString("date")); + } + + @Test + @Ignore + public void testLog() throws IOException, SAXException { + Page publishLog = client.goTo("job/" + testsJobName + "/" + build.getNumber() + "/nga/tests/log", "text/plain"); + assertEquals("This is the log", publishLog.getWebResponse().getContentAsString()); + } + + private static final class TestApiPreflightHandler extends OctaneServerMock.TestSpecificHandler { + + @Override + public boolean ownsUrlToProcess(String url) { + return url.endsWith("/jobs/" + testsJobName + "/tests-result-preflight"); + } + + @Override + public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { + if (baseRequest.getPathInfo().endsWith("/jobs/" + testsJobName + "/tests-result-preflight")) { + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write(String.valueOf(true)); + } + } + } + + private static final class TestApiPushTestsResultHandler extends OctaneServerMock.TestSpecificHandler { + private List testResults = new LinkedList<>(); + + @Override + public boolean ownsUrlToProcess(String url) { + return (RestService.SHARED_SPACE_INTERNAL_API_PATH_PART + sharedSpaceId + RestService.ANALYTICS_CI_PATH_PART + "test-results").equals(url); + } + + @Override + public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { + testResults.add(getBodyAsString(baseRequest)); + Map body = new HashMap<>(); + body.put("id", String.valueOf(pushTestResultId)); + body.put("status", "queued"); + response.setStatus(HttpServletResponse.SC_ACCEPTED); + response.getWriter().write(new ObjectMapper().writeValueAsString(body)); + } + } + + private static final class TestApiPushTestsLogHandler extends OctaneServerMock.TestSpecificHandler { + + @Override + public boolean ownsUrlToProcess(String url) { + return (RestService.SHARED_SPACE_INTERNAL_API_PATH_PART + sharedSpaceId + RestService.ANALYTICS_CI_PATH_PART + "test-results/" + pushTestResultId + "/log").equals(url); + } + + @Override + public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write("This is the log"); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java new file mode 100644 index 0000000000..83ff1ac758 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestCustomJUnitArchiver.java @@ -0,0 +1,91 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Recorder; +import hudson.tasks.test.AbstractTestResultAction; +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +public class TestCustomJUnitArchiver extends Recorder { + + private String resultFile; + + public TestCustomJUnitArchiver(String resultFile) { + this.resultFile = resultFile; + } + + @Override + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + build.addAction(new TestResultAction()); + InputStream is = build.getWorkspace().child(resultFile).read(); + String junitResults = IOUtils.toString(is, "UTF-8"); + junitResults = junitResults + .replaceAll("%%%WORKSPACE%%%", build.getWorkspace().getRemote()) + .replaceAll("%%%SEPARATOR%%%", File.separator.equals("\\") ? "\\\\" : File.separator); + IOUtils.closeQuietly(is); + new FilePath(build.getRootDir()).child("junitResult.xml").write(junitResults, "UTF-8"); + return true; + } + + private static class TestResultAction extends AbstractTestResultAction { + + @Override + public int getFailCount() { + return 0; + } + + @Override + public int getTotalCount() { + return 0; + } + + @Override + public Object getResult() { + return new Object(); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestJenkinsDurationTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestJenkinsDurationTest.java new file mode 100644 index 0000000000..ad00d6ced4 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestJenkinsDurationTest.java @@ -0,0 +1,85 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +import static org.junit.Assert.assertEquals; + +/** + * Created by berkovir on 06/02/2017. + */ +@SuppressWarnings({"squid:S2698","squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925"}) +public class TestJenkinsDurationTest { + + @ClassRule + public static final JenkinsRule rule = new JenkinsRule(); + + + @Test + public void testDuration() throws Exception { + + FreeStyleProject p = rule.createFreeStyleProject("test-duration"); + + assertEquals(0, p.getBuilds().toArray().length); + long start = System.currentTimeMillis(); + AbstractBuild build = p.scheduleBuild2(0).get(); + + + while (build.isBuilding()){ + Thread.sleep(10); + } + + long end = System.currentTimeMillis(); + long buildDurationWithoutPostProcessTime = build.getDuration(); + long buildDurationTotal = (end - start); + long pluginPostProcessWorkTime = buildDurationTotal - buildDurationWithoutPostProcessTime; + + + long buildDurationTotalExpected = 3000; + long pluginPostProcessWorkTimeExpected = 2200; + + System.out.println(String.format("buildDurationTotal=%d, expected=%d", buildDurationTotal, buildDurationTotalExpected)); + System.out.println(String.format("pluginPostProcessWorkTime=%d, expected=%d", pluginPostProcessWorkTime, pluginPostProcessWorkTimeExpected)); + Assert.assertTrue(String.format("buildDurationTotal=%d, expected=%d", buildDurationTotal, buildDurationTotalExpected),buildDurationTotal < buildDurationTotalExpected); + Assert.assertTrue(String.format("pluginPostProcessWorkTime=%d, expected=%d", pluginPostProcessWorkTime, pluginPostProcessWorkTimeExpected),pluginPostProcessWorkTime < pluginPostProcessWorkTimeExpected); + + int t; + + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterable.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterable.java new file mode 100644 index 0000000000..75b1471d1f --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterable.java @@ -0,0 +1,63 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitTestResult; + +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.Reader; + +public class TestResultIterable implements Iterable { + + private Reader reader; + + public TestResultIterable(File file) throws FileNotFoundException { + this.reader = new FileReader(file); + } + + public TestResultIterable(Reader reader) { + this.reader = reader; + } + + @Override + public TestResultIterator iterator() { + try { + return new TestResultIterator(reader); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterator.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterator.java new file mode 100644 index 0000000000..d1910254eb --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestResultIterator.java @@ -0,0 +1,149 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitTestResult; +import com.microfocus.application.automation.tools.octane.tests.junit.TestResultStatus; +import hudson.util.IOUtils; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; +import java.io.Reader; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.NoSuchElementException; + +public class TestResultIterator implements Iterator { + + private Reader input; + private XMLEventReader reader; + private LinkedList items = new LinkedList<>(); + private boolean closed; + private String serverId; + private String jobId; + private String buildId; + private String subType; + + public TestResultIterator(Reader input) throws XMLStreamException { + this.input = input; + reader = XMLInputFactory.newInstance().createXMLEventReader(input); + } + + @Override + public boolean hasNext() { + try { + while (items.isEmpty() && !closed) { + if (reader.hasNext()) { + XMLEvent event = reader.nextEvent(); + if (event instanceof StartElement) { + Attribute attribute; + StartElement element = (StartElement) event; + String localName = element.getName().getLocalPart(); + if ("test_run".equals(localName)) { + String moduleName = element.getAttributeByName(new QName("module")).getValue(); + String packageName = element.getAttributeByName(new QName("package")).getValue(); + String className = element.getAttributeByName(new QName("class")).getValue(); + String testName = element.getAttributeByName(new QName("name")).getValue(); + long duration = Long.valueOf(element.getAttributeByName(new QName("duration")).getValue()); + TestResultStatus status = TestResultStatus.fromPrettyName(element.getAttributeByName(new QName("status")).getValue()); + long started = Long.valueOf(element.getAttributeByName(new QName("started")).getValue()); + items.add(new JUnitTestResult(moduleName, packageName, className, testName, status, duration, started, null, null, null,null,null, null, false)); + } else if ("build".equals(localName)) { + attribute = element.getAttributeByName(new QName("server_id")); + if (attribute != null) { + serverId = attribute.getValue(); + } + attribute = element.getAttributeByName(new QName("job_id")); + if (attribute != null) { + jobId = attribute.getValue(); + } + attribute = element.getAttributeByName(new QName("build_id")); + if (attribute != null) { + buildId = attribute.getValue(); + } + attribute = element.getAttributeByName(new QName("sub_type")); + if (attribute != null) { + this.subType = attribute.getValue(); + } + } + } + } else { + closed = true; + IOUtils.closeQuietly(input); + reader.close(); + } + } + return !items.isEmpty(); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } + + @Override + public JUnitTestResult next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return items.removeFirst(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public String getServerId() { + hasNext(); + return serverId; + } + + public String getJobId() { + hasNext(); + return jobId; + } + + public String getBuildId() { + hasNext(); + return buildId; + } + + public String getSubType() { + hasNext(); + return subType; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestUtils.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestUtils.java new file mode 100644 index 0000000000..647148dbf4 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/TestUtils.java @@ -0,0 +1,131 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests; + +import com.hp.octane.integrations.OctaneSDK; +import com.hp.octane.integrations.dto.DTOBase; +import com.hp.octane.integrations.dto.DTOFactory; +import com.hp.octane.integrations.dto.connectivity.OctaneResultAbridged; +import com.hp.octane.integrations.dto.connectivity.OctaneTaskAbridged; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitTestResult; +import com.microfocus.application.automation.tools.octane.tests.junit.TestResultStatus; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.util.Secret; +import org.junit.Assert; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class TestUtils { + + static Set helloWorldTests = new HashSet<>(); + + static { + helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testOne", TestResultStatus.PASSED)); + helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testTwo", TestResultStatus.FAILED)); + helloWorldTests.add(testSignature("helloWorld", "hello", "HelloWorldTest", "testThree", TestResultStatus.SKIPPED)); + } + + public static void createDummyConfiguration(){ + ConfigurationService.configurePlugin(new OctaneServerSettingsModel( + "http://localhost:8008/ui/?p=1001/1002","username", + Secret.fromString("password"),null)); + } + + public static AbstractBuild runAndCheckBuild(AbstractProject project) throws Exception { + AbstractBuild build = (AbstractBuild) project.scheduleBuild2(0).get(); + if (!build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { // avoid expensive build.getLog() until condition is met + Assert.fail("Build status: " + build.getResult() + ", log follows:\n" + build.getLog()); + } + return build; + } + + private static String testSignature(JUnitTestResult testResult) { + return testSignature(testResult.getModuleName(), testResult.getPackageName(), testResult.getClassName(), + testResult.getTestName(), testResult.getResult()); + } + + static String testSignature(String moduleName, String packageName, String className, String testName, TestResultStatus status) { + return moduleName + "#" + packageName + "#" + className + "#" + testName + "#" + status.toPrettyName() + "#"; + } + + static void matchTests(TestResultIterable testResultIterable, String buildType, long started, Set... expectedTests) { + Set copy = new HashSet<>(); + for (Set expected : expectedTests) { + copy.addAll(expected); + } + TestResultIterator it = testResultIterable.iterator(); + Assert.assertEquals(buildType, it.getJobId()); + while (it.hasNext()) { + JUnitTestResult testResult = it.next(); + String testSignature = TestUtils.testSignature(testResult); + Assert.assertTrue("Not found: " + testSignature + " in " + copy, copy.remove(testSignature)); + Assert.assertEquals("Start time differs", started, testResult.getStarted()); + } + Assert.assertTrue("More tests expected: " + copy.toString(), copy.isEmpty()); + } + + static public String getMavenHome() { + String result = System.getenv("MAVEN_HOME") != null && !System.getenv("MAVEN_HOME").isEmpty() ? + System.getenv("MAVEN_HOME") : + System.getenv("M2_HOME"); + if (result == null || result.isEmpty()) { + throw new IllegalStateException("nor MAVEN_HOME neither M2_HOME is defined, won't run"); + } + return result; + } + + public static T sendTask(String url, Class targetType) { + DTOFactory dtoFactory = DTOFactory.getInstance(); + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + OctaneTaskAbridged task = dtoFactory.newDTO(OctaneTaskAbridged.class) + .setMethod(com.hp.octane.integrations.dto.connectivity.HttpMethod.GET) + .setUrl(url) + .setHeaders(headers); + OctaneResultAbridged taskResult = OctaneSDK.getClients().get(0).getTasksProcessor().execute(task); + + T result = null; + if(targetType!=null){ + result = dtoFactory.dtoFromJson(taskResult.getBody(), targetType); + } + + return result; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java new file mode 100644 index 0000000000..70e437d240 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/build/BuildHandlerUtilsTest.java @@ -0,0 +1,110 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.build; + +import com.microfocus.application.automation.tools.octane.tests.CopyResourceSCM; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.matrix.*; +import hudson.maven.MavenModuleSet; +import hudson.maven.MavenModuleSetBuild; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.tasks.Maven; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.ToolInstallations; + +import java.util.HashMap; + +@SuppressWarnings({"squid:S2699", "squid:S3658", "squid:S2259", "squid:S1872", "squid:S2925", "squid:S109", "squid:S1607", "squid:S2701"}) +public class BuildHandlerUtilsTest { + + @ClassRule + public static final JenkinsRule jenkins = new JenkinsRule(); + + @Test + public void testMatrixBuildType() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class, "matrix-project"); + matrixProject.setAxes(new AxisList(new Axis("OS", "Linux", "Windows"))); + MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); + + BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); + Assert.assertEquals("matrix-project", descriptor.getJobId()); + Assert.assertEquals("", descriptor.getSubType()); + + Assert.assertEquals("matrix-project", BuildHandlerUtils.getProjectFullName(build)); + + HashMap expectedType = new HashMap<>(); + expectedType.put("OS=Linux", "matrix-project/OS=Linux"); + expectedType.put("OS=Windows", "matrix-project/OS=Windows"); + + for (MatrixRun run : build.getExactRuns()) { + descriptor = BuildHandlerUtils.getBuildType(run); + Assert.assertTrue("matrix-project/OS=Linux".equals(descriptor.getJobId()) || "matrix-project/OS=Windows".equals(descriptor.getJobId())); + String fullName = expectedType.remove(descriptor.getSubType()); + Assert.assertEquals(fullName, BuildHandlerUtils.getProjectFullName(run)); + } + Assert.assertTrue(expectedType.isEmpty()); + } + + @Test + public void testMavenBuildType() throws Exception { + MavenModuleSet project = jenkins.createProject(MavenModuleSet.class, "maven-project"); + project.runHeadless(); + + Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven35(); + + project.setMaven(mavenInstallation.getName()); + project.setGoals(String.format("clean test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", TestUtils.getMavenHome(), System.getenv("TEMP"))); + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(project); + + BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); + Assert.assertEquals("maven-project", descriptor.getJobId()); + Assert.assertEquals("", descriptor.getSubType()); + + Assert.assertEquals("maven-project", BuildHandlerUtils.getProjectFullName(build)); + } + + @Test + public void testFallbackBuildType() throws Exception { + FreeStyleProject project = jenkins.createFreeStyleProject("freestyle-project"); + FreeStyleBuild build = (FreeStyleBuild) TestUtils.runAndCheckBuild(project); + BuildDescriptor descriptor = BuildHandlerUtils.getBuildType(build); + Assert.assertEquals("freestyle-project", descriptor.getJobId()); + Assert.assertEquals("", descriptor.getSubType()); + Assert.assertEquals("freestyle-project", BuildHandlerUtils.getProjectFullName(build)); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java new file mode 100644 index 0000000000..b843f33c4c --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsDetectionTest.java @@ -0,0 +1,157 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.CopyResourceSCM; +import com.microfocus.application.automation.tools.octane.tests.ExtensionUtil; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitExtension; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.tasks.Maven; +import hudson.tasks.junit.JUnitResultArchiver; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.jvnet.hudson.test.ToolInstallations; +import org.mockito.Mockito; + +import java.io.File; +import java.io.FileReader; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class ResultFieldsDetectionTest extends OctanePluginTestBase { + + private static FreeStyleProject project; + + private static ResultFieldsDetectionService detectionService; + + @Before + public void setUp() throws Exception { + + project = rule.createFreeStyleProject("junit - job-" + UUID.randomUUID().toString()); + JUnitExtension junitExtension = ExtensionUtil.getInstance(rule, JUnitExtension.class); + detectionService = Mockito.mock(ResultFieldsDetectionService.class); + junitExtension._setResultFieldsDetectionService(detectionService); + + Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven35(); + //Maven.MavenInstallation mavenInstallation = new Maven.MavenInstallation("default-system-maven", TestUtils.getMavenHome(), JenkinsRule.NO_PROPERTIES); + + //project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" -U test",TestUtils.getMavenHome()), mavenInstallation.getName(), null, null, "-Dmaven.test.failure.ignore=true")); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" -U test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), mavenInstallation.getName(), null, null, "-Dmaven.test.failure.ignore=true")); + + project.setScm(new CopyResourceSCM("/helloWorldRoot")); + } + + @Test + public void testDetectionNotRun() throws Exception { + //there is no test publisher set up in this project, detection will not run + AbstractBuild build = TestUtils.runAndCheckBuild(project); + verify(detectionService, Mockito.never()).getDetectedFields(build); + } + + @Test + public void testDetectionRunOnce() throws Exception { + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + verify(detectionService, Mockito.times(1)).getDetectedFields(build); + } + + @Test + public void testDetectedFieldsInXml() throws Exception { + when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(new ResultFields("HOLA", "CIAO", "SALUT")); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + ResultFields resultFields = xmlReader.readXml().getResultFields(); + + Assert.assertNotNull(resultFields); + Assert.assertEquals("HOLA", resultFields.getFramework()); + Assert.assertEquals("CIAO", resultFields.getTestingTool()); + Assert.assertEquals("SALUT", resultFields.getTestLevel()); + } + + @Test + public void testNoDetectedFieldsInXml() throws Exception { + when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(null); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + ResultFields resultFields = xmlReader.readXml().getResultFields(); + Assert.assertNull(resultFields.getFramework()); + Assert.assertNull(resultFields.getTestingTool()); + Assert.assertNull(resultFields.getTestLevel()); + } + + @Test + public void testEmptyDetectedFieldsInXml() throws Exception { + when(detectionService.getDetectedFields(any(AbstractBuild.class))).thenReturn(new ResultFields(null, null, null)); + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + ResultFields resultFields = xmlReader.readXml().getResultFields(); + + Assert.assertNull(resultFields.getFramework()); + Assert.assertNull(resultFields.getTestingTool()); + Assert.assertNull(resultFields.getTestLevel()); + } + + /** + * We do not detect Junit yet. + */ + @Test + public void testNotDetectableConfigurationInXml() throws Exception { + project.getPublishersList().add(new JUnitResultArchiver("**/target/surefire-reports/*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + ResultFields resultFields = xmlReader.readXml().getResultFields(); + + Assert.assertNull(resultFields.getFramework()); + Assert.assertNull(resultFields.getTestingTool()); + Assert.assertNull(resultFields.getTestLevel()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsTest.java new file mode 100644 index 0000000000..82a4a4df74 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsTest.java @@ -0,0 +1,53 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import org.junit.Assert; +import org.junit.Test; + +public class ResultFieldsTest { + + @Test + public void testEquals() { + ResultFields x = new ResultFields("foo", "bar", null); + Assert.assertTrue(x.equals(x)); + Assert.assertTrue(!x.equals(null)); + + ResultFields y = new ResultFields("foo", "bar", null); + Assert.assertTrue(x.equals(y) && y.equals(x)); + Assert.assertTrue(x.hashCode() == y.hashCode()); + + ResultFields z = new ResultFields("foo", "bar", ""); + Assert.assertTrue(!x.equals(z) && !z.equals(x)); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java new file mode 100644 index 0000000000..0188531b9b --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/ResultFieldsXmlReader.java @@ -0,0 +1,152 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; +import java.io.Reader; +import java.util.LinkedList; +import java.util.List; + +public class ResultFieldsXmlReader { + + private Reader input; + private XMLEventReader eventReader; + private ResultFields resultFields; + private List testAttributes; + + public ResultFieldsXmlReader(Reader input) throws XMLStreamException { + this.input = input; + eventReader = XMLInputFactory.newInstance().createXMLEventReader(input); + resultFields = new ResultFields(); + testAttributes = new LinkedList(); + } + + public TestResultContainer readXml() { + boolean fieldsElement = false; + try { + while (eventReader.hasNext()) { + XMLEvent event = eventReader.nextEvent(); + if (event instanceof StartElement) { + StartElement element = (StartElement) event; + String localName = element.getName().getLocalPart(); + if ("test_fields".equals(localName)) { + fieldsElement = true; + } + if ("test_field".equals(localName)) { + if (!fieldsElement) { + Assert.fail(" element found, but surrounding element '' is missing in the XML file"); + } + String type = element.getAttributeByName(new QName("type")).getValue(); + String value = element.getAttributeByName(new QName("value")).getValue(); + if (type.equals("Framework")) { + resultFields.setFramework(value); + } else if (type.equals("Testing_Tool_Type")) { + resultFields.setTestingTool(value); + } else if (type.equals("Test_Level")) { + resultFields.setTestLevel(value); + } + } + if ("test_run".equals(localName)) { + String moduleName = element.getAttributeByName(new QName("module")).getValue(); + String packageName = element.getAttributeByName(new QName("package")).getValue(); + String className = element.getAttributeByName(new QName("class")).getValue(); + String testName = element.getAttributeByName(new QName("name")).getValue(); + testAttributes.add(new TestAttributes(moduleName, packageName, className, testName)); + } + } + } + IOUtils.closeQuietly(input); + eventReader.close(); + } catch (XMLStreamException e){ + throw new RuntimeException(e); + } + return new TestResultContainer(testAttributes, resultFields); + } + + public class TestResultContainer { + + private List testAttributes; + private ResultFields resultFields; + + public TestResultContainer(List testAttributes, ResultFields resultFields) { + this.testAttributes = testAttributes; + this.resultFields = resultFields; + } + + public List getTestAttributes() { + return testAttributes; + } + + public ResultFields getResultFields() { + return resultFields; + } + } + + public class TestAttributes { + private final String moduleName; + private final String packageName; + private final String className; + private final String testName; + + public TestAttributes(final String moduleName, final String packageName, final String className, final String testName) { + this.moduleName = moduleName; + this.packageName = packageName; + this.className = className; + this.testName = testName; + } + + public String getPackageName() { + return packageName; + } + + public String getModuleName() { + return moduleName; + } + + public String getClassName() { + return className; + } + + public String getTestName() { + return testName; + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java new file mode 100644 index 0000000000..044dead1c0 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/TestNGExtensionTest.java @@ -0,0 +1,352 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.google.inject.Inject; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.tests.CopyResourceSCM; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.FilePath; +import hudson.maven.MavenBuild; +import hudson.maven.MavenModule; +import hudson.maven.MavenModuleSet; +import hudson.maven.MavenModuleSetBuild; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.tasks.Maven; +import hudson.tasks.junit.JUnitResultArchiver; +import hudson.tasks.test.AbstractTestResultAction; +import org.junit.*; +import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.ToolInstallations; + +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Map; +import java.util.UUID; + +@SuppressWarnings({"squid:S2698","squid:S2699","squid:S3658"}) +public class TestNGExtensionTest extends OctanePluginTestBase { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Inject + public TestNGExtension extension = new TestNGExtension(); + + private String mavenName; + + @Before + public void setUp() throws Exception { + mavenName = ToolInstallations.configureMaven35().getName(); + } + + @Ignore("temp ignore") + @Test + public void testFreestyleProject() throws Exception { + String projectName = "testNG-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("helloWorld/target/surefire-reports/TEST*.xml, helloWorld2/target/surefire-reports/TEST*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Test + public void testFreestyleProjectOneModule() throws Exception { + String projectName = "testNG-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("target/surefire-reports/TEST*.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Ignore("temp ignore") + @Test + public void testFreestyleProjectCustomLocation() throws Exception { + String projectName = "testNG-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" test -P custom-report-location -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.getPublishersList().add(new JUnitResultArchiver("**\\custom-report-location/**.xml")); + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Ignore("temp ignore") + @Test + public void testMavenOneModule() throws Exception { + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true",TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); + AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Test + public void testMavenMultimodule() throws Exception { + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + System.setProperty("jenkins.security.s2m.RunningBuildFilePathFilter.SKIP","true"); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); + MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + + //test detection in all sub-modules that include tests + Map moduleLastBuilds = build.getModuleLastBuilds(); + for (MavenBuild mavenBuild : moduleLastBuilds.values()) { + AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); + if (action != null) { + fields = readResultFields(mavenBuild); + assertTestNGFields(fields); + } + } + } + + @Test + public void testMavenOneModuleCustomLocation() throws Exception { + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -P custom-report-location -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test -P custom-report-location --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + + mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot/helloWorld")); + AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + //we do not support combination of custom test report location and not publishing tests + Assert.assertNull(fields.getFramework()); + Assert.assertNull(fields.getTestLevel()); + Assert.assertNull(fields.getTestingTool()); + } + + @Ignore("temp ignore") + @Test + public void testMavenMultimoduleCustomLocation() throws Exception { + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -P custom-report-location -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test -P custom-report-location --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + //we do not support combination of custom test report location and not publishing tests + Assert.assertNull(fields.getFramework()); + Assert.assertNull(fields.getTestLevel()); + Assert.assertNull(fields.getTestingTool()); + } + + @Ignore("temp ignore") + @Test + public void testMavenMultimoduleCustomLocationPublished() throws Exception { + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -P custom-report-location -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test -P custom-report-location --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.getPublishersList().add(new JUnitResultArchiver("**/custom-report-location/**.xml")); + mavenProject.setScm(new CopyResourceSCM("/helloWorldTestNGRoot")); + AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Test + public void testMavenFailsafe() throws Exception { + String projectName = "testNG-job-maven-failsafe-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("verify"); + mavenProject.setGoals(String.format("verify --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldFailsafe")); + AbstractBuild build = TestUtils.runAndCheckBuild(mavenProject); + + ResultFields fields = readResultFields(build); + assertTestNGFields(fields); + } + + @Test + public void testFindingFiles() throws IOException, InterruptedException { + temporaryFolder.newFolder("src"); + temporaryFolder.newFolder("target"); + temporaryFolder.newFolder("target", "foo"); + temporaryFolder.newFolder("target", "bar"); + temporaryFolder.newFolder("target", "baz"); + temporaryFolder.newFolder("target", "baz", "qux"); + + String[] pathsToXmls = new String[]{ + "target/foo/TEST1.xml", + "target/foo/TEST2.xml", + "target/foo/TEST3.xml", + "target/bar/TEST4.xml", + "target/bar/TEST5.xml", + "target/baz/TEST1.xml", + "target/baz/TEST2.xml", + "target/baz/qux/TEST1.xml", + "target/baz/qux/TEST2.xml", + }; + + for (String filePath : pathsToXmls) { + temporaryFolder.newFile(filePath); + } + + TestNGExtension.TestNgResultsFileFinder testNgFinder = new TestNGExtension.TestNgResultsFileFinder(null); + boolean found = testNgFinder.findTestNgResultsFile(temporaryFolder.getRoot(), pathsToXmls); + Assert.assertFalse(found); + + temporaryFolder.newFile("target/baz/qux/testng-results.xml"); + found = testNgFinder.findTestNgResultsFile(temporaryFolder.getRoot(), pathsToXmls); + Assert.assertTrue(found); + } + + @Test + public void testFindingFilesMavenBuild() throws Exception { + //running Junit tests - there will be no testng results file + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + + //mavenProject.setGoals("test -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true",TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldRoot/helloWorld")); + MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); + + //test detection in all sub-modules that include tests + Map moduleLastBuilds = build.getModuleLastBuilds(); + for (MavenBuild mavenBuild : moduleLastBuilds.values()) { + AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); + if (action != null) { + boolean found = extension.findTestNgResultsFile(mavenBuild); + Assert.assertFalse(found); + + //creating tesng result file manually + FilePath folder = mavenBuild.getWorkspace().child("target/surefire-reports/testng-results.xml"); + File report = new File(folder.toURI()); + report.createNewFile(); + found = extension.findTestNgResultsFile(mavenBuild); + Assert.assertTrue(found); + report.delete(); + } + } + } + + @Test + public void testFindingFilesMavenBuildFailsafe() throws Exception { + //running Junit tests - there will be no testng results file + String projectName = "testNG-job-maven-" + UUID.randomUUID().toString(); + MavenModuleSet mavenProject = rule.createProject(MavenModuleSet.class, projectName); + mavenProject.runHeadless(); + mavenProject.setMaven(mavenName); + //mavenProject.setGoals("test -Dmaven.test.failure.ignore=true"); + mavenProject.setGoals(String.format("test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=\"%s\\m2-temp\" -Dmaven.test.failure.ignore=true",TestUtils.getMavenHome(),System.getenv("TEMP"))); + mavenProject.setScm(new CopyResourceSCM("/helloWorldRoot/helloWorld")); + MavenModuleSetBuild build = (MavenModuleSetBuild) TestUtils.runAndCheckBuild(mavenProject); + + //test detection in all sub-modules that include tests + Map moduleLastBuilds = build.getModuleLastBuilds(); + for (MavenBuild mavenBuild : moduleLastBuilds.values()) { + AbstractTestResultAction action = mavenBuild.getAction(AbstractTestResultAction.class); + if (action != null) { + boolean found = extension.findTestNgResultsFile(mavenBuild); + Assert.assertFalse(found); + + //creating tesng result file manually + FilePath reports = mavenBuild.getWorkspace().child("target/failsafe-reports"); + File reportFolder = new File(reports.toURI()); + reportFolder.mkdirs(); + + File reportFile = new File(reports.child("testng-results.xml").toURI()); + reportFile.createNewFile(); + + found = extension.findTestNgResultsFile(mavenBuild); + Assert.assertTrue(found); + reportFile.delete(); + reportFolder.delete(); + } + } + } + + private void assertTestNGFields(ResultFields fields) { + Assert.assertNotNull(fields); + Assert.assertEquals("TestNG", fields.getFramework()); + Assert.assertNull(fields.getTestingTool()); + Assert.assertNull(fields.getTestLevel()); + } + + private ResultFields readResultFields(AbstractBuild build) throws FileNotFoundException, XMLStreamException { + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + return xmlReader.readXml().getResultFields(); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/UFTExtensionTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/UFTExtensionTest.java new file mode 100644 index 0000000000..bb28246155 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/detection/UFTExtensionTest.java @@ -0,0 +1,153 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.detection; + +import com.microfocus.application.automation.tools.model.AlmServerSettingsModel; +import com.microfocus.application.automation.tools.uft.model.FilterTestsModel; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFieldsXmlReader.TestAttributes; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFieldsXmlReader.TestResultContainer; +import com.microfocus.application.automation.tools.run.RunFromAlmBuilder; +import com.microfocus.application.automation.tools.run.RunFromFileBuilder; +import com.microfocus.application.automation.tools.uft.model.SpecifyParametersModel; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +import hudson.scm.SubversionSCM; +import hudson.tasks.Maven; +import hudson.tasks.junit.JUnitResultArchiver; +import org.junit.*; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.ToolInstallations; +import org.mockito.Mockito; + +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +@SuppressWarnings("squid:S2699") +public class UFTExtensionTest { + + @ClassRule + public static final JenkinsRule rule = new JenkinsRule(); + + private ResultFieldsDetectionService detectionService; + + @Before + public void before() { + detectionService = new ResultFieldsDetectionService(); + } + + @Test + public void testMockOneBuilder() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.getBuildersList().add(new RunFromFileBuilder("notExistingTest")); + + AbstractBuild buildMock = Mockito.mock(AbstractBuild.class); + Mockito.when(buildMock.getProject()).thenReturn(project); + + ResultFields fields = detectionService.getDetectedFields(buildMock); + assertUFTFields(fields); + } + + @Test + public void testMockMoreBuilders() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + FilterTestsModel filterTestsModel = new FilterTestsModel("testName", false, false, false, false, false); + SpecifyParametersModel parametersModel = new SpecifyParametersModel("[]"); + AlmServerSettingsModel almServerSettingsModel = new AlmServerSettingsModel("server2", "serverURL", new ArrayList<>(), new ArrayList<>()); + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), ToolInstallations.configureMaven35().getName(), null, null, "-Dmaven.test.failure.ignore=true")); + project.getBuildersList().add(new RunFromAlmBuilder("notExistingServer", "JOB", "sa", "", "domain", "project", "notExistingTests", "", "", "", "", "","", false, false, false, filterTestsModel, parametersModel, almServerSettingsModel)); + + AbstractBuild buildMock = Mockito.mock(AbstractBuild.class); + Mockito.when(buildMock.getProject()).thenReturn(project); + + ResultFields fields = detectionService.getDetectedFields(buildMock); + assertUFTFields(fields); + } + + @Test + public void testFileBuilder() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + project.getBuildersList().add(new RunFromFileBuilder("")); + + //UFT plugin will not find any test -> that will cause failing the scheduled build + //but as detection runs after completion of run, we are sure, that it did not fail because of detection service + AbstractBuild build = project.scheduleBuild2(0).get(); + + ResultFields fields = detectionService.getDetectedFields(build); + assertUFTFields(fields); + } + + @Ignore + @Test + public void testUFTEndToEnd() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + //TODO solve storing of example test + SubversionSCM scm = new SubversionSCM("http://localhost:8083/svn/selenium/branches/uft"); + project.setScm(scm); + project.getBuildersList().add(new RunFromFileBuilder("Calculator")); + project.getPublishersList().add(new JUnitResultArchiver("Results*.xml")); + //this will actually run the UFT test + AbstractBuild build = TestUtils.runAndCheckBuild(project); + + File mqmTestsXml = new File(build.getRootDir(), "mqmTests.xml"); + ResultFieldsXmlReader xmlReader = new ResultFieldsXmlReader(new FileReader(mqmTestsXml)); + TestResultContainer container = xmlReader.readXml(); + assertUFTFields(container.getResultFields()); + assertUFTTestAttributes(container.getTestAttributes()); + } + + private void assertUFTFields(ResultFields fields) { + Assert.assertNotNull(fields); + Assert.assertEquals("UFT", fields.getFramework()); + Assert.assertEquals("UFT", fields.getTestingTool()); + Assert.assertNull(fields.getTestLevel()); + } + + private void assertUFTTestAttributes(List testAttributes) { + for (TestAttributes test : testAttributes) { + Assert.assertTrue(test.getModuleName().isEmpty()); + Assert.assertTrue(test.getPackageName().isEmpty()); + Assert.assertTrue(test.getClassName().isEmpty()); + Assert.assertTrue(!test.getTestName().isEmpty()); + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java new file mode 100644 index 0000000000..72af13e78e --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/gherkin/GherkinResultsTest.java @@ -0,0 +1,268 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.gherkin; + +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.actions.cucumber.CucumberTestResultsActionPublisher; +import com.microfocus.application.automation.tools.octane.tests.CopyResourceSCM; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import hudson.matrix.*; +import hudson.maven.MavenModuleSet; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.FreeStyleProject; +import hudson.model.Result; +import hudson.tasks.Maven; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.jvnet.hudson.test.ToolInstallations; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * Created by franksha on 05/01/2017. + */ +@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701","squid:S2698"}) +public class GherkinResultsTest extends OctanePluginTestBase { + + private static String mavenName; + + + private static Set tests = new HashSet<>(); + static { + tests.add("My Amazing Feature"); + tests.add("My Fancy Feature"); + } + + @BeforeClass + public static void prepareClass() throws Exception { + rule.jenkins.setNumExecutors(10); + Maven.MavenInstallation mavenInstallation = ToolInstallations.configureMaven35(); + mavenName = mavenInstallation.getName(); + } + + @Test + public void testGherkinResultsDirectlyOnWorkspace() throws Exception { + gherkinResults("**/*Gherkin*.xml", true); + } + + @Ignore("temp ignore") + @Test + public void testGherkinResultsDirectlyOnWorkspaceEmptyGlob() throws Exception { + gherkinResults("", true); + } + + @Test + public void testGherkinResultsDirectlyOnWorkspaceNegative() throws Exception { + gherkinResults("abcd.xml", false); + } + + @Test + public void testGherkinResultsInSubFolder() throws Exception { + gherkinResultsInSubFolder("subFolder/*Gherkin*.xml", false); + } + + @Test + public void testGherkinResultsInSubFolderEmptyGlob() throws Exception { + gherkinResultsInSubFolder("", true); + } + + @Ignore("temp ignore") + @Test + public void testGherkinResultsInSubFolderNegative() throws Exception { + gherkinResultsInSubFolder("*Gherkin*.xml", false); + } + + @Ignore("temp ignore") + @Test + public void testGherkinResultsDirectlyOnWorkspaceLegacy() throws Exception { + gherkinResultsLegacy("**/*Gherkin*.xml", true); + } + @Test + public void testGherkinResultsDirectlyOnWorkspaceLegacyEmptyGlob() throws Exception { + gherkinResultsLegacy("", true); + } + + @Ignore("temp ignore") + @Test + public void testGherkinResultsDirectlyOnWorkspaceLegacyNegative() throws Exception { + gherkinResultsLegacy("abcd.xml", false); + } + + @Test + public void testGherkinResultsInSubFolderLegacy() throws Exception { + gherkinResultsLegacyWithSubFolder("subFolder/*Gherkin*.xml", false); + } + + @Test + public void testGherkinResultsInSubFolderLegacyEmptyGlob() throws Exception { + gherkinResultsLegacyWithSubFolder("", true); + } + + @Test + public void testGherkinResultsInSubFolderLegacyNegative() throws Exception { + gherkinResultsLegacyWithSubFolder("*Gherkin*.xml", false); + } + + @Test + public void testGherkinResultsMatrixProject() throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MatrixProject matrixProject = rule.createProject(MatrixProject.class, projectName); + matrixProject.setAxes(new AxisList(new Axis("osType", "Linux", "Windows"))); + + matrixProject.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + matrixProject.getPublishersList().add(new CucumberTestResultsActionPublisher("")); + matrixProject.setScm(new CopyResourceSCM("/helloCucumberWorld")); + + MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); + for (MatrixRun run : build.getExactRuns()) { + assertTestResultsEqual(tests, new File(run.getRootDir(), "mqmTests.xml")); + } +// Assert.assertEquals(new HashSet<>(Arrays.asList(projectName + "/osType=Windows#1", projectName + "/osType=Linux#1")), getQueuedItems()); + Assert.assertFalse(new File(build.getRootDir(), "mqmTests.xml").exists()); + } + + //@Test + public void testGherkinResultsWrongFile() throws Exception { + gherkinResults("pom.xml", false); + } + + //@Test + public void testGherkinResultsWrongLongFile() throws Exception { + gherkinResults("settings.xml", false); + } + + private void gherkinResults(String glob, boolean buildShouldSucceed) throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(), System.getenv("TEMP")), mavenName, null, null, "-Dmaven.test.failure.ignore=true")); + project.setScm(new CopyResourceSCM("/helloCucumberWorld")); + + project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); + + assertProject(project, buildShouldSucceed); + } + + private void gherkinResultsInSubFolder(String glob, boolean buildShouldSucceed) throws Exception { + String projectName = "root-job-" + UUID.randomUUID().toString(); + FreeStyleProject project = rule.createFreeStyleProject(projectName); + + project.getBuildersList().add(new Maven(String.format("--settings \"%s\\conf\\settings.xml\" clean test -Dmaven.repo.local=%s\\m2-temp", + TestUtils.getMavenHome(),System.getenv("TEMP")), mavenName, "subFolder/pom.xml", null, "-Dmaven.test.failure.ignore=true")); + project.setScm(new CopyResourceSCM("helloCucumberWorld", "subFolder")); + + project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); + + assertProject(project, buildShouldSucceed); + } + + private void gherkinResultsLegacy(String glob, boolean buildShouldSucceed) throws Exception { + MavenModuleSet project = prepareLegacyProject(false); + project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); + assertProject(project, buildShouldSucceed); + } + + private void gherkinResultsLegacyWithSubFolder(String glob, boolean buildShouldSucceed) throws Exception { + MavenModuleSet project = prepareLegacyProject(true); + project.getPublishersList().add(new CucumberTestResultsActionPublisher(glob)); + assertProject(project, buildShouldSucceed); + } + + private MavenModuleSet prepareLegacyProject(boolean subfolder) throws IOException { + String projectName = "root-job-" + UUID.randomUUID().toString(); + MavenModuleSet project = rule.createProject(MavenModuleSet.class, projectName); + project.runHeadless(); + + project.setMaven(mavenName); + project.setGoals(String.format("clean test --settings \"%s\\conf\\settings.xml\" -Dmaven.repo.local=%s\\m2-temp -Dmaven.test.failure.ignore=true", + TestUtils.getMavenHome(),System.getenv("TEMP"))); + if(subfolder) { + project.setRootPOM("subFolder/pom.xml"); + project.setScm(new CopyResourceSCM("/helloCucumberWorld", "subFolder")); + } else { + project.setScm(new CopyResourceSCM("/helloCucumberWorld")); + } + return project; + } + + private void assertProject(AbstractProject project, boolean buildShouldSucceed) throws Exception { + if(buildShouldSucceed) { + AbstractBuild build = TestUtils.runAndCheckBuild(project); + assertTestResultsEqual(tests, new File(build.getRootDir(), "mqmTests.xml")); +// Assert.assertEquals(Collections.singleton(project.getName() + "#1"), getQueuedItems()); + } else { + AbstractBuild build = (AbstractBuild) project.scheduleBuild2(0).get(); + Assert.assertEquals("Build should fail", Result.FAILURE, build.getResult()); +// Assert.assertEquals("Expects empty queue", 0, getQueuedItems().size()); + } + } + + private void assertTestResultsEqual(Set expected, File actual) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document actualDoc = dBuilder.parse(actual); + + NodeList actualTests = actualDoc.getElementsByTagName("gherkin_test_run"); + Assert.assertEquals("Number of tests should be equal", expected.size(), actualTests.getLength()); + + NodeList automatedTests = actualDoc.getElementsByTagName("test_run"); + Assert.assertEquals("There should be no automated tests", 0, automatedTests.getLength()); + + int i=0; + for (String expectedName : expected) { + Node actualTest = actualTests.item(i++); + Assert.assertEquals("Test name should be equal", expectedName, getAttr(actualTest, "name")); + Assert.assertEquals("Test status should be equal", "Passed", getAttr(actualTest, "status")); + } + } + + private String getAttr(Node node, String attrName) { + return node.getAttributes().getNamedItem(attrName).getNodeValue(); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java b/src/test/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java new file mode 100644 index 0000000000..413e991f66 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/octane/tests/xml/TestResultXmlWriterTest.java @@ -0,0 +1,115 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.octane.tests.xml; + +import com.hp.octane.integrations.testresults.XmlWritableTestResult; +import com.microfocus.application.automation.tools.model.OctaneServerSettingsModel; +import com.microfocus.application.automation.tools.octane.OctaneServerMock; +import com.microfocus.application.automation.tools.octane.OctanePluginTestBase; +import com.microfocus.application.automation.tools.octane.configuration.ConfigurationService; +import com.microfocus.application.automation.tools.octane.tests.TestResultContainer; +import com.microfocus.application.automation.tools.octane.tests.TestResultIterable; +import com.microfocus.application.automation.tools.octane.tests.TestResultIterator; +import com.microfocus.application.automation.tools.octane.tests.TestUtils; +import com.microfocus.application.automation.tools.octane.tests.detection.ResultFields; +import com.microfocus.application.automation.tools.octane.tests.junit.JUnitTestResult; +import com.microfocus.application.automation.tools.octane.tests.junit.TestResultStatus; +import hudson.FilePath; +import hudson.matrix.Axis; +import hudson.matrix.AxisList; +import hudson.matrix.MatrixBuild; +import hudson.matrix.MatrixProject; +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import hudson.util.Secret; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/*** + * Tests on TestResultXmlWriter + */ +@SuppressWarnings({"squid:S2698", "squid:S2699"}) +public class TestResultXmlWriterTest extends OctanePluginTestBase { + private static TestResultContainer container; + + @BeforeClass + public static void initialize() { + List testResults = new ArrayList<>(); + testResults.add(new JUnitTestResult("module", "package", "class", "testName", TestResultStatus.PASSED, 1, 2, null, null, null, null,null, null, false)); + container = new TestResultContainer(testResults.iterator(), new ResultFields()); + OctaneServerMock serverMock = OctaneServerMock.getInstance(); + OctaneServerSettingsModel model = new OctaneServerSettingsModel( + "http://127.0.0.1:" + serverMock.getPort() + "/ui?p=1001", + "username", + Secret.fromString("password"), + ""); + ConfigurationService.configurePlugin(model); + } + + @Test + public void testFreestyleProject() throws Exception { + FreeStyleProject project = rule.createFreeStyleProject("freestyle-project"); + FreeStyleBuild build = (FreeStyleBuild) TestUtils.runAndCheckBuild(project); + assertBuildType(build, "freestyle-project", null); + } + + @Test + public void testMatrixProject() throws Exception { + MatrixProject matrixProject = rule.createProject(MatrixProject.class, "matrix-project"); + matrixProject.setAxes(new AxisList(new Axis("OS", "Linux"))); + MatrixBuild build = (MatrixBuild) TestUtils.runAndCheckBuild(matrixProject); + Assert.assertEquals(1, build.getExactRuns().size()); + assertBuildType(build.getExactRuns().get(0), "matrix-project", "OS=Linux"); + } + + private void assertBuildType(AbstractBuild build, String jobName, String matrixExtendedName) throws IOException, XMLStreamException, InterruptedException { + Assert.assertNotNull(build); + Assert.assertNotNull(build.getWorkspace()); + FilePath testXml = new FilePath(build.getWorkspace(), "test.xml"); + TestResultXmlWriter xmlWriter = new TestResultXmlWriter(testXml, build); + xmlWriter.writeResults(container); + xmlWriter.close(); + + TestResultIterator iterator = new TestResultIterable(new File(testXml.getRemote())).iterator(); + Assert.assertEquals(jobName + (matrixExtendedName == null ? "" : "/" + matrixExtendedName), iterator.getJobId()); + Assert.assertEquals(matrixExtendedName, iterator.getSubType()); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/MockPcModel.java b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcModel.java new file mode 100644 index 0000000000..85739fbc9c --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcModel.java @@ -0,0 +1,61 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; +import com.microfocus.application.automation.tools.model.SecretContainer; +import com.microfocus.application.automation.tools.model.SecretContainerTest; + +public class MockPcModel extends PcModel { + + + public MockPcModel(String serverAndPort, String pcServerName, String credential, String almDomain, + String almProject, String testId, String autoTestInstanceID, String testInstanceId, String timeslotDurationHours, + String timeslotDurationMinutes, PostRunAction postRunAction, boolean vudsMode, String description, boolean webProtocol, String retry, String retryDelay, String retryOccurrences, boolean authenticateWithToken) { + super(serverAndPort, pcServerName, credential, almDomain, almProject, testId, autoTestInstanceID, testInstanceId, timeslotDurationHours, + timeslotDurationMinutes, postRunAction, vudsMode, description, "NO_TREND", null,false,null,null, retry, retryDelay, retryOccurrences, authenticateWithToken + ); + } + + @Override + protected SecretContainer setPassword(String almPassword) { + + SecretContainer secretContainer = new SecretContainerTest(); + secretContainer.initialize(almPassword); + + return secretContainer; + } + + + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxy.java b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxy.java new file mode 100644 index 0000000000..938180911f --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxy.java @@ -0,0 +1,112 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Iterator; + +import com.microfocus.application.automation.tools.run.PcBuilder; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.FileEntity; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHttpResponse; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; + +import static com.microfocus.adm.performancecenter.plugins.common.pcentities.RunState.*; +import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy; + +public class MockPcRestProxy extends PcRestProxy { + + private static Iterator runState = initializeRunStateIterator(); + + public MockPcRestProxy(String webProtocol, String pcServerName, boolean authenticateWithToken, String almDomain, String almProject,PrintStream logger) throws PcException { + super(webProtocol, pcServerName, authenticateWithToken, almDomain, almProject,null,null,null); + } + + @Override + protected HttpResponse executeRequest(HttpRequestBase request) throws PcException, ClientProtocolException, + IOException { + HttpResponse response = null; + String requestUrl = request.getURI().toString(); + if (requestUrl.equals(String.format(AUTHENTICATION_LOGIN_URL, PcTestBase.WEB_PROTOCOL, PcTestBase.PC_SERVER_NAME)) + || requestUrl.equals(String.format(AUTHENTICATION_LOGOUT_URL, + PcTestBase.WEB_PROTOCOL, PcTestBase.PC_SERVER_NAME)) + || requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID, PcTestBase.STOP_MODE))) { + response = getOkResponse(); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s", RUNS_RESOURCE_NAME)) + || requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID))) { + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.runResponseEntity)); + } else if(requestUrl.equals(String.format(getBaseURL() + "/%s", TESTS_RESOURCE_NAME)) + || requestUrl.equals(String.format(getBaseURL() + "/%s/%s", TESTS_RESOURCE_NAME, PcTestBase.TEST_ID))){ + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.testResponseEntity)); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID_WAIT))) { + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.runResponseEntity.replace("*", runState.next().value()))); + if (!runState.hasNext()) + runState = initializeRunStateIterator(); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID, + RESULTS_RESOURCE_NAME))) { + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.runResultsEntity)); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s/%s/data", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID, + RESULTS_RESOURCE_NAME, PcTestBase.REPORT_ID))) { + response = getOkResponse(); + response.setEntity(new FileEntity( + new File(getClass().getResource(PcBuilder.pcReportArchiveName).getPath()), ContentType.DEFAULT_BINARY)); + } + if (response == null) + throw new PcException(String.format("%s %s is not recognized by PC Rest Proxy", request.getMethod(), requestUrl)); + return response; + } + + private HttpResponse getOkResponse(){ + + return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + } + + private static Iterator initializeRunStateIterator(){ + + return Arrays.asList(INITIALIZING,RUNNING,COLLATING_RESULTS,CREATING_ANALYSIS_DATA,FINISHED).iterator(); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxyBadResponses.java b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxyBadResponses.java new file mode 100644 index 0000000000..a0743ddab8 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/MockPcRestProxyBadResponses.java @@ -0,0 +1,97 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Iterator; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHttpResponse; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; + +import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy; + +import static com.microfocus.adm.performancecenter.plugins.common.pcentities.RunState.*; + +public class MockPcRestProxyBadResponses extends PcRestProxy { + + private static Iterator runState = initializeRunStateIterator(); + + public MockPcRestProxyBadResponses(String webProtocol, String pcServerName, boolean authenticateWithToken, String almDomain, String almProject,PrintStream logger) throws PcException { + super(webProtocol, pcServerName, authenticateWithToken, almDomain, almProject,null,null, null); + } + + @Override + protected HttpResponse executeRequest(HttpRequestBase request) throws PcException, ClientProtocolException, + IOException { + HttpResponse response = null; + String requestUrl = request.getURI().toString(); + if (requestUrl.equals(String.format(AUTHENTICATION_LOGIN_URL, PcTestBase.WEB_PROTOCOL, PcTestBase.PC_SERVER_NAME))) { + throw new PcException(PcTestBase.pcAuthenticationFailureMessage); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s", RUNS_RESOURCE_NAME))){ + throw new PcException(PcTestBase.pcNoTimeslotExceptionMessage); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID_WAIT))) { + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.runResponseEntity.replace("*", runState.next().value()))); + if (!runState.hasNext()) + runState = initializeRunStateIterator(); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID, + RESULTS_RESOURCE_NAME))) { + response = getOkResponse(); + response.setEntity(new StringEntity(PcTestBase.emptyResultsEntity)); + } else if (requestUrl.equals(String.format(getBaseURL() + "/%s/%s/%s", RUNS_RESOURCE_NAME, PcTestBase.RUN_ID, PcTestBase.STOP_MODE))) { + throw new PcException(PcTestBase.pcStopNonExistRunFailureMessage); + } + if (response == null) + throw new PcException(String.format("%s %s is not recognized by PC Rest Proxy", request.getMethod(), requestUrl)); + return response; + } + + private HttpResponse getOkResponse(){ + + return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); + } + + private static Iterator initializeRunStateIterator() { + + return Arrays.asList(INITIALIZING, RUNNING, RUN_FAILURE).iterator(); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/PcTestBase.java b/src/test/java/com/microfocus/application/automation/tools/pc/PcTestBase.java new file mode 100644 index 0000000000..1748e584cd --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/PcTestBase.java @@ -0,0 +1,131 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; + +import java.io.PrintStream; + +public interface PcTestBase { + + public static final String SERVER_AND_PORT = "jenkins.server:8082"; + public static final String PC_SERVER_NAME = "pcServer.hp.com"; + public static final String CREDENTIALSID = "123456789"; + public static final String ALM_DOMAIN = "ALMDOM"; + public static final String ALM_PROJECT = "ALMPROJ"; + public static final String TEST_ID = "1"; + public static final String TEST_INSTANCE_ID = "2"; + public static final String TIMESLOT_DURATION_HOURS = "0"; + public static final String TIMESLOT_DURATION_MINUTES = "34"; + public static final String TIMESLOT_ID = "56"; + public static final PostRunAction POST_RUN_ACTION = PostRunAction.COLLATE_AND_ANALYZE; + public static final boolean VUDS_MODE = false; + public static final String DESCRIPTION = "Testing HPE Performance Center Jenkins plugin"; + public static final String RUN_ID = "7"; + public static final String RUN_ID_WAIT = "8"; + public static final String REPORT_ID = "9"; + public static final String STOP_MODE = "stop"; + public static final String WEB_PROTOCOL = "http"; + public static final Boolean IS_HTTPS = false; + public static final String TESTINSTANCEID = "MANUAL"; + public static final PrintStream LOGGER = null; + public static final String RETRY = "NO_RETRY"; + public static final String RETRYDELAY = "5"; + public static final String RETRYOCCURRENCES = "3"; + public static final boolean AUTHENTICATE_WITH_TOKEN = false; + + public static final MockPcModel pcModel = new MockPcModel(SERVER_AND_PORT,PC_SERVER_NAME, CREDENTIALSID, ALM_DOMAIN, ALM_PROJECT, + TEST_ID,TESTINSTANCEID, TEST_INSTANCE_ID, + TIMESLOT_DURATION_HOURS, + TIMESLOT_DURATION_MINUTES, POST_RUN_ACTION, + VUDS_MODE, DESCRIPTION,IS_HTTPS, RETRY, RETRYDELAY, RETRYOCCURRENCES, AUTHENTICATE_WITH_TOKEN); + + public static final String runResponseEntity = "" + + "" + TEST_ID + "" + + "" + TEST_INSTANCE_ID + "" + + "" + POST_RUN_ACTION.getValue() + "" + + "1076" + + "false" + + "" + RUN_ID + "" + + "" + TIMESLOT_DURATION_MINUTES + "" + + "*" + + "" + + ""; + + public static final String emptyResultsEntity = ""; + + public static final String runResultsEntity = "" + + "" + + "1302" + + "output.mdb.zip" + + "Output Log" + + "" + RUN_ID + "" + + "" + + "" + + "1303" + + "RawResults.zip" + + "Raw Results" + + "" + RUN_ID + "" + + "" + + "" + + "1304" + + "Results.zip" + + "Analyzed Result" + + "" + RUN_ID + "" + + "" + + "" + + "" + REPORT_ID + "" + + "Reports.zip" + + "HTML Report" + + "" + RUN_ID + "" + + "" + + "" + + "1306" + + "HighLevelReport_7.xls" + + "Rich Report" + + "" + RUN_ID + "" + + "" + + ""; + + public static final String pcAuthenticationFailureMessage = "Exception of type 'HPE.PC.API.Model.Exceptions.InvalidAuthenticationDataException' was thrown. Error code: 1100"; + + public static final String pcNoTimeslotExceptionMessage = "Failed to retrieve reservation information for reservation " + TIMESLOT_ID + ". Error code: 1202"; + + public static final String pcStopNonExistRunFailureMessage = "Failed to retrieve run " + RUN_ID + " information from domain " + ALM_DOMAIN + ", project " + ALM_PROJECT + ". Error code: 1300"; + + public static final String testResponseEntity = "" + + "2" + + "test1" + + ""; + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClient.java b/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClient.java new file mode 100644 index 0000000000..76719d0e7a --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClient.java @@ -0,0 +1,120 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import com.microfocus.application.automation.tools.run.PcBuilder; +import hudson.FilePath; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy; + +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; + +@SuppressWarnings({"squid:S2699","squid:S3658"}) +public class TestPcClient { + + private static PcClient pcClient; + public final String RESOURCES_DIR = getClass().getResource("").getPath(); + + @BeforeClass + public static void setUp() { + try { + PcRestProxy resetProxy = new MockPcRestProxy(PcTestBase.WEB_PROTOCOL, PcTestBase.PC_SERVER_NAME, PcTestBase.AUTHENTICATE_WITH_TOKEN, PcTestBase.ALM_DOMAIN, + PcTestBase.ALM_PROJECT,PcTestBase.LOGGER); + pcClient = new PcClient(PcTestBase.pcModel, System.out, resetProxy); + } catch (Exception e) { + e.printStackTrace(System.out); + } + } + + @Test + public void testStartRun(){ + System.out.println("Testing Start Run with PC client"); + try { + Assert.assertTrue("Failed to start run with pcClient", pcClient.startRun() > 0); + } catch (Exception e) { + Assert.fail(e.toString()); + } + } + + @Test (timeout=5000) + public void testWaitForRunCompletion(){ + + System.out.println("Testing Wait for Run Completion with PC client"); + try { + PcRunResponse response = pcClient.waitForRunCompletion(Integer.parseInt(PcTestBase.RUN_ID_WAIT), 200); + Assert.assertEquals(response.getRunState(), RunState.FINISHED.value()); + } catch (InterruptedException e) { + Assert.fail("pcClient did not return from waitForRunCompletion (test run has timed out)"); + }catch (Exception e) { + Assert.fail(e.toString()); + } + } + + @Test + public void testPublishRunReport(){ + + System.out.println("Testing Publish PC Run Report to Jenkins server with PC client"); + try { + + FilePath reportHtml = pcClient.publishRunReport(Integer.parseInt(PcTestBase.RUN_ID), + String.format(PcBuilder.getRunReportStructure(), RESOURCES_DIR, PcBuilder.getArtifactsDirectoryName(), PcTestBase.RUN_ID)); + Assert.assertTrue("Failed to publish PC run report", reportHtml.exists()); + try { + // Test cleanup + reportHtml.getParent().getParent().getParent().deleteRecursive(); + } catch (Exception e) { + } + } catch (Exception e) { + Assert.fail(e.toString()); + } + } + + @Test + public void testLogout() { + System.out.println("Testing Logout from PC server"); + Assert.assertTrue("Failed to logout with pcClient", pcClient.logout()); + } + + @Test + public void testStopRun() { + System.out.println("Testing Stop Run with PC client"); + Assert.assertTrue("Failed to stop run with pcClient", pcClient.stopRun(Integer.parseInt(PcTestBase.RUN_ID))); + } + + +} + diff --git a/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClientNegativeScenrios.java b/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClientNegativeScenrios.java new file mode 100644 index 0000000000..2145d5d407 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pc/TestPcClientNegativeScenrios.java @@ -0,0 +1,127 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pc; + +import com.microfocus.application.automation.tools.run.PcBuilder; +import hudson.FilePath; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; + +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy; +import com.microfocus.adm.performancecenter.plugins.common.pcentities.*; + +@SuppressWarnings({"squid:S2699","squid:S3658"}) +public class TestPcClientNegativeScenrios { + + private static PcClient pcClient; + public final String RESOURCES_DIR = getClass().getResource("").getPath(); + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @BeforeClass + public static void setUp() { + System.out.println("Starting Performance Center client negative testing scenarios:"); + try { + PcRestProxy resetProxy = new MockPcRestProxyBadResponses(PcTestBase.WEB_PROTOCOL,PcTestBase.PC_SERVER_NAME, PcTestBase.AUTHENTICATE_WITH_TOKEN, PcTestBase.ALM_DOMAIN, + PcTestBase.ALM_PROJECT,PcTestBase.LOGGER); + pcClient = new PcClient(PcTestBase.pcModel, new PrintStream(new OutputStream() { + + @Override + public void write(int b) throws IOException {} + + }), resetProxy); + } catch (Exception e) { + e.printStackTrace(System.out); + } + } + + @AfterClass + public static void tearDown() { + System.out.println("End of Performance Center client negative testing scenarios"); + } + + @Test + public void testLoginWithWrongCredentials() { + + System.out.println("Testing Login to PC server with wrong credentials"); + Assert.assertFalse("Login to PC server with wrong creadentials should have failed", pcClient.login()); + } + + @Test(timeout = 5000) + public void testHandleRunFailureWhileWaitingForRunCompletion() { + + System.out.println("Testing Wait For Run Completion with PC client while run fails"); + try { + PcRunResponse response = pcClient.waitForRunCompletion(Integer.parseInt(PcTestBase.RUN_ID_WAIT), 200); + Assert.assertEquals(response.getRunState(), RunState.RUN_FAILURE.value()); + } catch (InterruptedException e) { + Assert.fail("pcClient did not return from waitForRunCompletion (test run has timed out)"); + } catch (Exception e) { + Assert.fail(e.toString()); + } + } + + @Test + public void testPublishRunReportWithEmptyResults() { + + System.out.println("Testing Publish PC Run Report to while run results are empty"); + try { + + FilePath reportHtml = pcClient.publishRunReport(Integer.parseInt(PcTestBase.RUN_ID), + String.format(PcBuilder.getRunReportStructure(), RESOURCES_DIR, PcBuilder.getArtifactsDirectoryName(),PcTestBase.RUN_ID)); + Assert.assertNull("pcClient.publishRunReport should have returned null due to empty run results", + reportHtml); + } catch (Exception e) { + Assert.fail("pcClient.publishRunReport threw an exception (should have returned null due to empty run results): " + + e.toString()); + } + } + + @Test + public void testStopNonExistingRun() { + + System.out.println("Testing stopping a non-exising run with PC client"); + Assert.assertFalse("Stopping a non-existing run should have failed", pcClient.stopRun(Integer.parseInt(PcTestBase.RUN_ID))); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java b/src/test/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java new file mode 100644 index 0000000000..46fa74b6ad --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/pipelineSteps/LrScenarioLoadStepTest.java @@ -0,0 +1,81 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.pipelineSteps; + +import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +/** +* LoadRunnerTestStep Tester. +* +* @author +* @since
      ??? 28, 2016
      +* @version 1.0 +*/ +@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607","squid:S2701"}) +public class LrScenarioLoadStepTest { + + @Rule + public JenkinsRule jenkinsRule = new JenkinsRule(); + + + @Before + public void before() throws Exception { + } + + @After + public void after() throws Exception { + } + + /** + * Method: runLoadRunnerScenario + */ + @Test + public void testLrScenarioRun() throws Exception { + // Setup the job + WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "foo"); + job.setDefinition(new CpsFlowDefinition("node {}")); // insert here the pipeline code to run + + //run the build nad wait for successful result + WorkflowRun workflowRun = jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0).get()); + + //now we need to check the results. + + } +} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/results/RunResultRecorderTest.java b/src/test/java/com/microfocus/application/automation/tools/results/RunResultRecorderTest.java similarity index 86% rename from src/test/java/com/hp/application/automation/tools/results/RunResultRecorderTest.java rename to src/test/java/com/microfocus/application/automation/tools/results/RunResultRecorderTest.java index c3e790bc7e..ab11a1059a 100644 --- a/src/test/java/com/hp/application/automation/tools/results/RunResultRecorderTest.java +++ b/src/test/java/com/microfocus/application/automation/tools/results/RunResultRecorderTest.java @@ -1,23 +1,40 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.results; +package com.microfocus.application.automation.tools.results; -import com.hp.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; -import com.hp.application.automation.tools.results.projectparser.performance.LrJobResults; +import com.microfocus.application.automation.tools.results.projectparser.performance.JobLrScenarioResult; +import com.microfocus.application.automation.tools.results.projectparser.performance.LrJobResults; +import com.microfocus.application.automation.tools.model.ResultsPublisherModel; import hudson.FilePath; import org.junit.After; import org.junit.Before; @@ -27,9 +44,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.List; -import static com.hp.application.automation.tools.model.ResultsPublisherModel.CreateHtmlReportResults; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -367,7 +382,7 @@ public void testBuildJobDataset() throws Exception { public void testCreatingJobDataSet() { try { - RunResultRecorder runResultRecorder = new RunResultRecorder(CreateHtmlReportResults.getValue()); + RunResultRecorder runResultRecorder = new RunResultRecorder(ResultsPublisherModel.CreateHtmlReportResults.getValue()); Method parseScenarioResults = runResultRecorder.getClass().getDeclaredMethod("parseScenarioResults", FilePath.class); parseScenarioResults.setAccessible(true); @@ -404,7 +419,7 @@ public void testCreatingJobDataSet() @Test public void testParseScenarioResults() throws Exception { - RunResultRecorder runResultRecorder = new RunResultRecorder(CreateHtmlReportResults.getValue()); + RunResultRecorder runResultRecorder = new RunResultRecorder(ResultsPublisherModel.CreateHtmlReportResults.getValue()); FilePath runReportPath = new FilePath(new File(getClass().getResource("RunReport.xml").getPath())); JobLrScenarioResult result = null; try { diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/AntTESTS-TestSuites.xml b/src/test/java/com/microfocus/application/automation/tools/results/parser/AntTESTS-TestSuites.xml similarity index 83% rename from src/test/java/com/hp/application/automation/tools/results/parser/AntTESTS-TestSuites.xml rename to src/test/java/com/microfocus/application/automation/tools/results/parser/AntTESTS-TestSuites.xml index 976dfcb1b8..105718514e 100644 --- a/src/test/java/com/hp/application/automation/tools/results/parser/AntTESTS-TestSuites.xml +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/AntTESTS-TestSuites.xml @@ -1,4 +1,36 @@ + + diff --git a/src/test/java/com/hp/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml b/src/test/java/com/microfocus/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml similarity index 79% rename from src/test/java/com/hp/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml rename to src/test/java/com/microfocus/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml index d837b57cc5..cd6694d18a 100644 --- a/src/test/java/com/hp/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/MAVENTEST-com.demoapp.demo.AppTest.xml @@ -1,4 +1,35 @@ + diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/NUnitReport.xml b/src/test/java/com/microfocus/application/automation/tools/results/parser/NUnitReport.xml new file mode 100644 index 0000000000..a4cc6de841 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/NUnitReport.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java new file mode 100644 index 0000000000..bdca46461c --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestAntJUnitReportParserImpl.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import org.junit.Assert; + +import com.microfocus.application.automation.tools.results.parser.antjunit.AntJUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +@SuppressWarnings("squid:S2698") +public class TestAntJUnitReportParserImpl { + + //@Test + public void testParseTestSets() throws Exception { + InputStream in = TestAntJUnitReportParserImpl.class.getResourceAsStream("AntTESTS-TestSuites.xml"); + AntJUnitReportParserImpl parser = new AntJUnitReportParserImpl(); + List testsets = parser.parseTestSets(in, "JUnit", "Ant"); + Assert.assertEquals(testsets.size(), 1); + Assert.assertEquals("TestProg1Prj1Test1", testsets.get(0).getName() ); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java new file mode 100644 index 0000000000..6c66204a64 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestJenkinsJunitReportParserImpl.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import com.microfocus.application.automation.tools.results.parser.jenkinsjunit.JenkinsJUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import org.junit.Assert; + +@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872"}) +public class TestJenkinsJunitReportParserImpl { + + //@Test + public void testParseTestSets() throws Exception { + InputStream in = TestJenkinsJunitReportParserImpl.class.getResourceAsStream("junitResult.xml"); + JenkinsJUnitReportParserImpl parser = new JenkinsJUnitReportParserImpl(); + List testsets = parser.parseTestSets(in, "JUnit", "LeanFT"); + Assert.assertEquals(1, testsets.size()); + Assert.assertEquals("prog1prj1.TestProg1Prj1Test1", testsets.get(0).getName()); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java new file mode 100644 index 0000000000..8f02597170 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestMavenSureFireReportParserImpl.java @@ -0,0 +1,55 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import com.microfocus.application.automation.tools.results.parser.mavensurefire.MavenSureFireReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import org.junit.Assert; + + +public class TestMavenSureFireReportParserImpl { + + //@Test + public void testParseTestSets()throws Exception { + InputStream in = TestMavenSureFireReportParserImpl.class.getResourceAsStream("MAVENTEST-com.demoapp.demo.AppTest.xml"); + MavenSureFireReportParserImpl parser = new MavenSureFireReportParserImpl(); + List testsets = parser.parseTestSets(in, "JUnit", "Maven"); + assert (testsets.size () == 1); + AlmTestSet testset = testsets.get(0); + Assert.assertEquals("com.demoapp.demo.AppTest", testset.getName()); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/TestNUnitReportParserImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestNUnitReportParserImpl.java new file mode 100644 index 0000000000..ecec08f54f --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestNUnitReportParserImpl.java @@ -0,0 +1,54 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import com.microfocus.application.automation.tools.results.parser.nunit.NUnitReportParserImpl; +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import org.junit.Assert; + +@SuppressWarnings({"squid:S2699","squid:S3658"}) +public class TestNUnitReportParserImpl { + + //@Test + public void testParseTestSets() throws Exception{ + InputStream in = TestNUnitReportParserImpl.class.getResourceAsStream("NUnitReport.xml"); + NUnitReportParserImpl parser = new NUnitReportParserImpl(); + List testsets = parser.parseTestSets(in, "NUnit", "Selenium"); + Assert.assertEquals(1, testsets.size()); + Assert.assertEquals("NUnit_Test1.dll_ExampleTestOfNUnit", testsets.get(0).getName()); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java new file mode 100644 index 0000000000..4f1f6acca0 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/TestTestNGXmlReportParserImpl.java @@ -0,0 +1,57 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.parser; + +import java.io.InputStream; +import java.util.List; + +import com.microfocus.application.automation.tools.results.service.almentities.AlmTestSet; +import org.junit.Assert; + +import com.microfocus.application.automation.tools.results.parser.testngxml.TestNGXmlReportParserImpl; + +@SuppressWarnings("squid:S2698") +public class TestTestNGXmlReportParserImpl { + + //@Test + public void testParseTestSets() throws Exception { + + InputStream in = TestTestNGXmlReportParserImpl.class.getResourceAsStream("testng-results.xml"); + TestNGXmlReportParserImpl parser = new TestNGXmlReportParserImpl(); + List testsets = parser.parseTestSets(in, "TestNG", "jenkins"); + + Assert.assertEquals(1, testsets.size()); + Assert.assertEquals("Suite1", testsets.get(0).getName()); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/junitResult.xml b/src/test/java/com/microfocus/application/automation/tools/results/parser/junitResult.xml new file mode 100644 index 0000000000..c268b14b36 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/junitResult.xml @@ -0,0 +1,74 @@ + + + + + + + C:\QC\Jenkins\workspace\test1\prog1prj1\output\TEST-prog1prj1.TestProg1Prj1Test1.xml + prog1prj1.TestProg1Prj1Test1 + + + 0.064 + 2015-05-12T12:23:27 + + + 0.002 + prog1prj1.TestProg1Prj1Test1 + testMethod1 + false + 0 + + + 0.001 + prog1prj1.TestProg1Prj1Test1 + testMethod2 + false + 0 + + + 0.061 + prog1prj1.TestProg1Prj1Test1 + testMethod3 + false + junit.framework.AssertionFailedError: Not yet implemented + at prog1prj1.TestProg1Prj1Test1.testMethod3(Unknown Source) + + Not yet implemented + 0 + + + + + 0.064 + false + \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/results/parser/testng-results.xml b/src/test/java/com/microfocus/application/automation/tools/results/parser/testng-results.xml new file mode 100644 index 0000000000..54ff8b7e68 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/parser/testng-results.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/com/microfocus/application/automation/tools/results/service/NUnitReport.xml b/src/test/java/com/microfocus/application/automation/tools/results/service/NUnitReport.xml new file mode 100644 index 0000000000..a4cc6de841 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/service/NUnitReport.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java b/src/test/java/com/microfocus/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java new file mode 100644 index 0000000000..2011208b71 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/service/TestDefaultExternalEntityUploadServiceImpl.java @@ -0,0 +1,140 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.results.service; + +import hudson.model.AbstractBuild; +import hudson.model.FreeStyleProject; +//import org.junit.Before; +//import org.junit.ClassRule; +//import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +import java.io.IOException; + +public class TestDefaultExternalEntityUploadServiceImpl { + + FreeStyleProject project; + + public static final JenkinsRule jenkins = new JenkinsRule(); + + public void initialize() throws IOException { + project = jenkins.createFreeStyleProject("freestyle-project"); + } + + public void testJunit() throws Exception{ + AlmRestInfo loginInfo = new AlmRestInfo( + "http://localhost:8085/qcbin", + "DEFAULT", + null, + "testexternal1", + "sa", + "", + "" + ); + int i = 107; + AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); + + AbstractBuild build = project.scheduleBuild2(0).get(); + + IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, build.getWorkspace(), new SystemOutLogger()); + String reportFilePath = this.getClass().getResource("junitResult.xml").getPath(); + String testingFramework = "JUnit"; + String testingTool = "Jenkins"; + String subversion = "1"; + String testFolderPath = "Import\\New Test Folder\\junit" + i; + String testsetFolderPath = "Import\\New Test Set Folder\\junit" +i; + long start = System.currentTimeMillis(); + service.uploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); + long end = System.currentTimeMillis(); + System.out.println("total time:" + (end -start)); + } + + public void testtestNG() throws Exception{ + AlmRestInfo loginInfo = new AlmRestInfo( + "http://localhost:8085/qcbin", + "DEFAULT", + null, + "testexternal1", + "sa", + "", + "" + ); + + int i = 108; + AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); + + AbstractBuild build = project.scheduleBuild2(0).get(); + IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, build.getWorkspace(), new SystemOutLogger()); + + String reportFilePath = this.getClass().getResource("testng-results.xml").getPath(); + String testingFramework = "TestNG"; + String testingTool = "Jenkins testng"; + String subversion = "1"; + String testFolderPath = "Import\\New Test Folder\\testng"+i; + String testsetFolderPath = "Import\\New Test Set Folder\\testng"+i; + long start = System.currentTimeMillis(); + service.uploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); + long end = System.currentTimeMillis(); + System.out.println("total time:" + (end -start)); + } + + public void testnunit() throws Exception{ + int i = 109; + AlmRestInfo loginInfo = new AlmRestInfo( + "http://localhost:8085/qcbin", + "DEFAULT", + null, + "testexternal1", + "sa", + "", + "" + ); + AlmRestTool u = new AlmRestTool(loginInfo, new SystemOutLogger()); + + AbstractBuild build = project.scheduleBuild2(0).get(); + IExternalEntityUploadService service = new DefaultExternalEntityUploadServiceImpl(u, build.getWorkspace(), new SystemOutLogger()); + + String reportFilePath = this.getClass().getResource("NUnitReport.xml").getPath(); + + String testingFramework = "NUNit"; + String testingTool = "Jenkins nunit"; + String subversion = "1"; + String testFolderPath = "Import\\New Test Folder\\nunit"+i; + String testsetFolderPath = "Import\\New Test Set Folder\\nunit"+i; + long start = System.currentTimeMillis(); + service.uploadExternalTestSet(loginInfo,reportFilePath, testsetFolderPath, testFolderPath, testingFramework, testingTool, subversion, "local","http://localhost:8085/"); + long end = System.currentTimeMillis(); + System.out.println("total time:" + (end -start)); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/results/service/junitResult.xml b/src/test/java/com/microfocus/application/automation/tools/results/service/junitResult.xml new file mode 100644 index 0000000000..c268b14b36 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/service/junitResult.xml @@ -0,0 +1,74 @@ + + + + + + + C:\QC\Jenkins\workspace\test1\prog1prj1\output\TEST-prog1prj1.TestProg1Prj1Test1.xml + prog1prj1.TestProg1Prj1Test1 + + + 0.064 + 2015-05-12T12:23:27 + + + 0.002 + prog1prj1.TestProg1Prj1Test1 + testMethod1 + false + 0 + + + 0.001 + prog1prj1.TestProg1Prj1Test1 + testMethod2 + false + 0 + + + 0.061 + prog1prj1.TestProg1Prj1Test1 + testMethod3 + false + junit.framework.AssertionFailedError: Not yet implemented + at prog1prj1.TestProg1Prj1Test1.testMethod3(Unknown Source) + + Not yet implemented + 0 + + + + + 0.064 + false + \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/results/service/testng-results.xml b/src/test/java/com/microfocus/application/automation/tools/results/service/testng-results.xml new file mode 100644 index 0000000000..54ff8b7e68 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/results/service/testng-results.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/common/ConsoleLogger.java b/src/test/java/com/microfocus/application/automation/tools/sse/common/ConsoleLogger.java new file mode 100644 index 0000000000..2c5a8671c4 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/common/ConsoleLogger.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import com.microfocus.application.automation.tools.sse.sdk.Logger; + +public class ConsoleLogger implements Logger { + + @Override + public void log(String message) { + + System.out.println(message); + } + + @Override + public void error(String message) { + log(message); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/common/RestClient4Test.java b/src/test/java/com/microfocus/application/automation/tools/sse/common/RestClient4Test.java new file mode 100644 index 0000000000..bb8846178a --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/common/RestClient4Test.java @@ -0,0 +1,51 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.common; + +import com.microfocus.application.automation.tools.rest.RestClient; + +public class RestClient4Test extends RestClient { + private final static String AUTH_INFO_FRONT = ""; + private final static String AUTH_INFO_BACK = ""; + + public RestClient4Test(String url, String domain, String project, String username) { + super(url, domain, project, username); + } + + public byte[] getExpectAuthInfo() { + + String authInfo = AUTH_INFO_FRONT + getUsername() + AUTH_INFO_BACK; + + return authInfo.getBytes(); + } +} diff --git a/src/test/java/com/hp/application/automation/tools/sse/common/TestCase.java b/src/test/java/com/microfocus/application/automation/tools/sse/common/TestCase.java similarity index 90% rename from src/test/java/com/hp/application/automation/tools/sse/common/TestCase.java rename to src/test/java/com/microfocus/application/automation/tools/sse/common/TestCase.java index 3405835e7f..08898ffaba 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/common/TestCase.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/common/TestCase.java @@ -1,23 +1,39 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.common; +package com.microfocus.application.automation.tools.sse.common; -import com.hp.application.automation.tools.model.CdaDetails; -import com.hp.application.automation.tools.sse.sdk.Args; +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.sse.sdk.Args; public abstract class TestCase { @@ -62,6 +78,7 @@ protected Args createArgs() { return new Args( URL, DOMAIN, + null, PROJECT, USER, PASS, diff --git a/src/test/java/com/hp/application/automation/tools/sse/result/TestPublisher.java b/src/test/java/com/microfocus/application/automation/tools/sse/result/TestPublisher.java similarity index 84% rename from src/test/java/com/hp/application/automation/tools/sse/result/TestPublisher.java rename to src/test/java/com/microfocus/application/automation/tools/sse/result/TestPublisher.java index 671f95aca8..b5b4841f97 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/result/TestPublisher.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/result/TestPublisher.java @@ -1,38 +1,54 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.result; +package com.microfocus.application.automation.tools.sse.result; import java.net.HttpURLConnection; import java.util.List; import java.util.Map; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testcase; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuite; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import com.microfocus.application.automation.tools.sse.sdk.Client; +import com.microfocus.application.automation.tools.sse.sdk.ResourceAccessLevel; +import com.microfocus.application.automation.tools.sse.sdk.Response; import org.junit.Assert; import org.junit.Test; -import com.hp.application.automation.tools.sse.common.ConsoleLogger; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; -import com.hp.application.automation.tools.sse.result.model.junit.Testcase; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuite; -import com.hp.application.automation.tools.sse.result.model.junit.Testsuites; -import com.hp.application.automation.tools.sse.sdk.Client; -import com.hp.application.automation.tools.sse.sdk.ResourceAccessLevel; -import com.hp.application.automation.tools.sse.sdk.Response; +import com.microfocus.application.automation.tools.sse.common.ConsoleLogger; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; @SuppressWarnings("squid:S2699") public class TestPublisher extends TestCase { diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadDomain.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadDomain.java similarity index 81% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadDomain.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadDomain.java index c4ff7e3a27..8e3807459c 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadDomain.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadDomain.java @@ -1,25 +1,41 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; -import com.hp.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; public class MockRestClientBadDomain extends RestClient4Test { diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java similarity index 80% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java index 9f0bc6a2e6..60dc3b2bc4 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunEntity.java @@ -1,25 +1,41 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; -import com.hp.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; public class MockRestClientBadRunEntity extends RestClient4Test { @@ -55,7 +71,7 @@ public Response httpPost(String url, byte[] data, Map headers, R Response ret = new Response(); if (url.contains("startrun")) { - ret.setData("0com.hp.alm.platform.exception.CTdException: Failed to prepare timeslot for run. No entity of type test-set with id 5 exists.;".getBytes()); + ret.setData("0Failed to prepare timeslot for run. No entity of type TEST_SET with id 5 exists.".getBytes()); } ret.setStatusCode(201); diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java similarity index 81% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java index 7efb5f63dc..f2db674276 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientBadRunResponse.java @@ -1,25 +1,41 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; -import com.hp.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; public class MockRestClientBadRunResponse extends RestClient4Test { diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java similarity index 81% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java index f446cd7104..ef4011f1b4 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFailedLogin.java @@ -1,25 +1,41 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; -import com.hp.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; public class MockRestClientFailedLogin extends RestClient4Test { diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFunctional.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFunctional.java similarity index 85% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFunctional.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFunctional.java index bd66032d4f..ba97322f55 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/MockRestClientFunctional.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientFunctional.java @@ -1,25 +1,41 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; -import com.hp.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; public class MockRestClientFunctional extends RestClient4Test { diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientPC.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientPC.java new file mode 100644 index 0000000000..dad28cd581 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockRestClientPC.java @@ -0,0 +1,72 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.net.HttpURLConnection; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; + +public class MockRestClientPC extends RestClient4Test { + + public MockRestClientPC(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { + + Response ret = new Response(); + if (url.contains("rest/is-authenticated")) { + ret = new Response(null, getExpectAuthInfo(), null, HttpURLConnection.HTTP_OK); + } else if (url.contains("runs/")) { + ret.setData("12013-04-0931N/A9RuntimeOperations/RunStart.aspx?pcRunID=363&qcRunID=42sa15:52:53NRun Failure421009AdhocRun_2013-04-09 15:52:51N1_4252013-04-09 15:52:5141722013-04-09 15:52:53hp.pc.run.performance-testN0".getBytes()); + } + ret.setStatusCode(200); + + return ret; + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + Response ret = new Response(); + if (url.contains("startrun")) { + ret.setData("11005".getBytes()); + } + ret.setStatusCode(201); + + return ret; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockSseModel.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockSseModel.java new file mode 100644 index 0000000000..c8b87e103a --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/MockSseModel.java @@ -0,0 +1,82 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.model.ProxySettings; +import com.microfocus.application.automation.tools.model.SecretContainer; +import com.microfocus.application.automation.tools.model.SecretContainerTest; +import com.microfocus.application.automation.tools.model.SseModel; + +public class MockSseModel extends SseModel { + + public MockSseModel( + String almServerName, + String almUserName, + String almPassword, + String almDomain, + String almProject, + String runType, + String almEntityId, + String timeslotDuration, + String description, + String postRunAction, + String environmentConfigurationId, + CdaDetails cdaDetails, + ProxySettings proxySettings) { + + super( + almServerName, + almUserName, + almPassword, + almDomain, + null, + almProject, + runType, + almEntityId, + timeslotDuration, + description, + postRunAction, + environmentConfigurationId, + cdaDetails); + } + + @Override + protected SecretContainer setPassword(String almPassword) { + + SecretContainer secretContainer = new SecretContainerTest(); + secretContainer.initialize(almPassword); + + return secretContainer; + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestBvsRunHandler.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestBvsRunHandler.java new file mode 100644 index 0000000000..61aefa5541 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestBvsRunHandler.java @@ -0,0 +1,120 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import java.net.HttpURLConnection; +import java.util.Map; + +/** + * @author Effi Bar-She'an + */ +@Ignore +@SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109","squid:S1607"}) +public class TestBvsRunHandler extends TestCase { + + @Test + public void testStart() { + + Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); + Response response = + new RunHandlerFactory().create(client, "BVS", ENTITY_ID).start( + DURATION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + null); + Assert.assertTrue(response.isOk()); + } + + private class MockRestStartClient extends RestClient4Test { + + public MockRestStartClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } + + @Test + public void testStop() { + + Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); + Response response = new RunHandlerFactory().create(client, "BVS", "23").stop(); + Assert.assertTrue(response.isOk()); + } + + @Test + public void testReportUrl() { + + RunHandler handler = + new RunHandlerFactory().create( + new RestClient(URL, DOMAIN, PROJECT, USER), + "BVS", + "1001"); + handler.setRunId("1"); + Assert.assertTrue(String.format( + "%s/webui/alm/%s/%s/lab/index.jsp?processRunId=1", + URL, + DOMAIN, + PROJECT).equals( + handler.getReportUrl(createArgs()))); + + } + + private class MockRestStopClient extends RestClient4Test { + + public MockRestStopClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestEventLogHandler.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestEventLogHandler.java similarity index 83% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/TestEventLogHandler.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestEventLogHandler.java index a31654da07..3f154c23f1 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestEventLogHandler.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestEventLogHandler.java @@ -1,31 +1,46 @@ /* -/* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.EventLogHandler; import org.junit.Assert; import org.junit.Test; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.EventLogHandler; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; @SuppressWarnings({"squid:S2699","squid:S3658","squid:S2259","squid:S1872","squid:S2925","squid:S109"}) public class TestEventLogHandler extends TestCase { diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPCRunHandler.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPCRunHandler.java new file mode 100644 index 0000000000..aa1fc8cdb1 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPCRunHandler.java @@ -0,0 +1,126 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import org.junit.Assert; +import org.junit.Test; + +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; + +/** + * @author Effi Bar-She'an + * @author Dani Schreiber + */ +@SuppressWarnings({"squid:S2699","squid:S3658"}) +public class TestPCRunHandler extends TestCase { + + @Test + public void testStart() { + + Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); + Response response = + new RunHandlerFactory().create(client, "PC", ENTITY_ID).start( + DURATION, + POST_RUN_ACTION, + "", + null); + Assert.assertTrue(response.isOk()); + } + + private class MockRestStartClient extends RestClient4Test { + + public MockRestStartClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } + + @Test + public void testStop() { + + Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); + Response response = new RunHandlerFactory().create(client, "PC", "23").stop(); + Assert.assertTrue(response.isOk()); + } + + @Test + public void testReportUrl() { + RunHandler handler = + new RunHandlerFactory().create( + new RestClient(URL, DOMAIN, PROJECT, USER), + "PC", + "1001"); + handler.setRunId("1"); + + try { + Assert.assertTrue(String.format( + "td://%s.%s.%s:8080/qcbin/[TestRuns]?EntityLogicalName=run&EntityID=%s", + PROJECT, + DOMAIN, + new URL(URL).getHost(), + "1").equals( + handler.getReportUrl(createArgs()))); + } catch (MalformedURLException e) { + Assert.fail(); + } + + } + + private class MockRestStopClient extends RestClient4Test { + + public MockRestStopClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPollHandler.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPollHandler.java similarity index 76% rename from src/test/java/com/hp/application/automation/tools/sse/sdk/TestPollHandler.java rename to src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPollHandler.java index 933b70739d..a7f8169607 100644 --- a/src/test/java/com/hp/application/automation/tools/sse/sdk/TestPollHandler.java +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPollHandler.java @@ -1,32 +1,48 @@ /* - * Copyright 2017 Hewlett-Packard Development Company, L.P. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright 2012-2023 Open Text * - * 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. + * 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. + * ___________________________________________________________________ */ -package com.hp.application.automation.tools.sse.sdk; +package com.microfocus.application.automation.tools.sse.sdk; import java.net.HttpURLConnection; import java.util.Map; +import com.microfocus.application.automation.tools.sse.common.TestCase; import org.junit.Assert; import org.junit.Test; -import com.hp.application.automation.tools.sse.common.ConsoleLogger; -import com.hp.application.automation.tools.sse.common.RestClient4Test; -import com.hp.application.automation.tools.sse.common.TestCase; -import com.hp.application.automation.tools.sse.sdk.handler.PollHandler; -import com.hp.application.automation.tools.sse.sdk.handler.PollHandlerFactory; +import com.microfocus.application.automation.tools.sse.common.ConsoleLogger; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.sdk.handler.PollHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.PollHandlerFactory; @SuppressWarnings("squid:S2698") public class TestPollHandler extends TestCase { diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPostRequest.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPostRequest.java new file mode 100644 index 0000000000..f30cf40f2e --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestPostRequest.java @@ -0,0 +1,101 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.StringUtils; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.request.PostRequest; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; + +@SuppressWarnings("squid:S2699") +public class TestPostRequest extends TestCase { + + @Test + public void testPostRequestException() { + + Response response = + new MockPostRequest(new MockRestClientPostRequestException( + URL, + DOMAIN, + PROJECT, + USER), RUN_ID).execute(); + Assert.assertTrue(PostRequestException.class.equals(response.getFailure().getClass())); + } + + private class MockRestClientPostRequestException extends RestClient4Test { + + public MockRestClientPostRequestException( + String url, + String domain, + String project, + String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + throw new PostRequestException(); + } + } + + private class PostRequestException extends NullPointerException { + + private static final long serialVersionUID = 1L; + + } + + private class MockPostRequest extends PostRequest { + + protected MockPostRequest(Client client, String runId) { + + super(client, runId); + } + + @Override + protected String getSuffix() { + + return StringUtils.EMPTY_STRING; + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestAuthenticator.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestAuthenticator.java new file mode 100644 index 0000000000..4ea06482dc --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestAuthenticator.java @@ -0,0 +1,200 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.net.HttpURLConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.sdk.authenticator.RestAuthenticator; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.sse.common.ConsoleLogger; +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; + +@SuppressWarnings("squid:S2698") +public class TestRestAuthenticator extends TestCase { + + @Test + public void testLoginAlreadyAuthenticated() { + + Client client = new MockRestClientAlreadyAuthenticated(URL, DOMAIN, PROJECT, USER); + boolean ok = new RestAuthenticator().login(client, "tester", "blabla", "RESTClient", new ConsoleLogger()); + Assert.assertTrue(ok); + } + + public class MockRestClientAlreadyAuthenticated extends RestClient4Test { + + public MockRestClientAlreadyAuthenticated( + String url, + String domain, + String project, + String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, getExpectAuthInfo(), null, HttpURLConnection.HTTP_OK); + } + } + + @Test + public void testLoginNotAuthenticated() { + + Client client = new MockRestClientNotAuthenticated(URL, DOMAIN, PROJECT, USER); + boolean ok = new RestAuthenticator().login(client, "tester", "blabla", "RESTClient", new ConsoleLogger()); + Assert.assertTrue(ok); + } + + public class MockRestClientNotAuthenticated extends RestClient4Test { + + private int _time = 0; + private final String _isAuthenticatedUrl; + private final String _authenticationUrl; + + private MockRestClientNotAuthenticated( + String url, + String domain, + String project, + String username) { + + super(url, domain, project, username); + _isAuthenticatedUrl = build(RestAuthenticator.IS_AUTHENTICATED); + _authenticationUrl = build("authentication-point/authenticate"); + } + + @Override + public Response httpPost( + String url, + byte[] data, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + + @Override + public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { + + Response ret = null; + if (++_time == 1) { + Assert.assertEquals(_isAuthenticatedUrl, url); + ret = + new Response( + getAuthenticationHeaders(), + null, + null, + HttpURLConnection.HTTP_UNAUTHORIZED); + } else if (_time == 2) { + Assert.assertEquals(_authenticationUrl, url); + ret = new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + Assert.assertTrue("More than 2 calls to httpGet", _time < 3); + + return ret; + } + + private Map> getAuthenticationHeaders() { + + Map> ret = new HashMap>(1); + List values = new ArrayList(); + values.add(String.format("LWSSO realm=\"%s\"", build("authentication-point"))); + ret.put(RestAuthenticator.AUTHENTICATE_HEADER, values); + + return ret; + } + } + + @Test + public void testLoginFailedToLogin() { + + Client client = new MockRestClientFailedToLogin(URL, DOMAIN, PROJECT, USER); + boolean ok = new RestAuthenticator().login(client, "tester", "blabla", "RESTClient", new ConsoleLogger()); + Assert.assertFalse(ok); + } + + public class MockRestClientFailedToLogin extends RestClient4Test { + + private int _time = 0; + private final String _isAuthenticatedUrl; + private final String _authenticationUrl; + + private MockRestClientFailedToLogin( + String url, + String domain, + String project, + String username) { + + super(url, domain, project, username); + _isAuthenticatedUrl = build(RestAuthenticator.IS_AUTHENTICATED); + _authenticationUrl = build("authentication-point/authenticate"); + } + + @Override + public Response httpGet(String url, String queryString, Map headers, ResourceAccessLevel resourceAccessLevel) { + + Response ret = null; + if (++_time == 1) { + Assert.assertEquals(_isAuthenticatedUrl, url); + ret = + new Response( + getAuthenticationHeaders(), + null, + null, + HttpURLConnection.HTTP_UNAUTHORIZED); + } else if (_time == 2) { + Assert.assertEquals(_authenticationUrl, url); + ret = new Response(null, null, null, HttpURLConnection.HTTP_UNAUTHORIZED); + } + Assert.assertTrue("More than 2 calls to httpGet", _time < 3); + + return ret; + } + + private Map> getAuthenticationHeaders() { + + Map> ret = new HashMap>(1); + List values = new ArrayList(); + values.add(String.format("LWSSO realm=\"%s\"", build("authentication-point"))); + ret.put(RestAuthenticator.AUTHENTICATE_HEADER, values); + + return ret; + } + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestClient.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestClient.java new file mode 100644 index 0000000000..82c24c2cfc --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRestClient.java @@ -0,0 +1,75 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.sse.common.TestCase; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.rest.RestClient; + +@SuppressWarnings("squid:S2699") +public class TestRestClient extends TestCase { + + @Test + public void testBuild() { + + final String SUFFIX = "mysuffix"; + String url = new RestClient(URL, null, null, USER).build(SUFFIX); + + Assert.assertEquals(String.format("%s/%s", URL, SUFFIX), url); + } + + @Test + public void testBuildRequest() { + + final String SUFFIX = "mysuffix"; + String url = new RestClient(URL, DOMAIN, PROJECT, USER).buildRestRequest(SUFFIX); + + Assert.assertEquals( + String.format("%s/rest/domains/%s/projects/%s/%s", URL, DOMAIN, PROJECT, SUFFIX), + url); + } + + @Test + public void testBuildRequestWithSlash() { + final String URL = "http://16.55.245.168:8081/qcbin/"; + final String SUFFIX = "mysuffix"; + String url = new RestClient(URL, DOMAIN, PROJECT, USER).buildRestRequest(SUFFIX); + + Assert.assertEquals( + String.format("%srest/domains/%s/projects/%s/%s", URL, DOMAIN, PROJECT, SUFFIX), + url); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunHandlerFactory.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunHandlerFactory.java new file mode 100644 index 0000000000..787148a021 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunHandlerFactory.java @@ -0,0 +1,83 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import com.microfocus.application.automation.tools.sse.sdk.handler.TestSetRunHandler; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.sse.sdk.handler.BvsRunHandler; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandler; + +@SuppressWarnings("squid:S2699") +public class TestRunHandlerFactory extends TestCase { + + @Test + public void testRunHandlerBVS() { + + RunHandler runHandler = + new RunHandlerFactory().create(new MockRestClientFunctional( + URL, + DOMAIN, + PROJECT, + USER), SseModel.BVS, "1001"); + Assert.assertNotNull(runHandler); + Assert.assertTrue(runHandler.getClass() == BvsRunHandler.class); + } + + @Test + public void testRunHandlerTestSet() { + + RunHandler runHandler = + new RunHandlerFactory().create(new MockRestClientFunctional( + URL, + DOMAIN, + PROJECT, + USER), SseModel.TEST_SET, "1001"); + Assert.assertNotNull(runHandler); + Assert.assertTrue(runHandler.getClass() == TestSetRunHandler.class); + } + + @Test(expected = SSEException.class) + public void testRunHandlerUnrecognized() { + + new RunHandlerFactory().create( + new MockRestClientFunctional(URL, DOMAIN, PROJECT, USER), + "Custom", + "1001"); + } +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManager.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManager.java new file mode 100644 index 0000000000..3e305c9e94 --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManager.java @@ -0,0 +1,326 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.common.SSEException; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.common.XPathUtils; +import com.microfocus.application.automation.tools.sse.sdk.request.GetTestInstancesRequest; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.ArgsFactory; +import com.microfocus.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testcase; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; + +import java.util.Collections; + +@SuppressWarnings({"squid:S2698","squid:S2699"}) +public class TestRunManager extends TestCase { + + @Test + public void testEndToEndBVS() throws InterruptedException { + + SseModel model = createBvsModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientFunctional( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + Assert.assertTrue(verifyEmpty(testsuites, connection, args) || verifyTestsuitesFunctional(testsuites, "bvs")); + } + + @Test + public void testEndToEndBVSWithCDA() throws InterruptedException { + + SseModel model = createBvsModelWithCDA(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientFunctional( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + Assert.assertTrue(verifyEmpty(testsuites, connection, args) || verifyTestsuitesFunctional(testsuites, "bvs")); + } + + @Test + public void testEndToEndBVSWithEmptyCDA() throws InterruptedException { + + SseModel model = createBvsModelWithEmptyCDA(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientFunctional( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + Assert.assertNotNull(testsuites); + Assert.assertTrue(verifyEmpty(testsuites, connection, args) || verifyTestsuitesFunctional(testsuites, "bvs")); + } + + @Test + public void testEndToEndTestSet() throws InterruptedException { + + SseModel model = createTestSetModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientFunctional( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + Assert.assertTrue(verifyEmpty(testsuites, connection, args) || verifyTestsuitesFunctional(testsuites, "testset")); + } + + @Test + public void testEndToEndPC() throws InterruptedException { + + SseModel model = createPCModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientPC( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + Assert.assertTrue(verifyEmpty(testsuites, connection, args) || verifyTestsuitesPC(testsuites, "testset")); + } + + @Test + public void testBadRunEntity() throws InterruptedException { + + SseModel model = createBvsModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientBadRunEntity( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + RunManager runManager = new RunManager(); + Testsuites testsuites = runManager.execute(connection, args, new ConsoleLogger()); + + Assert.assertTrue(verifyEmpty(testsuites, connection, args)); + } + + @Test + public void testLoginFailed() throws InterruptedException { + + SseModel model = createBvsModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientFailedLogin( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + } + + @Test + public void testBadRunResponse() { + + SseModel model = createTestSetModel(); + model.setAlmServerUrl(URL); + Args args = new ArgsFactory().create(model); + RestClient connection = + new MockRestClientBadRunResponse( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + boolean thrown = false; + try { + new RunManager().execute(connection, args, new ConsoleLogger()); + } catch (Throwable cause) { + thrown = true; + } + + Assert.assertTrue(thrown || verifyEmpty(new Testsuites(), connection, args)); + } + + private MockSseModel createBvsModel() { + + return new MockSseModel( + SERVERNAME, + USER, + PASS, + DOMAIN, + PROJECT, + "BVS", + "1041", + DURATION, + DESCRIPTION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + null, + null); + } + + private MockSseModel createBvsModelWithCDA() { + + return new MockSseModel( + SERVERNAME, + USER, + PASS, + DOMAIN, + PROJECT, + "BVS", + "1041", + DURATION, + DESCRIPTION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + CDA_DETAILS, + null); + } + + private MockSseModel createBvsModelWithEmptyCDA() { + + return new MockSseModel( + SERVERNAME, + USER, + PASS, + DOMAIN, + PROJECT, + "BVS", + "1041", + DURATION, + DESCRIPTION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + new CdaDetails("", "", ""), + null); + } + + private MockSseModel createTestSetModel() { + + return new MockSseModel( + SERVERNAME, + USER, + PASS, + DOMAIN, + PROJECT, + "TEST_SET", + "1041", + DURATION, + DESCRIPTION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + null, + null); + } + + private MockSseModel createPCModel() { + + return new MockSseModel( + SERVERNAME, + USER, + PASS, + DOMAIN, + PROJECT, + "PC", + "1041", + DURATION, + DESCRIPTION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + null, + null); + } + + private boolean verifyTestsuitesFunctional(Testsuites testsuites, String runType) { + + boolean ret = true; + Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); + ret = + (testcase.getStatus().equals(JUnitTestCaseStatus.PASS)) + && (testcase.getName().equals("vapi1")) + && (testcase.getClassname().equals(String.format("%s1 (id:1041).testset1", runType))) && (testcase.getTime().equals("0.0")); + + return ret; + } + + private boolean verifyTestsuitesPC(Testsuites testsuites, String runType) { + + boolean ret = true; + Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); + ret = + (testcase.getStatus().equals("error")) + && (testcase.getName().equals("Unnamed test")) + && (testcase.getClassname().equals("PC Test ID: 5, Run ID: 42, Test Set ID: 1.(Unnamed test set)")) + && (testcase.getTime().equals("0.0")); + + return ret; + } + + private boolean verifyEmpty(Testsuites testsuites, RestClient connection, Args args) { + boolean ret = false; + + Response res = new GetTestInstancesRequest(connection, args.getEntityId()).execute(); + + ret = !res.isOk() || res.getData() == null || !XPathUtils.hasResults(res.toString()); + + return ret && testsuites.getTestsuite().isEmpty(); + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java new file mode 100644 index 0000000000..d5a9180a1a --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestRunManagerSystemTests.java @@ -0,0 +1,144 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import com.microfocus.application.automation.tools.model.CdaDetails; +import com.microfocus.application.automation.tools.model.SseModel; +import com.microfocus.application.automation.tools.sse.ArgsFactory; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testcase; +import com.microfocus.application.automation.tools.sse.result.model.junit.Testsuites; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import com.microfocus.application.automation.tools.rest.RestClient; +import com.microfocus.application.automation.tools.sse.result.model.junit.JUnitTestCaseStatus; + +/** + * + * @author Amir Zahavi + * + */ +@Ignore +@SuppressWarnings("squid:S2699") +public class TestRunManagerSystemTests { + + private static final String SERVER_NAME = "zahavia1.emea.hpqcorp.net"; + private static final int PORT = 8080; + private static final String PROJECT = "Project1"; + private static int TEST_SET_ID = 2; + private static int BVS_ID = 1084; + + @Test + public void testEndToEndTestSet() throws InterruptedException { + + SseModel model = createModel(SseModel.TEST_SET, SERVER_NAME, PROJECT, PORT, TEST_SET_ID); + Args args = new ArgsFactory().create(model); + RestClient connection = + new RestClient( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + assertTestsuitesPassed(testsuites); + } + + @Test + public void testEndToEndBVS() throws InterruptedException { + + SseModel model = createModel(SseModel.BVS, SERVER_NAME, PROJECT, PORT, BVS_ID); + Args args = new ArgsFactory().create(model); + RestClient connection = + new RestClient( + args.getUrl(), + args.getDomain(), + args.getProject(), + args.getUsername()); + Testsuites testsuites = new RunManager().execute(connection, args, new ConsoleLogger()); + + Assert.assertNotNull(testsuites); + assertTestsuitesPassed(testsuites); + } + + private void assertTestsuitesPassed(Testsuites testsuites) { + + Testcase testcase = testsuites.getTestsuite().get(0).getTestcase().get(0); + Assert.assertNotNull(testcase); + Assert.assertTrue( + "Test did not run successfully", + testcase.getStatus().equals(JUnitTestCaseStatus.PASS)); + } + + /** + * + * @param entityType + * "BVS" or "TEST_SET" + */ + private SseModel createModel( + String entityType, + String serverName, + String projectName, + int port, + int testSetID) { + + final String userName = "sa"; + String description = ""; + final String password = ""; + String domain = "DEFAULT"; + String timeslotDuration = "30"; + String postRunAction = "Collate"; + String environmentConfigurationId = ""; + CdaDetails cdaDetails = null; + SseModel ret = + new MockSseModel( + serverName, + userName, + password, + domain, + projectName, + entityType, + String.valueOf(testSetID), + timeslotDuration, + description, + postRunAction, + environmentConfigurationId, + cdaDetails, + null); + ret.setAlmServerUrl(String.format("http://%s:%d/qcbin", serverName, port)); + + return ret; + } + +} diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandler.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandler.java new file mode 100644 index 0000000000..f41e812cab --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandler.java @@ -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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + +import java.net.HttpURLConnection; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import com.microfocus.application.automation.tools.sse.sdk.handler.TestSetRunHandler; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; + +/** + * @author Effi Bar-She'an + */ +@SuppressWarnings("squid:S2699") +public class TestTestSetRunHandler extends TestCase { + + @Test + public void testStart() { + + Client client = new MockRestStartClient(URL, DOMAIN, PROJECT, USER); + Response response = + new RunHandlerFactory().create(client, "TEST_SET", ENTITY_ID).start( + DURATION, + POST_RUN_ACTION, + ENVIRONMENT_CONFIGURATION_ID, + null); + Assert.assertTrue(response.isOk()); + } + + private class MockRestStartClient extends RestClient4Test { + + public MockRestStartClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } + + @Test + public void testStop() { + + Client client = new MockRestStopClient(URL, DOMAIN, PROJECT, USER); + Response response = new TestSetRunHandler(client, "23").stop(); + Assert.assertTrue(response.isOk()); + } + + private class MockRestStopClient extends RestClient4Test { + + public MockRestStopClient(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpPost(String url, byte[] data, Map headers, ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, null, null, HttpURLConnection.HTTP_OK); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java new file mode 100644 index 0000000000..06c748d5da --- /dev/null +++ b/src/test/java/com/microfocus/application/automation/tools/sse/sdk/TestTestSetRunHandlerGetReportUrl.java @@ -0,0 +1,128 @@ +/* + * 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. + * ___________________________________________________________________ + */ + +package com.microfocus.application.automation.tools.sse.sdk; + + +import java.net.HttpURLConnection; +import java.util.Map; + +import com.microfocus.application.automation.tools.sse.common.TestCase; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandlerFactory; +import org.junit.Assert; +import org.junit.Test; + +import com.microfocus.application.automation.tools.sse.common.RestClient4Test; +import com.microfocus.application.automation.tools.sse.sdk.handler.RunHandler; + +/** + * @author Effi Bar-She'an + */ +@SuppressWarnings("squid:S2699") +public class TestTestSetRunHandlerGetReportUrl extends TestCase { + + private static final String _dataFormat = "\n" + + "12.50.39 (Patch 1)\n" + + "%s\n" + + "%s\n" + + "0\n" + + "1\n" + + "1\n" + + ""; + + @Test + public void testBuildNewUrl() { + + RunHandler runHandler = new RunHandlerFactory().create(new MockClient(URL, DOMAIN, PROJECT, USER, String.format(_dataFormat, "12", "5")), "TEST_SET", ENTITY_ID); + runHandler.setRunId(RUN_ID); + String url = runHandler.getReportUrl(createArgs()); + Assert.assertTrue(String.format("URL does not contains ui. URL: %s", url), url.contains("/ui/")); + Assert.assertTrue(String.format("URL does not ends with Run ID: %s, URL: %s", RUN_ID, url) , url.endsWith(RUN_ID)); + } + + @Test + public void testBuildOldUrl() { + + RunHandler runHandler = new RunHandlerFactory().create(new MockClient(URL, DOMAIN, PROJECT, USER, String.format(_dataFormat, "12", "0")), "TEST_SET", ENTITY_ID); + runHandler.setRunId(RUN_ID); + String url = runHandler.getReportUrl(createArgs()); + Assert.assertTrue(String.format("URL does not contains webui. URL: %s", url), url.contains("/webui/")); + Assert.assertTrue(String.format("URL does not ends with Run ID: %s, URL: %s", RUN_ID, url) , url.endsWith(RUN_ID)); + } + + @Test + public void testBuildHttpCallThrowsException() { + + RunHandler runHandler = new RunHandlerFactory().create(new MockClientThrowsException(URL, DOMAIN, PROJECT, USER), "TEST_SET", ENTITY_ID); + runHandler.setRunId(RUN_ID); + Assert.assertEquals("NA", runHandler.getReportUrl(createArgs())); + } + + private class MockClient extends RestClient4Test { + + private final String _data; + + public MockClient(String url, String domain, String project, String username, String data) { + + super(url, domain, project, username); + _data = data; + } + + @Override + public Response httpGet( + String url, + String queryString, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + return new Response(null, _data.getBytes(), null, HttpURLConnection.HTTP_OK); + } + } + + private class MockClientThrowsException extends RestClient4Test { + + public MockClientThrowsException(String url, String domain, String project, String username) { + + super(url, domain, project, username); + } + + @Override + public Response httpGet( + String url, + String queryString, + Map headers, + ResourceAccessLevel resourceAccessLevel) { + + throw new RuntimeException("catch me if you can :)"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/UFT/UFT_results.xml b/src/test/resources/UFT/UFT_results.xml index 6b6a9891f0..019195241d 100644 --- a/src/test/resources/UFT/UFT_results.xml +++ b/src/test/resources/UFT/UFT_results.xml @@ -1,4 +1,36 @@ + + diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults0.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults0.xml deleted file mode 100644 index 6ebe0780fe..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults0.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults1.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults1.xml deleted file mode 100644 index 7497603011..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f1/OctaneGherkinResults1.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults0.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults0.xml deleted file mode 100644 index 40d6790656..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults0.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults1.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults1.xml deleted file mode 100644 index 7497603011..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f2/OctaneGherkinResults1.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults0.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults0.xml deleted file mode 100644 index d36518f92e..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults0.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults1.xml b/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults1.xml deleted file mode 100644 index e686218078..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/octane/tests/gherkin/f3/OctaneGherkinResults1.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/results/RunReport_sc5.xml b/src/test/resources/com/hp/application/automation/tools/results/RunReport_sc5.xml deleted file mode 100644 index 47559cb9a3..0000000000 --- a/src/test/resources/com/hp/application/automation/tools/results/RunReport_sc5.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Passed - Passed - Passed - Failed - Passed - Failed - - \ No newline at end of file diff --git a/src/test/resources/com/hp/application/automation/tools/pc/Reports.zip b/src/test/resources/com/microfocus/application/automation/tools/pc/Reports.zip similarity index 100% rename from src/test/resources/com/hp/application/automation/tools/pc/Reports.zip rename to src/test/resources/com/microfocus/application/automation/tools/pc/Reports.zip diff --git a/src/test/resources/com/hp/application/automation/tools/results/RunReport.xml b/src/test/resources/com/microfocus/application/automation/tools/results/RunReport.xml similarity index 80% rename from src/test/resources/com/hp/application/automation/tools/results/RunReport.xml rename to src/test/resources/com/microfocus/application/automation/tools/results/RunReport.xml index c6c096733a..44ae7f8a0f 100644 --- a/src/test/resources/com/hp/application/automation/tools/results/RunReport.xml +++ b/src/test/resources/com/microfocus/application/automation/tools/results/RunReport.xml @@ -1,25 +1,33 @@ diff --git a/src/test/resources/com/microfocus/application/automation/tools/results/RunReport_sc5.xml b/src/test/resources/com/microfocus/application/automation/tools/results/RunReport_sc5.xml new file mode 100644 index 0000000000..545e0ddd9c --- /dev/null +++ b/src/test/resources/com/microfocus/application/automation/tools/results/RunReport_sc5.xml @@ -0,0 +1,63 @@ + + + + + + + Passed + Passed + Passed + Failed + Passed + Failed + + \ No newline at end of file diff --git a/src/test/resources/helloCucumberWorld/pom.xml b/src/test/resources/helloCucumberWorld/pom.xml index 4547845909..cdffb4e64f 100644 --- a/src/test/resources/helloCucumberWorld/pom.xml +++ b/src/test/resources/helloCucumberWorld/pom.xml @@ -1,4 +1,36 @@ + + @@ -8,13 +40,47 @@ 1 1.0-SNAPSHOT + + 1.8 + 1.8 + + + + info.cukes + cucumber-java + 1.2.5 + test + + + junit + junit + 4.13.1 + test + com.hpe.alm.octane octane-cucumber-jvm - 12.53.19 + 12.55.7 + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + \ No newline at end of file diff --git a/src/test/resources/helloCucumberWorld/settings.xml b/src/test/resources/helloCucumberWorld/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloCucumberWorld/settings.xml +++ b/src/test/resources/helloCucumberWorld/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloCucumberWorld/src/test/java/MyStepdefs.java b/src/test/resources/helloCucumberWorld/src/test/java/MyStepdefs.java index b2a89d7478..22bee6e501 100644 --- a/src/test/resources/helloCucumberWorld/src/test/java/MyStepdefs.java +++ b/src/test/resources/helloCucumberWorld/src/test/java/MyStepdefs.java @@ -1,5 +1,39 @@ -import cucumber.api.PendingException; -import cucumber.api.java.en.*; +/* + * 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. + * ___________________________________________________________________ + */ + +import cucumber.api.java.en.And; +import cucumber.api.java.en.Given; +import cucumber.api.java.en.Then; +import cucumber.api.java.en.When; /** * Created by franksha on 27/09/2016. diff --git a/src/test/resources/helloCucumberWorld/src/test/java/RunnerTest.java b/src/test/resources/helloCucumberWorld/src/test/java/RunnerTest.java index 3fe583b26e..f57c394bb9 100644 --- a/src/test/resources/helloCucumberWorld/src/test/java/RunnerTest.java +++ b/src/test/resources/helloCucumberWorld/src/test/java/RunnerTest.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + import com.hpe.alm.octane.OctaneCucumber; import cucumber.api.CucumberOptions; import org.junit.runner.RunWith; diff --git a/src/test/resources/helloWorldFailsafe/pom.xml b/src/test/resources/helloWorldFailsafe/pom.xml index e5b9fcea90..cd614e09c7 100644 --- a/src/test/resources/helloWorldFailsafe/pom.xml +++ b/src/test/resources/helloWorldFailsafe/pom.xml @@ -1,3 +1,35 @@ + + 4.0.0 @@ -44,4 +76,21 @@ + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + \ No newline at end of file diff --git a/src/test/resources/helloWorldFailsafe/settings.xml b/src/test/resources/helloWorldFailsafe/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldFailsafe/settings.xml +++ b/src/test/resources/helloWorldFailsafe/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldFailsafe/src/main/java/hello/HelloWorld.java b/src/test/resources/helloWorldFailsafe/src/main/java/hello/HelloWorld.java index 5169a37d32..efb25836d7 100644 --- a/src/test/resources/helloWorldFailsafe/src/main/java/hello/HelloWorld.java +++ b/src/test/resources/helloWorldFailsafe/src/main/java/hello/HelloWorld.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; public class HelloWorld { diff --git a/src/test/resources/helloWorldFailsafe/src/test/java/hello/ITHelloWorld.java b/src/test/resources/helloWorldFailsafe/src/test/java/hello/ITHelloWorld.java index e49f7e2a00..b8ceb1d176 100644 --- a/src/test/resources/helloWorldFailsafe/src/test/java/hello/ITHelloWorld.java +++ b/src/test/resources/helloWorldFailsafe/src/test/java/hello/ITHelloWorld.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; import org.testng.Assert; diff --git a/src/test/resources/helloWorldRoot/helloWorld/pom.xml b/src/test/resources/helloWorldRoot/helloWorld/pom.xml index 05069f4317..6f9c3a80c6 100644 --- a/src/test/resources/helloWorldRoot/helloWorld/pom.xml +++ b/src/test/resources/helloWorldRoot/helloWorld/pom.xml @@ -1,3 +1,35 @@ + + 4.0.0 @@ -12,7 +44,7 @@ junit junit - 4.8.2 + 4.13.1 compile @@ -52,4 +84,22 @@ + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldRoot/helloWorld/settings.xml b/src/test/resources/helloWorldRoot/helloWorld/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldRoot/helloWorld/settings.xml +++ b/src/test/resources/helloWorldRoot/helloWorld/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldRoot/helloWorld/src/main/java/hello/HelloWorld.java b/src/test/resources/helloWorldRoot/helloWorld/src/main/java/hello/HelloWorld.java index 5169a37d32..efb25836d7 100644 --- a/src/test/resources/helloWorldRoot/helloWorld/src/main/java/hello/HelloWorld.java +++ b/src/test/resources/helloWorldRoot/helloWorld/src/main/java/hello/HelloWorld.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; public class HelloWorld { diff --git a/src/test/resources/helloWorldRoot/helloWorld/src/test/java/hello/HelloWorldTest.java b/src/test/resources/helloWorldRoot/helloWorld/src/test/java/hello/HelloWorldTest.java index a3aa7b6238..4f264df445 100644 --- a/src/test/resources/helloWorldRoot/helloWorld/src/test/java/hello/HelloWorldTest.java +++ b/src/test/resources/helloWorldRoot/helloWorld/src/test/java/hello/HelloWorldTest.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; import org.junit.Assert; diff --git a/src/test/resources/helloWorldRoot/helloWorld2/pom.xml b/src/test/resources/helloWorldRoot/helloWorld2/pom.xml index 6b2edffb83..ee3f52a540 100644 --- a/src/test/resources/helloWorldRoot/helloWorld2/pom.xml +++ b/src/test/resources/helloWorldRoot/helloWorld2/pom.xml @@ -1,3 +1,35 @@ + + 4.0.0 @@ -12,7 +44,7 @@ junit junit - 4.8.2 + 4.13.1 compile @@ -52,4 +84,22 @@ + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldRoot/helloWorld2/settings.xml b/src/test/resources/helloWorldRoot/helloWorld2/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldRoot/helloWorld2/settings.xml +++ b/src/test/resources/helloWorldRoot/helloWorld2/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldRoot/helloWorld2/src/main/java/hello/HelloWorld2.java b/src/test/resources/helloWorldRoot/helloWorld2/src/main/java/hello/HelloWorld2.java index 619e206a26..19a876d244 100644 --- a/src/test/resources/helloWorldRoot/helloWorld2/src/main/java/hello/HelloWorld2.java +++ b/src/test/resources/helloWorldRoot/helloWorld2/src/main/java/hello/HelloWorld2.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; public class HelloWorld2 { diff --git a/src/test/resources/helloWorldRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java b/src/test/resources/helloWorldRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java index 2542f69399..8cd028e451 100644 --- a/src/test/resources/helloWorldRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java +++ b/src/test/resources/helloWorldRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; import org.junit.Test; diff --git a/src/test/resources/helloWorldRoot/pom.xml b/src/test/resources/helloWorldRoot/pom.xml index db74ed3b10..71789350a0 100644 --- a/src/test/resources/helloWorldRoot/pom.xml +++ b/src/test/resources/helloWorldRoot/pom.xml @@ -1,4 +1,36 @@ + + 4.0.0 @@ -12,4 +44,23 @@ helloWorld helloWorld2 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldRoot/settings.xml b/src/test/resources/helloWorldRoot/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldRoot/settings.xml +++ b/src/test/resources/helloWorldRoot/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld/pom.xml b/src/test/resources/helloWorldTestNGRoot/helloWorld/pom.xml index 9deeb5aeb4..ff6b6d6de0 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld/pom.xml +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld/pom.xml @@ -1,3 +1,35 @@ + + 4.0.0 @@ -64,4 +96,22 @@ + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld/settings.xml b/src/test/resources/helloWorldTestNGRoot/helloWorld/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld/settings.xml +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld/src/main/java/hello/HelloWorld.java b/src/test/resources/helloWorldTestNGRoot/helloWorld/src/main/java/hello/HelloWorld.java index 5169a37d32..efb25836d7 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld/src/main/java/hello/HelloWorld.java +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld/src/main/java/hello/HelloWorld.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; public class HelloWorld { diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld/src/test/java/hello/HelloWorldTest.java b/src/test/resources/helloWorldTestNGRoot/helloWorld/src/test/java/hello/HelloWorldTest.java index 7927d76ed0..b179387a7b 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld/src/test/java/hello/HelloWorldTest.java +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld/src/test/java/hello/HelloWorldTest.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; import org.testng.Assert; diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld2/pom.xml b/src/test/resources/helloWorldTestNGRoot/helloWorld2/pom.xml index 05649c38fd..ff7757a872 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld2/pom.xml +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld2/pom.xml @@ -1,3 +1,35 @@ + + 4.0.0 @@ -64,4 +96,22 @@ + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld2/settings.xml b/src/test/resources/helloWorldTestNGRoot/helloWorld2/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld2/settings.xml +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld2/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/main/java/hello/HelloWorld2.java b/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/main/java/hello/HelloWorld2.java index 619e206a26..19a876d244 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/main/java/hello/HelloWorld2.java +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/main/java/hello/HelloWorld2.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; public class HelloWorld2 { diff --git a/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java b/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java index 0ae7c6dddb..54a86a1cfb 100644 --- a/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java +++ b/src/test/resources/helloWorldTestNGRoot/helloWorld2/src/test/java/hello/HelloWorld2Test.java @@ -1,3 +1,35 @@ +/* + * 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. + * ___________________________________________________________________ + */ + package hello; import org.testng.annotations.Test; diff --git a/src/test/resources/helloWorldTestNGRoot/pom.xml b/src/test/resources/helloWorldTestNGRoot/pom.xml index e4e11e1507..ce8f9604a6 100644 --- a/src/test/resources/helloWorldTestNGRoot/pom.xml +++ b/src/test/resources/helloWorldTestNGRoot/pom.xml @@ -1,4 +1,36 @@ + + 4.0.0 @@ -12,4 +44,23 @@ helloWorld helloWorld2 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + central + https://repo1.maven.org/maven2 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/test/resources/helloWorldTestNGRoot/settings.xml b/src/test/resources/helloWorldTestNGRoot/settings.xml index b82e246027..d4c05531e4 100644 --- a/src/test/resources/helloWorldTestNGRoot/settings.xml +++ b/src/test/resources/helloWorldTestNGRoot/settings.xml @@ -1,131 +1,144 @@ + ~ 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. + ~ ___________________________________________________________________ + --> - - - optional - true - http - proxyuser - proxypass - web-proxy.il.hpecorp.net - 8080 - local.net|some.host.com - - + + + + + + + + + + + + - - - nexus - external:* - http://mydtbld0051.hpeswlab.net:8081/nexus/content/groups/mqm-public - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - m.g.o-public - - - - - - nexus - - - nexus - http://arbitraryUrl - true - true - - - - - nexus - http://arbitraryUrl - true - true - - - - - - jenkins - - true - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - true - true - - - - - - hudson - - true - - - - - - - - - teamcity - - true - - - - jetbrains-all - http://repository.jetbrains.com/all - - - - - - - - - - nexus - jenkins - teamcity - - - - com.atlassian.maven.plugins - org.mortbay.jetty - org.jenkins-ci.tools - com.hp.mqm.plugins - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +