/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2001, ThoughtWorks, Inc.
* 200 E. Randolph, 25th Floor
* Chicago, IL 60601 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* + Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
package net.sourceforge.cruisecontrol.sourcecontrols;
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import net.sourceforge.cruisecontrol.CruiseControlException;
import net.sourceforge.cruisecontrol.Log;
import net.sourceforge.cruisecontrol.testutil.TestUtil.FilesToDelete;
import net.sourceforge.cruisecontrol.util.DateUtil;
/**
* Unit tests for BuildStatus.java.
*
*@author Garrick Olson
*/
public class BuildStatusTest extends TestCase {
private BuildStatus buildStatus;
private final FilesToDelete filesToDelete = new FilesToDelete();
protected void setUp() throws Exception {
buildStatus = new BuildStatus();
}
protected void tearDown() throws Exception {
buildStatus = null;
filesToDelete.delete();
}
/**
* Make sure the validate() method works properly.
*/
public void testValidate() throws Exception {
// Verify log directory is mandatory
try {
buildStatus.validate();
fail("Should have thrown exception indicating log directory is mandatory");
} catch (CruiseControlException e) {
assertEquals("Wrong exception", "'logdir' is required for BuildStatus", e.getMessage());
}
// Verify log directory must exist
buildStatus.setLogDir("does not exist");
try {
buildStatus.validate();
fail("Should have thrown exception indicating log directory must exist");
} catch (CruiseControlException e) {
assertTrue("Wrong exception", e.getMessage().startsWith("Log directory does not exist"));
}
// Verify log directory must be a directory
File tempFile = File.createTempFile("temp", "txt");
tempFile.deleteOnExit();
filesToDelete.add(tempFile);
buildStatus.setLogDir(tempFile.getAbsolutePath());
try {
buildStatus.validate();
fail("Should have thrown exception indicating log directory must be a directory");
} catch (CruiseControlException e) {
assertTrue("Wrong exception", e.getMessage().startsWith("Log directory is not a directory"));
}
// Set it to a directory and everything should be okay
buildStatus.setLogDir(tempFile.getParentFile().getAbsolutePath());
buildStatus.validate();
}
/**
* Verify the getModifications() method works properly.
*/
public void testGetModifications() throws Exception {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
buildStatus.setLogDir(tempDir.getAbsolutePath());
buildStatus.validate();
Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
calendar.add(Calendar.DATE, -1);
Date yesterday = calendar.getTime();
calendar.add(Calendar.DATE, -1);
Date twoDaysAgo = calendar.getTime();
// Should be no modifications at this point
List modifications = buildStatus.getModifications(twoDaysAgo, null);
assertEquals("Wrong number of modifications", 0, modifications.size());
// Verify an unsuccessful build does not show up
File yesterdayLog = new File(tempDir, Log.formatLogFileName(yesterday));
yesterdayLog.createNewFile();
filesToDelete.add(yesterdayLog);
modifications = buildStatus.getModifications(twoDaysAgo, null);
assertEquals("Wrong number of modifications", 0, modifications.size());
// Verify a successful build shows up
File yesterdayLog2 = new File(tempDir, Log.formatLogFileName(yesterday, "good.1"));
yesterdayLog2.createNewFile();
filesToDelete.add(yesterdayLog2);
modifications = buildStatus.getModifications(twoDaysAgo, null);
assertEquals("Wrong number of modifications", 1, modifications.size());
Map properties = buildStatus.getProperties();
// Verify properties were set correctly
assertEquals("Property was not set correctly", tempDir.getAbsolutePath(),
properties.get(BuildStatus.MOST_RECENT_LOGDIR_KEY));
assertEquals("Property was not set correctly", yesterdayLog2.getName(),
properties.get(BuildStatus.MOST_RECENT_LOGFILE_KEY));
assertEquals("Property was not set correctly", DateUtil.getFormattedTime(yesterday),
properties.get(BuildStatus.MOST_RECENT_LOGTIME_KEY));
assertEquals("Property was not set correctly", "good.1",
properties.get(BuildStatus.MOST_RECENT_LOGLABEL_KEY));
assertEquals(4, properties.size());
// Verify date range works
modifications = buildStatus.getModifications(today, null);
assertEquals("Wrong number of modifications", 0, modifications.size());
// Verify properties are set correctly when there are multiple modifications
File todayLog = new File(tempDir, Log.formatLogFileName(today, "good.2"));
todayLog.createNewFile();
filesToDelete.add(todayLog);
buildStatus.setProperty("property");
modifications = buildStatus.getModifications(twoDaysAgo, null);
assertEquals("Wrong number of modifications", 2, modifications.size());
properties = buildStatus.getProperties();
// Verify properties were set correctly
assertEquals("Property was not set correctly", tempDir.getAbsolutePath(), properties
.get(BuildStatus.MOST_RECENT_LOGDIR_KEY));
assertEquals("Property was not set correctly", todayLog.getName(), properties
.get(BuildStatus.MOST_RECENT_LOGFILE_KEY));
assertEquals("Property was not set correctly", DateUtil.getFormattedTime(today), properties
.get(BuildStatus.MOST_RECENT_LOGTIME_KEY));
assertEquals("Property was not set correctly", "good.2", properties.get(BuildStatus.MOST_RECENT_LOGLABEL_KEY));
assertEquals("true", properties.get("property"));
assertEquals(5, properties.size());
}
public void testVetoIfFailing() throws Exception {
buildStatus.setVetoIfFailing(true);
File tempDir = new File(System.getProperty("java.io.tmpdir"));
buildStatus.setLogDir(tempDir.getAbsolutePath());
buildStatus.validate();
Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
calendar.add(Calendar.DATE, -1);
Date yesterday = calendar.getTime();
calendar.add(Calendar.DATE, -1);
Date twoDaysAgo = calendar.getTime();
// Should be no modifications at this point
List modifications = buildStatus.getModifications(twoDaysAgo, null);
assertEquals("Wrong number of modifications", 0, modifications.size());
// Verify an unsuccessful build causes veto
File yesterdayLog = new File(tempDir, Log.formatLogFileName(yesterday));
yesterdayLog.createNewFile();
filesToDelete.add(yesterdayLog);
try {
buildStatus.getModifications(twoDaysAgo, null);
fail("build should abort if last build is failing");
} catch (RuntimeException e) {
assertEquals("most recent build failed: " + yesterdayLog.getName(), e.getMessage());
}
// Verify build vetoed if last build failed, even if out of date range
try {
buildStatus.getModifications(today, null);
fail("build should abort if last build is failing");
} catch (RuntimeException e) {
assertEquals("most recent build failed: " + yesterdayLog.getName(), e.getMessage());
}
// Verify passing build prevents veto
File todayLog = new File(tempDir, Log.formatLogFileName(today, "good.1"));
todayLog.createNewFile();
filesToDelete.add(todayLog);
buildStatus.getModifications(twoDaysAgo, null);
}
}