/* * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * https://jwsdp.dev.java.net/CDDLv1.0.html * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable, * add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */ package hudson.plugins.javatest_report; import hudson.model.AbstractBuild; import hudson.model.ModelObject; import java.util.HashMap; import java.util.Map; /** * Common data applicable to all test model objects. * * <p> * Setter methods are for Digester, and once created the test objects * are immutable. * * @param <S> * The derived type of {@link TestCollection} (the same design pattern as you seen in {@link Enum}) * * @author Rama Pulavarthi */ public abstract class TestObject<S extends TestObject<S>> implements ModelObject { /** * Unique identifier. */ private String id; /** * Optional human-readable name. */ private String name; /** * Optional description that possibly includes HTML. */ private String description; private Status status; /** * Optional message that complements status. */ private String statusMessage; /** * Optional attributes of a test. */ private Map<String,String> attributes; // set by the TestCollection when this is added to it. TestCollection parent; /** * This test has been failing since this build number (not id.) * <p/> * If {@link #getStatus()} is {@link Status#PASS}}, this field is left unused to 0. */ private /*final*/ int failedSince; /*package*/ TestObject() { } public String getId() { return id; } public void setId(String id) { this.id = id.replace(':','.'); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public final String getDisplayName() { if(name!=null) { if(name.equals("unknown")) { return id.substring(7); } return name; } else return id; } public AbstractBuild getOwner() { return parent.getOwner(); } /** * If this test failed, then return the build number * when this test started failing. */ public int getFailedSince() { // some old test data doesn't have failedSince value set, so for those compute them. if (!isPassed() && failedSince == 0) { TestObject prev = getPreviousResult(); if (prev != null && !prev.isPassed()) { this.failedSince = prev.failedSince; // this.failedSince = prev.getFailedSince(); } else this.failedSince = getOwner().getNumber(); } return failedSince; } private boolean isPassed() { return getStatus() == Status.PASS; } /** * Gets the number of consecutive builds (including this) * that this test case has been failing. */ public int getAge() { if (isPassed()) return 0; else return getOwner().getNumber() - failedSince + 1; } /** * Gets the counter part of this {@link TestObject} in the previous run. * * @return null * if no such counter part exists. */ public S getPreviousResult() { TestCollection p = (TestCollection)parent.getPreviousResult(); if(p!=null) return (S)p.get(getId()); else return null; } public Status getStatus() { return status; } // Digester don't understand enum public void setStatusString(String status) { if(status.equalsIgnoreCase("pass")) this.status = Status.PASS; else if(status.equalsIgnoreCase("did_not_run")) this.status = Status.SKIP; else if(status.equalsIgnoreCase("error")) this.status = Status.ERROR; else this.status = Status.FAIL; } public void addAttribute(String name, String value) { if(attributes == null) attributes = new HashMap<String,String>(); attributes.put(name,value); if(name.equals("logfile")) statusMessage = value; } public String getStatusMessage() { return statusMessage; } public abstract int getTotalCount(); public abstract int getFailCount(); public abstract int getSkippedCount(); }