
com.hp.mqm.atrf.App Maven / Gradle / Ivy
The newest version!
/*
* 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.mqm.atrf;
import com.hp.mqm.atrf.alm.entities.*;
import com.hp.mqm.atrf.alm.services.AlmQueryBuilder;
import com.hp.mqm.atrf.alm.services.AlmWrapperService;
import com.hp.mqm.atrf.core.configuration.ConfigurationUtilities;
import com.hp.mqm.atrf.core.configuration.FetchConfiguration;
import com.hp.mqm.atrf.core.configuration.ReturnCode;
import com.hp.mqm.atrf.core.rest.RestStatusException;
import com.hp.mqm.atrf.octane.core.OctaneTestResultOutput;
import com.hp.mqm.atrf.octane.entities.TestRunResultEntity;
import com.hp.mqm.atrf.octane.services.OctaneWrapperService;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by berkovir on 08/12/2016.
*/
public class App {
static final Logger logger = LogManager.getLogger();
private FetchConfiguration configuration;
private AlmWrapperService almWrapper;
private OctaneWrapperService octaneWrapper;
private Map alm2OctaneTestingToolMapper = new HashMap<>();
private DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//2016-03-22 11:34:23
private DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");//2016-03-22 11:34:23
private final String OCTANE_RUN_PASSED_STATUS = "Passed";
private final String OCTANE_RUN_FAILED_STATUS = "Failed";
private final String OCTANE_RUN_SKIPPED_STATUS = "Skipped";
private Set OCTANE_RUN_VALID_STATUS = new HashSet<>(Arrays.asList(OCTANE_RUN_PASSED_STATUS, OCTANE_RUN_FAILED_STATUS));
public App(FetchConfiguration configuration) {
this.configuration = configuration;
alm2OctaneTestingToolMapper.put("MANUAL", "Manual");
alm2OctaneTestingToolMapper.put("LEANFT-TEST", "LeanFT");
alm2OctaneTestingToolMapper.put("QUICKTEST_TEST", "UFT");
alm2OctaneTestingToolMapper.put("BUSINESS-PROCESS", "BPT");
}
public void start() {
confValidation();
List resultOutputs = outputToOctane();
getCreationStatus(resultOutputs);
}
private void confValidation() {
logger.info(System.lineSeparator());
logger.info("PHASE : connectivity validation");
//VALIDATE LOGIN TO ALM
loginToAlm();
//VALIDATE LOGIN TO OCTANE
if (!isOutput()) {
loginToOctane();
}
}
private void getCreationStatus(List resultOutputs) {
logger.info(System.lineSeparator());
logger.info("PHASE : get creation statuses");
sleep(10 * 1000);//wait at least 5 sec before to give time to octane to complete the creation
for (int i = 0; i < resultOutputs.size(); i++) {
OctaneTestResultOutput current = resultOutputs.get(i);
getCreationStatusInternal(configuration, i + 1, current);
}
}
private void getCreationStatusInternal(FetchConfiguration configuration, int bulkId, OctaneTestResultOutput output) {
int failsCount = 0;
boolean finished = false;
int sleepSize = Integer.parseInt(configuration.getSyncSleepBetweenPosts()) * 1000;
while (!finished) {
if (!output.getStatus().equals("success") && !output.getStatus().equals(OctaneTestResultOutput.FAILED_SEND_STATUS)) {
try {
output = octaneWrapper.getTestResultStatus(output);
} catch (Exception e) {
failsCount++;
if (failsCount > 3) {
logger.info(String.format("Bulk #%s : failed to get creation status ", bulkId));
break;
} else {
logger.info(String.format("Bulk #%s : failed to get creation status, trial %s", bulkId, failsCount));
sleep(sleepSize);
continue;
}
}
}
logger.info(String.format("Bulk #%s : creation status is %s", bulkId, output.getStatus().toUpperCase()));
if (!(output.getStatus().equals("running") || output.getStatus().equals("queued"))) {
finished = true;
} else {
sleep(sleepSize);
}
}
}
private boolean isOutput() {
boolean isOutput = StringUtils.isNotEmpty(configuration.getOutputFile());
return isOutput;
}
private List outputToOctane() {
if (!isOutput()) {
logger.info(System.lineSeparator());
logger.info("PHASE : send data to ALM Octane");
}
int bulkSize = Integer.parseInt(configuration.getSyncBulkSize());
int fetchLimit = Integer.parseInt(configuration.getRunFilterFetchLimit());
int pageSize = Math.min(bulkSize, fetchLimit);
AlmQueryBuilder queryBuilder = almWrapper.buildRunFilter(configuration);
queryBuilder.addPageSize(pageSize);
//PRINT EXPECTED RUN COUNT
int expectedRunsCount = 0;
try {
expectedRunsCount = almWrapper.getExpectedRuns(queryBuilder);
} catch (RestStatusException e) {
logger.error(String.format("Failed to execute Rest query in ALM. Validate Run Filter section in configuration. The received exception from ALM is %s", e.getMessage()));
System.exit(ReturnCode.FAILURE.getReturnCode());
}
expectedRunsCount = Math.min(expectedRunsCount, fetchLimit);
logger.info(String.format("Expected runs : %d", expectedRunsCount));
int expectedBulks = expectedRunsCount / bulkSize;
if (expectedRunsCount % bulkSize > 0) {
expectedBulks++;
}
logger.info(String.format("Expected bulks : %d", expectedBulks));
//LOOP OF SEND
long lastSentTime = 0;
int runStartIndex = 0;
int sleepBetweenPosts = Integer.parseInt(configuration.getSyncSleepBetweenPosts()) * 1000;
long start = System.currentTimeMillis();
List resultOutputs = new ArrayList<>();
for (int bulkId = 1; bulkId <= expectedBulks; bulkId++) {
logger.info(String.format("Bulk #%s : preparing", bulkId));
//4.1 GET DATA FROM ALM
queryBuilder.addStartIndex(runStartIndex + 1);
List runs = almWrapper.fetchRuns(queryBuilder);
almWrapper.fetchRunRelatedEntities(runs);
runStartIndex += runs.size();
//4.2 SLEEP IF REQUIRED
long fromLastSent = System.currentTimeMillis() - lastSentTime;
long toSleep = sleepBetweenPosts - fromLastSent;
if (toSleep > 0) {
sleep(toSleep);
}
//4.3SEND/OUTPUT
List ngaRuns = prepareRunsForInjection(bulkId, runs);
if (isOutput()) {
File file = saveResults(configuration, ngaRuns);
String note = "";
if (runStartIndex < expectedRunsCount) {
note = String.format("(first %s runs)", bulkSize);
}
logger.info(String.format("The results are saved to %s: %s", note, file.getAbsolutePath()));
System.exit(0);
} else {
String firstRunId = ngaRuns.get(0).getRunId();
String lastRunId = ngaRuns.get(ngaRuns.size() - 1).getRunId();
OctaneTestResultOutput currentOutput = null;
try {
currentOutput = sendResults(bulkId, ngaRuns);
lastSentTime = System.currentTimeMillis();
ConfigurationUtilities.saveLastSentRunId(lastRunId);
logger.info(String.format("Bulk #%s : sending %s runs , run ids from %s to %s , job id=%s, %s",
bulkId, ngaRuns.size(), firstRunId, lastRunId, currentOutput.getId(), currentOutput.getStatus().toUpperCase()));
} catch (Exception e) {
String msg = e.getMessage();
int msgLength = 350;
if (msg.length() > msgLength) {
msg = msg.substring(0, msgLength);
}
logger.info(String.format("Bulk #%s : failed to send run ids from %s to %s: %s", bulkId, firstRunId, lastRunId, msg));
currentOutput = new OctaneTestResultOutput();
currentOutput.put(OctaneTestResultOutput.FIELD_STATUS, OctaneTestResultOutput.FAILED_SEND_STATUS);
}
resultOutputs.add(currentOutput);
}
}
long end = System.currentTimeMillis();
logger.info(String.format("Finished sending data to ALM Octane in %d sec ", (end - start) / 1000));
return resultOutputs;
}
private File saveResults(FetchConfiguration configuration, List runResults) {
List myRunResults = runResults;
File file = new File(configuration.getOutputFile());
StreamResult result = new StreamResult(file);
convertToXml(myRunResults, result, true);
return file;
}
private OctaneTestResultOutput sendResults(int bulkId, List runResults) {
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
convertToXml(runResults, result, false);
String xmlData = writer.toString();
int trial = 0;
OctaneTestResultOutput output = null;
boolean finished = false;
while (!finished) {
try {
trial++;
output = octaneWrapper.postTestResults(xmlData);
finished = true;
} catch (Exception ex) {
if (trial == 3) {
throw ex;
}
logger.warn(String.format("Bulk #%s : failed to send, trial %s", bulkId, trial));
//sleep before next send
sleep(5000);
}
}
return output;
}
private void sleep(long sleepSize) {
try {
Thread.sleep(sleepSize);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void loginToAlm() {
try {
logger.info("ALM : Validating login configuration ...");
almWrapper = new AlmWrapperService(configuration.getAlmServerUrl(), configuration.getAlmDomain(), configuration.getAlmProject());
try {
almWrapper.login(configuration.getAlmUser(), configuration.getAlmPassword());
logger.info("ALM : Login successful");
} catch (RestStatusException e) {
//validate credentials
if (e.getResponse().getStatusCode() == 401) {
String msg = String.format("Failed to login as '%s', validate credentials.", configuration.getAlmUser());
throw new RuntimeException(msg);
} else {
throw e;
}
} catch (RuntimeException e) {
//validate host
if (e.getCause() instanceof UnknownHostException) {
String msg = "Failed to connect to host : " + configuration.getAlmServerUrl();
throw new RuntimeException(msg);
} else {
throw e;
}
}
if (almWrapper.validateConnectionToDomain()) {
logger.info("ALM : Connected to ALM domain successfully");
} else {
throw new RuntimeException("Failed to connect to ALM domain " + configuration.getAlmDomain());
}
if (almWrapper.validateConnectionToProject()) {
logger.info("ALM : Connected to ALM project successfully");
} else {
throw new RuntimeException("Failed to connect to ALM project " + configuration.getAlmProject());
}
} catch (Exception e) {
logger.error("ALM : " + e.getMessage());
System.exit(ReturnCode.FAILURE.getReturnCode());
}
}
private void loginToOctane() {
try {
logger.info("ALM Octane : Validating login configuration ...");
long sharedSpaceId = Long.parseLong(configuration.getOctaneSharedSpaceId());
long workspaceId = Long.parseLong(configuration.getOctaneWorkspaceId());
octaneWrapper = new OctaneWrapperService(configuration.getOctaneServerUrl(), sharedSpaceId, workspaceId);
try {
octaneWrapper.login(configuration.getOctaneUser(), configuration.getOctanePassword());
logger.info("ALM Octane : Login successful");
} catch (RestStatusException e) {
//validate credentials
if (e.getResponse().getStatusCode() == 401) {
String msg = String.format("Failed to login as '%s', validate credentials.", configuration.getOctaneUser());
throw new RuntimeException(msg);
} else {
throw e;
}
} catch (RuntimeException e) {
//validate host
if (e.getCause() instanceof UnknownHostException) {
String msg = "Failed to connect to host : " + configuration.getAlmServerUrl();
throw new RuntimeException(msg);
} else {
throw e;
}
}
if (octaneWrapper.validateConnectionToSharedspace()) {
logger.info("ALM Octane : Connected to ALM Octane shared space successfully");
} else {
throw new RuntimeException("Failed to connect to ALM Octane shared space " + sharedSpaceId);
}
if (octaneWrapper.validateConnectionToWorkspace()) {
logger.info("ALM Octane : Connected to ALM Octane workspace successfully");
} else {
throw new RuntimeException("Failed to connect to ALM Octane workspace " + workspaceId);
}
} catch (Exception e) {
logger.error("ALM Octane : " + e.getMessage());
System.exit(ReturnCode.FAILURE.getReturnCode());
}
}
private List prepareRunsForInjection(int bulkId, List runs) {
List list = new ArrayList<>();
List skippedRunIds = new ArrayList<>();
for (Run run : runs) {
//preparation
Test test = almWrapper.getTest(run.getTestId());
TestFolder testFolder = almWrapper.getTestFolder(test.getTestFolderId());
TestSet testSet = almWrapper.getTestSet(run.getTestSetId());
TestConfiguration testConfiguration = almWrapper.getTestConfiguration(run.getTestConfigId());
if (testSet == null) {
//testSet was deleted
skippedRunIds.add(run.getId());
continue;
}
TestRunResultEntity injectionEntity = new TestRunResultEntity();
injectionEntity.setRunId(run.getId());
//TEST FIELDS
//test name + test configuration, if Test name =Test configuration, just keep test name
String testName = String.format("AlmTestId #%s : %s", test.getId(), sanitizeForXml(test.getName()));
if (!testConfiguration.getName().equals(test.getName())) {
testName = String.format("AlmTestId #%s, ConfId #%s : %s - %s", test.getId(), testConfiguration.getId(), sanitizeForXml(test.getName()), sanitizeForXml(testConfiguration.getName()));
}
injectionEntity.setTestName(restrictTo255(testName));
injectionEntity.setTestingToolType(alm2OctaneTestingToolMapper.get(test.getSubType()));
injectionEntity.setPackageValue(almWrapper.getProject());
injectionEntity.setModule(almWrapper.getDomain());
injectionEntity.setClassValue(restrictTo255(sanitizeForXml(testFolder.getName())));
//RUN FIELDS
injectionEntity.setDuration(run.getDuration());
injectionEntity.setRunName(restrictTo255(String.format("AlmTestSet #%s : %s", testSet.getId(), sanitizeForXml(testSet.getName()))));
injectionEntity.setExternalReportUrl(almWrapper.generateALMReferenceURL(run));
Date startedDate = null;
try {
startedDate = DATE_TIME_FORMAT.parse(run.getExecutionDate() + " " + run.getExecutionTime());
} catch (ParseException e) {
try {
startedDate = DATE_FORMAT.parse(run.getExecutionDate());
} catch (ParseException e1) {
throw new RuntimeException(String.format("Failed to convert run execution date '%s' to Java Date : %s", run.getExecutionDate(), e1.getMessage()));
}
}
injectionEntity.setStartedTime(Long.toString(startedDate.getTime()));
String status = OCTANE_RUN_VALID_STATUS.contains(run.getStatus()) ? run.getStatus() : OCTANE_RUN_SKIPPED_STATUS;
injectionEntity.setStatus(status);
injectionEntity.validateEntity();
list.add(injectionEntity);
}
if (!skippedRunIds.isEmpty()) {
List subList = skippedRunIds;
int showCount = 20;
String firstNMessage = "";
if (skippedRunIds.size() > showCount) {
subList = skippedRunIds.subList(0, showCount);
firstNMessage = String.format(", first %s runs are", showCount);
}
logger.info(String.format("Bulk #%s : %s runs are skipped as their testsets are deleted %s : %s", bulkId, skippedRunIds.size(), firstNMessage, StringUtils.join(subList, ",")));
}
return list;
}
private String sanitizeForXml(String str) {
if (hasInvalidCharacter(str)) {
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (!XMLChar.isInvalid(c)) {
strBuilder.append(c);
} else {
strBuilder.append("_");
}
}
return strBuilder.toString();
}
String newStr = null;
try {
newStr = new String(str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
newStr = str;
}
return newStr;
}
private boolean hasInvalidCharacter(String str) {
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (XMLChar.isInvalid(c)) {
return true;
}
}
return false;
}
private String restrictTo255(String value) {
if (value == null || value.length() <= 255) {
return value;
}
return value.substring(0, 255);
}
private void convertToXml(List runResults, StreamResult result, boolean formatXml) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("test_result");
doc.appendChild(rootElement);
Element testRuns = doc.createElement("test_runs");
rootElement.appendChild(testRuns);
for (TestRunResultEntity runResult : runResults) {
Element testRun = doc.createElement("test_run");
testRuns.appendChild(testRun);
testRun.setAttribute("module", runResult.getModule());
testRun.setAttribute("package", runResult.getPackageValue());
testRun.setAttribute("class", runResult.getClassValue());
testRun.setAttribute("name", runResult.getTestName());
testRun.setAttribute("duration", runResult.getDuration());
testRun.setAttribute("status", runResult.getStatus());
testRun.setAttribute("started", runResult.getStartedTime());
testRun.setAttribute("external_report_url", runResult.getExternalReportUrl());
testRun.setAttribute("run_name", runResult.getRunName());
Element testFields = doc.createElement("test_fields");
testRun.appendChild(testFields);
if (StringUtils.isNotEmpty(runResult.getTestingToolType())) {
Element testField = doc.createElement("test_field");
testFields.appendChild(testField);
testField.setAttribute("type", "Testing_Tool_Type");
testField.setAttribute("value", runResult.getTestingToolType());
}
if (OCTANE_RUN_FAILED_STATUS.equals(runResult.getStatus())) {
Element error = doc.createElement("error");
testRun.appendChild(error);
error.setAttribute("type", "Error");
error.setAttribute("message", "For more details , goto ALM run : " + runResult.getExternalReportUrl());
}
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
if (formatXml) {
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
}
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy