/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. */
  24. package hudson.tasks.test;
  25. import hudson.tasks.junit.TestAction;
  26. import hudson.model.AbstractBuild;
  27. import hudson.model.Run;
  28. import hudson.model.Result;
  29. import java.util.Collection;
  30. import static java.util.Collections.emptyList;
  31. /**
  32. * A class that represents a general concept of a test result, without any
  33. * language or implementation specifics.
  34. * Subclasses must add @Exported annotation to the fields they want to export.
  35. *
  36. * @sine 1.343
  37. */
  38. public abstract class TestResult extends TestObject {
  39. /**
  40. * If the concept of a parent action is important to a subclass, then it should
  41. * provide a non-noop implementation of this method.
  42. * @param action
  43. */
  44. public void setParentAction(AbstractTestResultAction action) {
  45. }
  46. /**
  47. * Returns the action that points to the top level test result includes
  48. * this test result.
  49. *
  50. * @return
  51. */
  52. public AbstractTestResultAction getParentAction() {
  53. return getOwner().getTestResultAction();
  54. }
  55. /**
  56. * Request that the result update its counts of its children. Does not
  57. * require a parent action or owner or siblings. Subclasses should
  58. * implement this, unless they are *always* in a tallied state.
  59. */
  60. public void tally() {
  61. }
  62. /**
  63. * Sets the parent test result
  64. * @param parent
  65. */
  66. public void setParent(TestObject parent) {
  67. }
  68. /**
  69. * Gets the human readable title of this result object.
  70. */
  71. public /* abstract */ String getTitle(){
  72. return "";
  73. }
  74. /**
  75. * Mark a build as unstable if there are failures. Otherwise, leave the
  76. * build result unchanged.
  77. *
  78. * @return {@link Result#UNSTABLE} if there are test failures, null otherwise.
  79. *
  80. */
  81. public Result getBuildResult() {
  82. if (getFailCount() > 0) {
  83. return Result.UNSTABLE;
  84. } else {
  85. return null;
  86. }
  87. }
  88. /**
  89. * Time it took to run this test. In seconds.
  90. */
  91. public /* abstract */ float getDuration() {
  92. return 0.0f;
  93. }
  94. /**
  95. * Gets the total number of passed tests.
  96. */
  97. public /* abstract */ int getPassCount() {
  98. return 0;
  99. }
  100. /**
  101. * Gets the total number of failed tests.
  102. */
  103. public /* abstract */ int getFailCount() {
  104. return 0;
  105. }
  106. /**
  107. * Gets the total number of skipped tests.
  108. */
  109. public /* abstract */ int getSkipCount() {
  110. return 0;
  111. }
  112. /**
  113. * Gets the counter part of this {@link TestResult} in the previous run.
  114. *
  115. * @return null if no such counter part exists.
  116. */
  117. public TestResult getPreviousResult() {
  118. AbstractBuild<?,?> b = getOwner();
  119. if (b == null) {
  120. return null;
  121. }
  122. while(true) {
  123. b = b.getPreviousBuild();
  124. if(b==null)
  125. return null;
  126. AbstractTestResultAction r = b.getAction(getParentAction().getClass());
  127. if(r!=null) {
  128. TestResult result = r.findCorrespondingResult(this.getId());
  129. if (result!=null)
  130. return result;
  131. }
  132. }
  133. }
  134. /**
  135. * Gets the counter part of this {@link TestResult} in the specified run.
  136. *
  137. * @return null if no such counter part exists.
  138. */
  139. public TestResult getResultInBuild(AbstractBuild<?,?> build) {
  140. AbstractTestResultAction tra = build.getAction(getParentAction().getClass());
  141. if (tra == null) {
  142. tra = build.getAction(AbstractTestResultAction.class);
  143. }
  144. return (tra == null) ? null : tra.findCorrespondingResult(this.getId());
  145. }
  146. /**
  147. * Gets the "children" of this test result that failed
  148. * @return the children of this test result, if any, or an empty collection
  149. */
  150. public Collection<? extends TestResult> getFailedTests() {
  151. return emptyList();
  152. }
  153. /**
  154. * Gets the "children" of this test result that passed
  155. * @return the children of this test result, if any, or an empty collection
  156. */
  157. public Collection<? extends TestResult> getPassedTests() {
  158. return emptyList();
  159. }
  160. /**
  161. * Gets the "children" of this test result that were skipped
  162. * @return the children of this test result, if any, or an empty list
  163. */
  164. public Collection<? extends TestResult> getSkippedTests() {
  165. return emptyList();
  166. }
  167. /**
  168. * If this test failed, then return the build number
  169. * when this test started failing.
  170. */
  171. public int getFailedSince() {
  172. return 0;
  173. }
  174. /**
  175. * If this test failed, then return the run
  176. * when this test started failing.
  177. */
  178. public Run<?,?> getFailedSinceRun() {
  179. return null;
  180. }
  181. /**
  182. * The stdout of this test.
  183. */
  184. public String getStdout() {
  185. return "";
  186. }
  187. /**
  188. * The stderr of this test.
  189. */
  190. public String getStderr() {
  191. return "";
  192. }
  193. /**
  194. * If there was an error or a failure, this is the stack trace, or otherwise null.
  195. */
  196. public String getErrorStackTrace() {
  197. return "";
  198. }
  199. /**
  200. * If there was an error or a failure, this is the text from the message.
  201. */
  202. public String getErrorDetails() {
  203. return "";
  204. }
  205. /**
  206. * @return true if the test was not skipped and did not fail, false otherwise.
  207. */
  208. public boolean isPassed() {
  209. return ((getSkipCount() == 0) && (getFailCount() == 0));
  210. }
  211. public String toPrettyString() {
  212. StringBuilder sb = new StringBuilder();
  213. sb.append("{");
  214. sb.append("Name: ").append(this.getName()).append(", ");
  215. sb.append("Result: ").append(this.getBuildResult()).append(",\n");
  216. sb.append("Total Count: ").append(this.getTotalCount()).append(", ");
  217. sb.append("Fail: ").append(this.getFailCount()).append(", ");
  218. sb.append("Skipt: ").append(this.getSkipCount()).append(", ");
  219. sb.append("Pass: ").append(this.getSkipCount()).append(",\n");
  220. sb.append("Test Result Class: " ).append(this.getClass().getName()).append(" }\n");
  221. return sb.toString();
  222. }
  223. /**
  224. * Annotate some text -- what does this do?
  225. * @param text
  226. * @return
  227. */
  228. public String annotate(String text) {
  229. if (text == null)
  230. return null;
  231. text = text.replace("&", "&amp;").replace("<", "&lt;").replaceAll(
  232. "\\b(https?://[^\\s)>]+)", "<a href=\"$1\">$1</a>");
  233. for (TestAction action: getTestActions()) {
  234. text = action.annotate(text);
  235. }
  236. return text;
  237. }
  238. }