001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2007, ThoughtWorks, Inc.
004: * 200 E. Randolph, 25th Floor
005: * Chicago, IL 60601 USA
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * + Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * + Redistributions in binary form must reproduce the above
016: * copyright notice, this list of conditions and the following
017: * disclaimer in the documentation and/or other materials provided
018: * with the distribution.
019: *
020: * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
021: * names of its contributors may be used to endorse or promote
022: * products derived from this software without specific prior
023: * written permission.
024: *
025: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
029: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
030: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
031: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
032: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
033: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
034: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036: ********************************************************************************/package net.sourceforge.cruisecontrol.dashboard.web.command;
037:
038: import java.util.Collection;
039: import java.util.HashMap;
040: import java.util.Map;
041:
042: import net.sourceforge.cruisecontrol.dashboard.Build;
043: import net.sourceforge.cruisecontrol.dashboard.BuildDetail;
044: import net.sourceforge.cruisecontrol.dashboard.BuildSummary;
045: import net.sourceforge.cruisecontrol.dashboard.CurrentStatus;
046: import net.sourceforge.cruisecontrol.dashboard.LogFile;
047: import net.sourceforge.cruisecontrol.dashboard.PreviousResult;
048: import net.sourceforge.cruisecontrol.dashboard.testhelpers.DataUtils;
049: import net.sourceforge.cruisecontrol.dashboard.utils.CCDateFormatter;
050:
051: import org.apache.commons.lang.StringUtils;
052: import org.jmock.Mock;
053: import org.jmock.cglib.MockObjectTestCase;
054: import org.joda.time.DateTime;
055:
056: public class BuildCommandTest extends MockObjectTestCase {
057: private LogFile logFile;
058:
059: private LogFile passedLogFile;
060:
061: protected void setUp() throws Exception {
062: super .setUp();
063: logFile = new LogFile("log19991212050505.xml");
064: passedLogFile = new LogFile("log19991212050505Lbuild.9.xml");
065: }
066:
067: public void testBuildCommandShouldTakeBuildAsContructor() {
068: Map props = new HashMap();
069: props.put("projectname", "project 1");
070: BuildDetail build = new BuildDetail(logFile, props);
071: BuildCommand command = new BuildCommand(build, null);
072: assertEquals("project 1", command.getBuild().getProjectName());
073: assertFalse(command.getBuild().hasPassed());
074: }
075:
076: public void testShouldReturnClassNameAsLongFailedWhenBuildIsMoreThanFailed24HoursAgo() {
077: BuildDetail build = new BuildDetail(logFile);
078: BuildCommand command = new BuildCommand(build, null);
079: BuildSummary buildSummary = new BuildSummary("",
080: PreviousResult.PASSED,
081: DataUtils.PASSING_BUILD_LBUILD_0_XML);
082: command.updateCssLevel(buildSummary);
083: assertEquals("8", command.getLevel());
084: }
085:
086: public void testShouldReturnClassNameAsFailedWhenBuildIsLessThanFailed24HoursAgo() {
087: BuildDetail build = new BuildDetail(logFile);
088: BuildCommand command = new BuildCommand(build, null);
089: String logFileName = "log"
090: + CCDateFormatter.yyyyMMddHHmmss(new DateTime())
091: + ".xml";
092: BuildSummary buildSummary = new BuildSummary("",
093: PreviousResult.PASSED, logFileName);
094: command.updateCssLevel(buildSummary);
095: assertEquals("0", command.getLevel());
096: }
097:
098: public void testShouldReturnClassNameAsFailedWhenBuildNeverPassed() {
099: BuildDetail build = new BuildDetail(new LogFile(
100: "log20051209122103.xml"));
101: BuildCommand command = new BuildCommand(build, null);
102: command.updateCssLevel(null);
103: assertEquals("8", command.getLevel());
104: }
105:
106: public void testCassNameShouldBeLevel8WhenTheLatestSuccessfulBuildIs24HoursAgo()
107: throws Exception {
108: BuildDetail build = new BuildDetail(passedLogFile);
109: BuildCommand buildCommand = new BuildCommand(build, null);
110: DateTime buildDate = new DateTime().minusYears(2);
111: String logFileName = "log"
112: + CCDateFormatter.yyyyMMddHHmmss(buildDate) + ".xml";
113: BuildSummary buildSummary = new BuildSummary("",
114: PreviousResult.PASSED, logFileName);
115: buildCommand.updateCssLevel(buildSummary);
116: assertEquals("8", buildCommand.getLevel());
117: }
118:
119: public void testShouldBeAbleToDelegateTheInvocationToBuildSummary()
120: throws Exception {
121: Build summary = new BuildSummary("project1",
122: PreviousResult.PASSED,
123: DataUtils.PASSING_BUILD_LBUILD_0_XML);
124: BuildCommand command = new BuildCommand(summary, null);
125: assertEquals("project1", command.getBuild().getProjectName());
126: }
127:
128: public void testCalculatesElapsedBuildTime() throws Exception {
129: Mock mockBuildSummary = mock(BuildSummary.class,
130: new Class[] { String.class }, new Object[] { "" });
131: BuildCommand command = new BuildCommand(
132: (Build) mockBuildSummary.proxy(), null);
133: DateTime fivePM = CCDateFormatter.format("2007-04-20 17:00:00",
134: "yyyy-MM-dd HH:mm:ss");
135: mockBuildSummary.expects(once()).method("getBuildingSince")
136: .will(returnValue(fivePM));
137: DateTime sixPM = CCDateFormatter.format("2007-04-20 18:00:00",
138: "yyyy-MM-dd HH:mm:ss");
139: Long elapsedSeconds = command.getElapsedTimeBuilding(sixPM);
140: assertEquals(new Long(3600), elapsedSeconds);
141: }
142:
143: public void testShouldClassNameAsDarkRedWhenBuildIsFailed24HoursAgo() {
144: Build buildSummary = new BuildSummary("",
145: PreviousResult.FAILED, DataUtils.FAILING_BUILD_XML);
146: Build lastSuccessful = new BuildSummary("",
147: PreviousResult.PASSED,
148: DataUtils.PASSING_BUILD_LBUILD_0_XML);
149: BuildCommand command = new BuildCommand(buildSummary, null);
150: command.updateCssLevel(lastSuccessful);
151: assertEquals("8", command.toJsonHash().get(
152: BuildCommand.CSS_LEVEL));
153: }
154:
155: public void testJsonHashShouldNotReturnDarkRedWhenBuildIsPassed() {
156: BuildSummary buildSummary = new BuildSummary("",
157: PreviousResult.PASSED,
158: DataUtils.PASSING_BUILD_LBUILD_0_XML);
159: buildSummary.updateStatus(CurrentStatus.WAITING
160: .getCruiseStatus());
161: BuildCommand command = new BuildCommand(buildSummary, null);
162: BuildSummary lastSuccessful = new BuildSummary("",
163: PreviousResult.PASSED,
164: DataUtils.PASSING_BUILD_LBUILD_0_XML);
165: command.updateCssLevel(lastSuccessful);
166: Map json = command.toJsonHash();
167: assertEquals("8", json.get(BuildCommand.CSS_LEVEL));
168: assertEquals(PreviousResult.PASSED.getStatus(), json
169: .get("previous_result"));
170: assertEquals(CurrentStatus.WAITING.getStatus(), json
171: .get("current_status"));
172:
173: String jsonString = command.toJsonString();
174: assertJsonContains(jsonString, BuildCommand.CSS_LEVEL, "8");
175: assertJsonContains(jsonString, "previous_result",
176: PreviousResult.PASSED.getStatus());
177: assertJsonContains(jsonString, "current_status",
178: CurrentStatus.WAITING.getStatus());
179: }
180:
181: public void testJsonHashShouldNotReturnCurrentStatusWhenLastSuccessfulBuildIsEmpty() {
182: BuildSummary buildSummary = new BuildSummary("",
183: PreviousResult.FAILED, DataUtils.FAILING_BUILD_XML);
184: buildSummary.updateStatus(CurrentStatus.WAITING
185: .getCruiseStatus());
186: BuildCommand command = new BuildCommand(buildSummary, null);
187: command.updateCssLevel(null);
188: Map json = command.toJsonHash();
189: assertEquals("8", json.get(BuildCommand.CSS_LEVEL));
190: assertEquals(PreviousResult.FAILED.getStatus(), json
191: .get("previous_result"));
192: assertEquals("Waiting", json.get("current_status"));
193:
194: String jsonString = command.toJsonString();
195: assertJsonContains(jsonString, BuildCommand.CSS_LEVEL, "8");
196: assertJsonContains(jsonString, "previous_result",
197: PreviousResult.FAILED.getStatus());
198: assertJsonContains(jsonString, "current_status",
199: CurrentStatus.WAITING.getStatus());
200: }
201:
202: public void testJsonHashShouldReturnBuildSinceForActiveBuild()
203: throws Exception {
204: BuildSummary buildSummary = new BuildSummary("",
205: PreviousResult.FAILED, DataUtils.FAILING_BUILD_XML);
206: buildSummary.updateStatus("now building");
207: buildSummary.updateBuildSince(new DateTime());
208: BuildCommand command = new BuildCommand(buildSummary, null);
209: Map json = command.toJsonHash();
210: assertTrue(json.containsKey("latest_build_date"));
211: assertEquals(PreviousResult.FAILED.getStatus(), json
212: .get("previous_result"));
213: assertEquals("Building", json.get("current_status"));
214:
215: String jsonString = command.toJsonString();
216: assertJsonContains(jsonString, "previous_result",
217: PreviousResult.FAILED.getStatus());
218: assertJsonContains(jsonString, "current_status",
219: CurrentStatus.BUILDING.getStatus());
220: }
221:
222: public void testJsonHashShouldReturnLowerCaseOfStatusWhenInvokeDetaultCss()
223: throws Exception {
224: BuildSummary buildSummary = new BuildSummary("",
225: PreviousResult.UNKNOWN, DataUtils.FAILING_BUILD_XML);
226: buildSummary.updateStatus(CurrentStatus.WAITING
227: .getCruiseStatus());
228: BuildCommand command = new BuildCommand(buildSummary, null);
229: Map json = command.toJsonHash();
230: assertTrue(json.containsKey("latest_build_date"));
231: assertEquals(PreviousResult.UNKNOWN.getStatus(), json
232: .get("previous_result"));
233: assertEquals(CurrentStatus.WAITING.getStatus(), json
234: .get("current_status"));
235:
236: String jsonString = command.toJsonString();
237: assertJsonContains(jsonString, "previous_result",
238: PreviousResult.UNKNOWN.getStatus());
239: assertJsonContains(jsonString, "current_status",
240: CurrentStatus.WAITING.getStatus());
241: }
242:
243: public void testJsonHashShouldNotReturnBuildSinceForNonActiveBuild()
244: throws Exception {
245: BuildSummary buildSummary = new BuildSummary("",
246: PreviousResult.FAILED, DataUtils.FAILING_BUILD_XML);
247: buildSummary.updateStatus(CurrentStatus.DISCONTINUED
248: .getCruiseStatus());
249: BuildCommand command = new BuildCommand(buildSummary, null);
250: Map json = command.toJsonHash();
251: assertTrue(json.containsKey("latest_build_date"));
252: assertEquals(PreviousResult.FAILED.getStatus(), json
253: .get("previous_result"));
254: assertEquals(CurrentStatus.DISCONTINUED.getStatus(), json
255: .get("current_status"));
256:
257: String jsonString = command.toJsonString();
258: assertJsonContains(jsonString, "previous_result",
259: PreviousResult.FAILED.getStatus());
260: assertJsonContains(jsonString, "current_status",
261: CurrentStatus.DISCONTINUED.getStatus());
262: }
263:
264: public void testShouldReturnUnknownIfDurationIsNull()
265: throws Exception {
266: Mock build = mock(Build.class);
267: build.expects(atLeastOnce()).method("getDuration").will(
268: returnValue(null));
269: BuildCommand command = new BuildCommand((Build) build.proxy(),
270: null);
271: assertEquals("Unknown", command.getDuration());
272: }
273:
274: public void testShouldReturnEmptyCollectionWhenNoModificationsAvailableFromLogFile()
275: throws Exception {
276: Mock build = mock(Build.class);
277: build.expects(atLeastOnce()).method("getModificationSet").will(
278: returnValue(null));
279: BuildCommand command = new BuildCommand((Build) build.proxy(),
280: null);
281: final Collection modifications = command.getModifications();
282: assertTrue("Modifications should be empty", modifications
283: .isEmpty());
284: }
285:
286: private void assertJsonContains(String jsonString, String key,
287: String value) {
288: assertTrue("Should contain \"" + key + "\" : \"" + value
289: + "\" in\n" + jsonString, StringUtils.contains(
290: jsonString, "\"" + key + "\" : \"" + value + "\""));
291: }
292: }
|