PageRenderTime 32ms CodeModel.GetById 18ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/hudson-core/src/main/java/hudson/tasks/test/TestResult.java

http://github.com/hudson/hudson
Java | 270 lines | 116 code | 32 blank | 122 comment | 16 complexity | 47456b6b4acd5cc6956387a4e3f518ee MD5 | raw file
  1/*
  2 * The MIT License
  3 * 
  4 * Copyright (c) 2009, Yahoo!, Inc.
  5 * 
  6 * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 * of this software and associated documentation files (the "Software"), to deal
  8 * in the Software without restriction, including without limitation the rights
  9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 * copies of the Software, and to permit persons to whom the Software is
 11 * furnished to do so, subject to the following conditions:
 12 * 
 13 * The above copyright notice and this permission notice shall be included in
 14 * all copies or substantial portions of the Software.
 15 * 
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 * THE SOFTWARE.
 23 */
 24package hudson.tasks.test;
 25
 26import hudson.tasks.junit.TestAction;
 27import hudson.model.AbstractBuild;
 28import hudson.model.Run;
 29import hudson.model.Result;
 30
 31import java.util.Collection;
 32
 33import static java.util.Collections.emptyList;
 34
 35
 36/**
 37 * A class that represents a general concept of a test result, without any
 38 * language or implementation specifics.
 39 * Subclasses must add @Exported annotation to the fields they want to export.
 40 *
 41 * @sine 1.343
 42 */
 43public abstract class TestResult extends TestObject {
 44
 45    /**
 46     * If the concept of a parent action is important to a subclass, then it should
 47     * provide a non-noop implementation of this method. 
 48     * @param action
 49     */
 50    public void setParentAction(AbstractTestResultAction action) {
 51    }
 52
 53    /**
 54     * Returns the action that points to the top level test result includes
 55     * this test result.
 56     * 
 57     * @return
 58     */
 59    public AbstractTestResultAction getParentAction() {
 60        return getOwner().getTestResultAction();
 61    }
 62    
 63    /**
 64     * Request that the result update its counts of its children. Does not
 65     * require a parent action or owner or siblings. Subclasses should
 66     * implement this, unless they are *always* in a tallied state.  
 67     */
 68    public void tally() {
 69    }
 70    
 71    /**
 72     * Sets the parent test result
 73     * @param parent
 74     */
 75    public void setParent(TestObject parent) {
 76    }
 77
 78    /**
 79     * Gets the human readable title of this result object.
 80     */
 81    public /* abstract */ String getTitle(){
 82        return "";
 83    }
 84
 85    /**
 86     * Mark a build as unstable if there are failures. Otherwise, leave the
 87     * build result unchanged.
 88     *
 89     * @return {@link Result#UNSTABLE} if there are test failures, null otherwise.
 90     *
 91     */
 92    public Result getBuildResult() {
 93        if (getFailCount() > 0) {
 94            return Result.UNSTABLE;
 95        } else {
 96            return null;
 97        }
 98    }
 99
100    /**
101     * Time it took to run this test. In seconds.
102     */
103    public /* abstract */ float getDuration() {
104        return 0.0f;
105    }
106
107    /**
108     * Gets the total number of passed tests.
109     */
110    public /* abstract */ int getPassCount() {
111        return 0;
112    }
113
114    /**
115     * Gets the total number of failed tests.
116     */
117    public /* abstract */ int getFailCount() {
118        return 0;
119    }
120
121
122    /**
123     * Gets the total number of skipped tests.
124     */
125    public /* abstract */ int getSkipCount() {
126        return 0;
127    }
128    
129    /**
130     * Gets the counter part of this {@link TestResult} in the previous run.
131     *
132     * @return null if no such counter part exists.
133     */
134    public TestResult getPreviousResult() {
135        AbstractBuild<?,?> b = getOwner();
136        if (b == null) {
137            return null;
138        }
139        while(true) {
140            b = b.getPreviousBuild();
141            if(b==null)
142                return null;
143            AbstractTestResultAction r = b.getAction(getParentAction().getClass());
144            if(r!=null) {
145                TestResult result = r.findCorrespondingResult(this.getId());
146                if (result!=null)
147                    return result;
148            }
149        }
150    }
151
152    /**
153     * Gets the counter part of this {@link TestResult} in the specified run.
154     *
155     * @return null if no such counter part exists.
156     */
157    public TestResult getResultInBuild(AbstractBuild<?,?> build) {
158        AbstractTestResultAction tra = build.getAction(getParentAction().getClass());
159        if (tra == null) {
160            tra = build.getAction(AbstractTestResultAction.class);
161        }
162        return (tra == null) ? null : tra.findCorrespondingResult(this.getId());
163    }
164
165    /**
166     * Gets the "children" of this test result that failed
167     * @return the children of this test result, if any, or an empty collection
168     */
169    public Collection<? extends TestResult> getFailedTests() {
170        return emptyList();
171    }
172
173
174    /**
175     * Gets the "children" of this test result that passed
176     * @return the children of this test result, if any, or an empty collection
177     */
178    public Collection<? extends TestResult> getPassedTests() {
179        return emptyList();
180    }
181
182    /**
183     * Gets the "children" of this test result that were skipped
184     * @return the children of this test result, if any, or an empty list
185     */
186    public Collection<? extends TestResult> getSkippedTests() {
187        return emptyList();
188    }
189
190    /**
191     * If this test failed, then return the build number
192     * when this test started failing.
193     */
194    public int getFailedSince() {
195        return 0;
196    }
197
198    /**
199     * If this test failed, then return the run
200     * when this test started failing.
201     */
202    public Run<?,?> getFailedSinceRun() {
203        return null;
204    }
205
206    /**
207     * The stdout of this test.
208     */
209    public String getStdout() {
210        return "";
211    }
212
213    /**
214     * The stderr of this test.
215     */
216    public String getStderr() {
217        return "";
218    }
219
220    /**
221     * If there was an error or a failure, this is the stack trace, or otherwise null.
222     */
223    public String getErrorStackTrace() {
224        return "";
225    }
226
227    /**
228     * If there was an error or a failure, this is the text from the message.
229     */
230    public String getErrorDetails() {
231        return ""; 
232    }
233
234    /**
235     * @return true if the test was not skipped and did not fail, false otherwise.
236     */
237    public boolean isPassed() {
238        return ((getSkipCount() == 0) && (getFailCount() == 0));
239    }
240
241    public String toPrettyString() {
242        StringBuilder sb = new StringBuilder();
243        sb.append("{");
244        sb.append("Name: ").append(this.getName()).append(", ");
245        sb.append("Result: ").append(this.getBuildResult()).append(",\n");
246        sb.append("Total Count: ").append(this.getTotalCount()).append(", ");
247        sb.append("Fail: ").append(this.getFailCount()).append(", ");
248        sb.append("Skipt: ").append(this.getSkipCount()).append(", ");
249        sb.append("Pass: ").append(this.getSkipCount()).append(",\n");
250        sb.append("Test Result Class: " ).append(this.getClass().getName()).append(" }\n");
251        return sb.toString(); 
252    }
253
254    /**
255     * Annotate some text -- what does this do? 
256     * @param text
257     * @return
258     */
259    public String annotate(String text) {
260        if (text == null)
261                return null;
262        text = text.replace("&", "&amp;").replace("<", "&lt;").replaceAll(
263                        "\\b(https?://[^\\s)>]+)", "<a href=\"$1\">$1</a>");
264
265        for (TestAction action: getTestActions()) {
266                text = action.annotate(text);
267        }
268        return text;
269    }
270}