/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.jenkins.results.parser; import java.io.FileNotFoundException; import java.net.URI; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; /** * @author Peter Yoo */ public class JenkinsPerformanceDataUtil { public static int getSlaveCount() { return _slaveCount; } public static List<Result> getSlowestResults() { if (_broken) { return null; } return _results; } public static int getTestCount() { return _testCount; } public static long getTotalDuration() { return _totalDuration; } public static void processPerformanceData( String jobName, String url, int size) { if (_broken) { return; } try { JSONObject jsonObject = null; if (url.contains("-source")) { jsonObject = JenkinsResultsParserUtil.toJSONObject( JenkinsResultsParserUtil.getLocalURL(url + "/api/json"), false); Result result = new Result(jobName, jsonObject); _results.add(result); Collections.sort(_results); _truncate(_results, size); _slaveCount++; _totalDuration += result.getDuration(); return; } int retryCount = 0; while (true) { try { jsonObject = JenkinsResultsParserUtil.toJSONObject( JenkinsResultsParserUtil.getLocalURL( url + "/testReport/api/json"), false); } catch (FileNotFoundException fnfe) { jsonObject = JenkinsResultsParserUtil.toJSONObject( JenkinsResultsParserUtil.getLocalURL(url + "/api/json"), false); Result result = new Result(jobName, jsonObject); _results.add(result); _slaveCount++; _totalDuration += result.getDuration(); break; } try { _results.addAll( _getSlowestResults(jobName, jsonObject, size)); break; } catch (IllegalArgumentException iae) { retryCount++; if (retryCount > 5) { System.out.println("Exceeded max retries"); throw iae; } System.out.println( "Retry in 60 seconds: " + iae.getMessage()); Thread.sleep(60 * 1000); } } Collections.sort(_results); _truncate(_results, size); } catch (Exception e) { System.out.println("Unable to parse performance data."); e.printStackTrace(); _broken = true; } } public static void reset() { _broken = false; _results.clear(); _slaveCount = 0; _testCount = 0; _totalDuration = 0; } public static class Result implements Comparable<Result> { public Result( JSONObject caseJSONObject, JSONObject childJSONObject, String jobName) throws Exception { _jobName = jobName; _className = caseJSONObject.getString("className"); _duration = caseJSONObject.getInt("duration"); _name = caseJSONObject.getString("name"); _status = caseJSONObject.getString("status"); _setAxis(childJSONObject); _setUrl(childJSONObject); } public Result(String jobName, JSONObject sourceJSONObject) throws Exception { _axis = ""; _className = ""; _duration = sourceJSONObject.getInt("duration") / 1000; _jobName = jobName; _name = sourceJSONObject.getString("fullDisplayName"); _status = sourceJSONObject.getString("result"); _url = sourceJSONObject.getString("url"); } @Override public int compareTo(Result result) { return -1 * Float.compare(getDuration(), result.getDuration()); } public String getAxis() { return _axis; } public String getClassName() { return _className; } public float getDuration() { return _duration; } public String getJobName() { return _jobName; } public String getName() { return _name; } public String getStatus() { return _status; } public String getUrl() { return _url; } private void _setAxis(JSONObject childJSONObject) throws Exception { String url = childJSONObject.getString("url"); url = URLDecoder.decode(url, "UTF-8"); int x = url.indexOf("AXIS_VARIABLE"); url = url.substring(x); int y = url.indexOf(","); _axis = url.substring(0, y); } private void _setUrl(JSONObject childJSONObject) throws Exception { String urlString = URLDecoder.decode( childJSONObject.getString("url"), "UTF-8"); StringBuilder sb = new StringBuilder(urlString); sb.append("testReport/"); int x = _className.lastIndexOf("."); sb.append(_className.substring(0, x)); sb.append("/"); sb.append(_className.substring(x + 1)); sb.append("/"); if (_className.contains("poshi")) { String poshiName = _name; poshiName = poshiName.replaceAll("\\[", "_"); poshiName = poshiName.replaceAll("\\]", "_"); poshiName = poshiName.replaceAll("#", "_"); sb.append(poshiName); sb.append("/"); } else { sb.append(_name); } URL url = JenkinsResultsParserUtil.createURL(sb.toString()); URI uri = url.toURI(); _url = uri.toASCIIString(); } private String _axis; private final String _className; private final int _duration; private final String _jobName; private final String _name; private final String _status; private String _url; } private static List<Result> _getSlowestResults( String name, JSONObject jobJSONObject, int maxSize) throws Exception { List<Result> results = new ArrayList<>(); JSONArray childReportsJSONArray = jobJSONObject.getJSONArray( "childReports"); for (int i = 0; i < childReportsJSONArray.length(); i++) { _slaveCount++; JSONObject childReportJSONObject = childReportsJSONArray.getJSONObject(i); if (!childReportJSONObject.has("child") || childReportJSONObject.isNull("child")) { throw new IllegalArgumentException("Child element is missing"); } JSONObject childJSONObject = childReportJSONObject.getJSONObject( "child"); if (!childReportJSONObject.has("result") || childReportJSONObject.isNull("result")) { throw new IllegalArgumentException( "Result element is missing for " + childJSONObject.getString("url")); } JSONObject childResultJSONObject = childReportJSONObject.getJSONObject("result"); _totalDuration += childResultJSONObject.getInt("duration"); JSONArray suitesJSONArray = childResultJSONObject.getJSONArray( "suites"); for (int j = 0; j < suitesJSONArray.length(); j++) { JSONObject suiteJSONObject = suitesJSONArray.getJSONObject(j); JSONArray casesJSONArray = suiteJSONObject.getJSONArray( "cases"); for (int k = 0; k < casesJSONArray.length(); k++) { _testCount++; JSONObject caseJSONObject = casesJSONArray.getJSONObject(k); Result result = new Result( caseJSONObject, childJSONObject, name); results.add(result); } } } Collections.sort(results); _truncate(results, maxSize); return results; } private static void _truncate(List<?> list, int maxSize) { if (list.size() < maxSize) { return; } List<?> sublist = list.subList(maxSize, list.size()); sublist.clear(); } private static boolean _broken; private static final List<Result> _results = new ArrayList<>(); private static int _slaveCount; private static int _testCount; private static long _totalDuration; }