package hudson.plugins.performance; import hudson.model.AbstractBuild; import hudson.model.ModelObject; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import hudson.model.TaskListener; import org.apache.log4j.Logger; /** * Root object of a performance report. */ public class PerformanceReportMap implements ModelObject { /** * The {@link PerformanceBuildAction} that this report belongs to. */ private transient PerformanceBuildAction buildAction; /** * {@link PerformanceReport}s are keyed by {@link PerformanceReport#reportFileName} * * Test names are arbitrary human-readable and URL-safe string that identifies an individual report. */ private Map<String, PerformanceReport> performanceReportMap = new HashMap<String, PerformanceReport>(); private static final String PERFORMANCE_REPORTS_DIRECTORY = "performance-reports"; /** * Parses the reports and build a {@link PerformanceReportMap}. * * @throws IOException * If a report fails to parse. */ PerformanceReportMap(PerformanceBuildAction buildAction, TaskListener listener) throws IOException { this.buildAction = buildAction; File repo = new File(getBuild().getRootDir(), PerformanceReportMap.getPerformanceReportDirRelativePath()); // files directly under the directory are for JMeter, for compatibility reasons. File[] files = repo.listFiles(new FileFilter() { public boolean accept(File f) { return !f.isDirectory(); } }); // this may fail, if the build itself failed, we need to recover gracefully if (files != null) { addAll(new JMeterParser("").parse(buildAction.getBuild(), Arrays.asList(files), listener)); } // otherwise subdirectory name designates the parser ID. File[] dirs = repo.listFiles(new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } }); // this may fail, if the build itself failed, we need to recover gracefully if (dirs != null) { for (File dir : dirs) { PerformanceReportParser p = buildAction.getParserById(dir.getName()); if (p!=null) { addAll(p.parse(getBuild(), Arrays.asList(dir.listFiles()), listener)); } } } } private void addAll(Collection<PerformanceReport> reports) { for (PerformanceReport r : reports) { r.setBuildAction(buildAction); performanceReportMap.put(r.getReportFileName(), r); } } public AbstractBuild<?, ?> getBuild() { return buildAction.getBuild(); } PerformanceBuildAction getBuildAction() { return buildAction; } public String getDisplayName() { return Messages.Report_DisplayName(); } public List<PerformanceReport> getPerformanceListOrdered() { List<PerformanceReport> listPerformance = new ArrayList<PerformanceReport>(getPerformanceReportMap().values()); Collections.sort(listPerformance); return listPerformance; } public Map<String, PerformanceReport> getPerformanceReportMap() { return performanceReportMap; } /** * <p> * Give the Performance report with the parameter for name in Bean * </p> * * @param performanceReportName * @return */ public PerformanceReport getPerformanceReport(String performanceReportName) { return performanceReportMap.get(performanceReportName); } /** * Get a URI report within a Performance report file * * @param uriReport * "Performance report file name";"URI name" * @return */ public UriReport getUriReport(String uriReport) { if (uriReport != null) { String uriReportDecoded; try { uriReportDecoded = URLDecoder.decode(uriReport.replace(UriReport.END_PERFORMANCE_PARAMETER, ""), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } StringTokenizer st = new StringTokenizer(uriReportDecoded, GraphConfigurationDetail.SEPARATOR); return getPerformanceReportMap().get(st.nextToken()).getUriReportMap().get(st.nextToken()); } else { return null; } } public String getUrlName() { return "performanceReportList"; } void setBuildAction(PerformanceBuildAction buildAction) { this.buildAction = buildAction; } public void setPerformanceReportMap(Map<String, PerformanceReport> performanceReportMap) { this.performanceReportMap = performanceReportMap; } public static String getPerformanceReportFileRelativePath(String reportFileName) { return getRelativePath(reportFileName); } public static String getPerformanceReportDirRelativePath() { return getRelativePath(null); } private static String getRelativePath(String reportFileName) { StringBuilder sb = new StringBuilder(100); sb.append(PERFORMANCE_REPORTS_DIRECTORY); if (reportFileName != null) { sb.append("/").append(reportFileName); } return sb.toString(); } /** * <p> * Verify if the PerformanceReport exist the performanceReportName must to be like it * is in the build * </p> * * @param performanceReportName * @return boolean */ public boolean isFailed(String performanceReportName) { return getPerformanceReport(performanceReportName) == null; } }