/********************************************************************************
* 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.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import junit.framework.TestCase;
import net.sourceforge.cruisecontrol.CruiseControlException;
import net.sourceforge.cruisecontrol.Modification;
import net.sourceforge.cruisecontrol.testutil.TestUtil.FilesToDelete;
import net.sourceforge.cruisecontrol.util.CVSDateUtil;
import net.sourceforge.cruisecontrol.util.Commandline;
import net.sourceforge.cruisecontrol.util.MockCommandline;
/**
* @author Robert Watkins
* @author <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a>
*/
public class ConcurrentVersionsSystemTest extends TestCase {
private static final String[] CVS_VERSION_COMMANDLINE = new String[] { "cvs", "version" };
private FilesToDelete filesToDelete;
private TimeZone originalTimeZone;
protected void setUp() throws Exception {
originalTimeZone = TimeZone.getDefault();
filesToDelete = new FilesToDelete();
}
protected void tearDown() throws Exception {
TimeZone.setDefault(originalTimeZone);
originalTimeZone = null;
filesToDelete.delete();
}
public void testParseStream() throws IOException, ParseException {
// ensure CVS version and simulated outputs are in sync
final String cvsVersion = "1.11.16";
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion(cvsVersion));
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
emailAliases.put("alden", "alden@users.sourceforge.net");
emailAliases.put("tim", "tim@tim.net");
cvs.setMailAliases(emailAliases);
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-11.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 5 modifications.", 5, modifications.size());
Modification mod1 = new Modification("cvs");
Modification.ModifiedFile mod1file = mod1.createModifiedFile("log4j.properties", null);
mod1file.action = "modified";
mod1.revision = "1.2";
mod1.modifiedTime = parseLogDateFormat("2002/03/13 13:45:50 GMT-6:00");
mod1.userName = "alden";
mod1.comment = "Shortening ConversionPattern so we don't use up all of the available screen space.";
mod1.emailAddress = "alden@users.sourceforge.net";
Modification mod2 = new Modification("cvs");
Modification.ModifiedFile mod2file = mod2.createModifiedFile("build.xml", null);
mod2file.action = "modified";
mod2.revision = "1.41";
mod2.modifiedTime = parseLogDateFormat("2002/03/13 19:56:34 GMT-6:00");
mod2.userName = "alden";
mod2.comment = "Added target to clean up test results.";
mod2.emailAddress = "alden@users.sourceforge.net";
Modification mod3 = new Modification("cvs");
Modification.ModifiedFile mod3file = mod3.createModifiedFile("build.xml", "main");
mod3file.action = "modified";
mod3.revision = "1.42";
mod3.modifiedTime = parseLogDateFormat("2002/03/15 13:20:28 GMT-6:00");
mod3.userName = "alden";
mod3.comment = "enabled debug info when compiling tests.";
mod3.emailAddress = "alden@users.sourceforge.net";
Modification mod4 = new Modification("cvs");
Modification.ModifiedFile mod4file = mod4.createModifiedFile("kungfu.xml", "main");
mod4file.action = "deleted";
mod4.revision = "1.2";
mod4.modifiedTime = parseLogDateFormat("2002/03/13 13:45:42 GMT-6:00");
mod4.userName = "alden";
mod4.comment = "Hey, look, a deleted file.";
mod4.emailAddress = "alden@users.sourceforge.net";
Modification mod5 = new Modification("cvs");
Modification.ModifiedFile mod5file = mod5.createModifiedFile("stuff.xml", "main");
mod5file.action = "deleted";
mod5.revision = "1.4";
mod5.modifiedTime = parseLogDateFormat("2002/03/13 13:38:42 GMT-6:00");
mod5.userName = "alden";
mod5.comment = "Hey, look, another deleted file.";
mod5.emailAddress = "alden@users.sourceforge.net";
assertEquals(mod5, modifications.get(0));
assertEquals(mod4, modifications.get(1));
assertEquals(mod1, modifications.get(2));
assertEquals(mod2, modifications.get(3));
assertEquals(mod3, modifications.get(4));
}
public void testParseStreamRemote() throws IOException, ParseException {
// ensure CVS version and simulated outputs are in sync
final String cvsVersion = "1.11.16";
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion(cvsVersion));
cvs.setModule("cruisecontrol");
cvs.setCvsRoot(":pserver:anonymous@cvs.sourceforge.net:/cvsroot/cruisecontrol");
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
emailAliases.put("alden", "alden@users.sourceforge.net");
emailAliases.put("tim", "tim@tim.net");
cvs.setMailAliases(emailAliases);
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-11-remote.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 5 modifications.", 5, modifications.size());
Modification mod1 = new Modification("cvs");
Modification.ModifiedFile mod1file = mod1.createModifiedFile("log4j.properties", null);
mod1file.action = "modified";
mod1.revision = "1.2";
mod1.modifiedTime = parseLogDateFormat("2002/03/13 13:45:50 GMT-6:00");
mod1.userName = "alden";
mod1.comment = "Shortening ConversionPattern so we don't use up all of the available screen space.";
mod1.emailAddress = "alden@users.sourceforge.net";
Modification mod2 = new Modification("cvs");
Modification.ModifiedFile mod2file = mod2.createModifiedFile("build.xml", null);
mod2file.action = "modified";
mod2.revision = "1.41";
mod2.modifiedTime = parseLogDateFormat("2002/03/13 19:56:34 GMT-6:00");
mod2.userName = "alden";
mod2.comment = "Added target to clean up test results.";
mod2.emailAddress = "alden@users.sourceforge.net";
Modification mod3 = new Modification("cvs");
Modification.ModifiedFile mod3file = mod3.createModifiedFile("build.xml", "main");
mod3file.action = "modified";
mod3.revision = "1.42";
mod3.modifiedTime = parseLogDateFormat("2002/03/15 13:20:28 GMT-6:00");
mod3.userName = "alden";
mod3.comment = "enabled debug info when compiling tests.";
mod3.emailAddress = "alden@users.sourceforge.net";
Modification mod4 = new Modification("cvs");
Modification.ModifiedFile mod4file = mod4.createModifiedFile("kungfu.xml", "main");
mod4file.action = "deleted";
mod4.revision = "1.2";
mod4.modifiedTime = parseLogDateFormat("2002/03/13 13:45:42 GMT-6:00");
mod4.userName = "alden";
mod4.comment = "Hey, look, a deleted file.";
mod4.emailAddress = "alden@users.sourceforge.net";
Modification mod5 = new Modification("cvs");
Modification.ModifiedFile mod5file = mod5.createModifiedFile("stuff.xml", "main");
mod5file.action = "deleted";
mod5.revision = "1.4";
mod5.modifiedTime = parseLogDateFormat("2002/03/13 13:38:42 GMT-6:00");
mod5.userName = "alden";
mod5.comment = "Hey, look, another deleted file.";
mod5.emailAddress = "alden@users.sourceforge.net";
assertEquals(mod5, modifications.get(0));
assertEquals(mod4, modifications.get(1));
assertEquals(mod1, modifications.get(2));
assertEquals(mod2, modifications.get(3));
assertEquals(mod3, modifications.get(4));
}
public void testParseStreamSlashDateFormat() throws IOException, ParseException {
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.12.9"));
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
emailAliases.put("bar", "bar@mailinator.com");
cvs.setMailAliases(emailAliases);
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-12-9slashdate.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 1 modification.", 1, modifications.size());
Modification mod1 = new Modification("cvs");
Modification.ModifiedFile mod1file = mod1.createModifiedFile("makefile", null);
mod1file.action = "modified";
mod1.revision = "1.1";
mod1.modifiedTime = CVSDateUtil.parseCVSDate("2006-11-30 20:57:14 GMT");
mod1.userName = "bar";
mod1.comment = "compiles...doubt it works";
mod1.emailAddress = "bar@mailinator.com";
assertEquals(mod1, modifications.get(0));
}
public void testParseStreamNewFormat() throws IOException, ParseException {
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.12.9"));
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
emailAliases.put("jerome", "jerome@coffeebreaks.org");
cvs.setMailAliases(emailAliases);
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-12.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 1 modification.", 1, modifications.size());
Modification mod1 = new Modification("cvs");
Modification.ModifiedFile mod1file = mod1.createModifiedFile("log4j.properties", null);
mod1file.action = "modified";
mod1.revision = "1.1";
mod1.modifiedTime = CVSDateUtil.parseCVSDate("2004-03-25 00:58:49 GMT");
mod1.userName = "jerome";
mod1.comment = "initial checkin";
mod1.emailAddress = "jerome@coffeebreaks.org";
assertEquals(mod1, modifications.get(0));
}
// disabled
// @todo Update cvslog1-11branch.txt file and restore test of branch parsing - see CC-548
public void xxxtestParseStreamBranch() throws IOException, ParseException {
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
emailAliases.put("alden", "alden@users.sourceforge.net");
cvs.setMailAliases(emailAliases);
cvs.setTag("BRANCH_TEST_BUILD");
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-11branch.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 4 modifications.", 4, modifications.size());
Modification mod1 = new Modification("cvs");
mod1.revision = "1.1.2.4";
mod1.modifiedTime = parseLogDateFormat("2002/10/03 16:05:23 GMT");
mod1.userName = "tim";
mod1.comment = "Test commit once more";
Modification.ModifiedFile mod1file = mod1.createModifiedFile("test.version", null);
mod1file.action = "modified";
mod1file.revision = mod1.revision;
Modification mod2 = new Modification("cvs");
mod2.revision = "1.1.2.3";
mod2.modifiedTime = parseLogDateFormat("2002/10/03 14:24:17 GMT");
mod2.userName = "tim";
mod2.comment = "Test commit";
Modification.ModifiedFile mod2file = mod2.createModifiedFile("test.version", null);
mod2file.action = "modified";
mod2file.revision = mod2.revision;
Modification mod3 = new Modification("cvs");
mod3.revision = "1.1.2.2";
mod3.modifiedTime = parseLogDateFormat("2002/10/02 21:54:44 GMT");
mod3.userName = "tim";
mod3.comment = "Update parameters for test";
Modification.ModifiedFile mod3file = mod3.createModifiedFile("test.version", null);
mod3file.action = "modified";
mod3file.revision = mod3.revision;
Modification mod4 = new Modification("cvs");
mod4.revision = "1.1.2.1";
mod4.modifiedTime = parseLogDateFormat("2002/10/02 21:49:31 GMT");
mod4.userName = "tim";
mod4.comment = "Add parameters for test";
Modification.ModifiedFile mod4file = mod4.createModifiedFile("test.version", null);
mod4file.action = "modified";
mod4file.revision = mod4.revision;
assertEquals(mod4, modifications.get(0));
assertEquals(mod3, modifications.get(1));
assertEquals(mod2, modifications.get(2));
assertEquals(mod1, modifications.get(3));
}
public void testParseStreamTagNoBranch() throws IOException, ParseException {
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.12.9"));
final Hashtable<String, String> emailAliases = new Hashtable<String, String>();
cvs.setMailAliases(emailAliases);
cvs.setTag("TEST");
BufferedInputStream input = new BufferedInputStream(loadTestLog("cvslog1-12tagnobranch.txt"));
final List<Modification> modifications = cvs.parseStream(input);
input.close();
Collections.sort(modifications);
assertEquals("Should have returned 1 modification.", 1, modifications.size());
Modification mod1 = new Modification("cvs");
mod1.revision = "1.49";
mod1.modifiedTime = parseLogDateFormat("2005/08/22 17:28:13 GMT");
mod1.userName = "jerome";
mod1.comment = "Test commit";
Modification.ModifiedFile mod1file = mod1.createModifiedFile("test.version", null);
mod1file.action = "modified";
mod1file.revision = mod1.revision;
assertEquals(mod1, modifications.get(0));
}
public void testGetProperties() throws IOException {
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs.setMailAliases(new Hashtable<String, String>());
cvs.setProperty("property");
cvs.setPropertyOnDelete("propertyOnDelete");
String logName = "cvslog1-11.txt";
BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
cvs.parseStream(input);
input.close();
Map table = cvs.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Should be two properties.", 2, table.size());
assertTrue("Property was not set.", table.containsKey("property"));
assertTrue("PropertyOnDelete was not set.", table.containsKey("propertyOnDelete"));
// negative test
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs2 = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs2.setMailAliases(new Hashtable<String, String>());
input = new BufferedInputStream(loadTestLog(logName));
cvs2.parseStream(input);
input.close();
table = cvs2.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Shouldn't be any properties.", 0, table.size());
}
public void testGetPropertiesNoModifications() throws IOException {
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs.setMailAliases(new Hashtable<String, String>());
cvs.setProperty("property");
cvs.setPropertyOnDelete("propertyOnDelete");
String logName = "cvslog1-11noMods.txt";
BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
cvs.parseStream(input);
input.close();
Map table = cvs.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Shouldn't be any properties.", 0, table.size());
}
public void testGetPropertiesOnlyModifications() throws IOException {
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs.setMailAliases(new Hashtable<String, String>());
cvs.setProperty("property");
cvs.setPropertyOnDelete("propertyOnDelete");
String logName = "cvslog1-11mods.txt";
BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
cvs.parseStream(input);
input.close();
Map table = cvs.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Should be one property.", 1, table.size());
assertTrue("Property was not set.", table.containsKey("property"));
// negative test
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs2 = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs2.setMailAliases(new Hashtable<String, String>());
cvs2.setPropertyOnDelete("propertyOnDelete");
input = new BufferedInputStream(loadTestLog(logName));
cvs2.parseStream(input);
input.close();
table = cvs2.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Shouldn't be any properties.", 0, table.size());
}
public void testGetPropertiesOnlyDeletions() throws IOException {
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs.setMailAliases(new Hashtable<String, String>());
cvs.setPropertyOnDelete("propertyOnDelete");
String logName = "cvslog1-11del.txt";
BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
cvs.parseStream(input);
input.close();
Map table = cvs.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Should be one property.", 1, table.size());
assertTrue("PropertyOnDelete was not set.", table.containsKey("propertyOnDelete"));
// negative test
// ensure CVS version and simulated outputs are in sync
ConcurrentVersionsSystem cvs2 = new SpecificVersionCVS(getOfficialCVSVersion("1.11.16"));
cvs2.setMailAliases(new Hashtable<String, String>());
input = new BufferedInputStream(loadTestLog(logName));
cvs2.parseStream(input);
input.close();
table = cvs2.getProperties();
assertNotNull("Table of properties shouldn't be null.", table);
assertEquals("Shouldn't be any properties.", 0, table.size());
}
public void testBuildHistoryCommand() throws CruiseControlException {
Date checkTime = new Date();
long tenMinutes = 10 * 60 * 1000;
Date lastBuildTime = new Date(checkTime.getTime() - tenMinutes);
ConcurrentVersionsSystem cvs = new ConcurrentVersionsSystem();
cvs.setCvsRoot("cvsroot");
cvs.setLocalWorkingCopy(".");
String[] expectedCommand = {
"cvs",
"-d",
"cvsroot",
"-q",
"log",
"-N",
"-S",
"-d" + ConcurrentVersionsSystem.formatCVSDate(lastBuildTime) + "<"
+ ConcurrentVersionsSystem.formatCVSDate(checkTime), "-b" };
String[] noTagCommand = cvs.buildHistoryCommand(lastBuildTime, checkTime).getCommandline();
assertCommandsEqual(expectedCommand, noTagCommand);
cvs.setTag("");
String[] emptyStringTagCommand = cvs.buildHistoryCommand(lastBuildTime, checkTime).getCommandline();
assertCommandsEqual(expectedCommand, emptyStringTagCommand);
cvs.setTag("HEAD");
String[] headTagCommand = cvs.buildHistoryCommand(lastBuildTime, checkTime).getCommandline();
assertCommandsEqual(expectedCommand, headTagCommand);
cvs.setReallyQuiet(true);
expectedCommand[3] = "-Q";
String[] reallyQuietCommand = cvs.buildHistoryCommand(lastBuildTime, checkTime).getCommandline();
assertCommandsEqual(expectedCommand, reallyQuietCommand);
}
private void assertCommandsEqual(String[] expectedCommand, String[] actualCommand) {
assertEquals("Mismatched lengths!", expectedCommand.length, actualCommand.length);
for (int i = 0; i < expectedCommand.length; i++) {
assertEquals(expectedCommand[i], actualCommand[i]);
}
}
public void testBuildHistoryCommandWithTag() throws CruiseControlException {
Date lastBuildTime = new Date();
ConcurrentVersionsSystem element = new ConcurrentVersionsSystem();
element.setCvsRoot("cvsroot");
element.setLocalWorkingCopy(".");
element.setTag("sometag");
String[] expectedCommand = new String[] {
"cvs",
"-d",
"cvsroot",
"-q",
"log",
"-N",
"-S",
"-d" + ConcurrentVersionsSystem.formatCVSDate(lastBuildTime) + "<"
+ ConcurrentVersionsSystem.formatCVSDate(lastBuildTime), "-rsometag" };
String[] actualCommand = element.buildHistoryCommand(lastBuildTime, lastBuildTime).getCommandline();
assertCommandsEqual(expectedCommand, actualCommand);
}
public void testHistoryCommandNullLocal() throws CruiseControlException {
Date lastBuildTime = new Date();
ConcurrentVersionsSystem element = new ConcurrentVersionsSystem();
element.setCvsRoot("cvsroot");
element.setModule("module");
element.setLocalWorkingCopy(null);
String[] expectedCommand = new String[] {
"cvs",
"-d",
"cvsroot",
"-q",
"rlog",
"-N",
"-S",
"-d" + ConcurrentVersionsSystem.formatCVSDate(lastBuildTime) + "<"
+ ConcurrentVersionsSystem.formatCVSDate(lastBuildTime), "-b", "module" };
String[] actualCommand = element.buildHistoryCommand(lastBuildTime, lastBuildTime).getCommandline();
assertCommandsEqual(expectedCommand, actualCommand);
}
public void testHistoryCommandWithCompression() throws CruiseControlException {
Date lastBuildTime = new Date();
ConcurrentVersionsSystem element = new ConcurrentVersionsSystem();
element.setLocalWorkingCopy(".");
element.setCompression("9");
String[] expectedCommand = new String[] {
"cvs",
"-z9",
"-q",
"log",
"-N",
"-S",
"-d" + ConcurrentVersionsSystem.formatCVSDate(lastBuildTime) + "<"
+ ConcurrentVersionsSystem.formatCVSDate(lastBuildTime), "-b" };
String[] actualCommand = element.buildHistoryCommand(lastBuildTime, lastBuildTime).getCommandline();
assertCommandsEqual(expectedCommand, actualCommand);
}
public void testHistoryCommandNullCVSROOT() throws CruiseControlException {
Date lastBuildTime = new Date();
ConcurrentVersionsSystem element = new ConcurrentVersionsSystem();
element.setCvsRoot(null);
element.setLocalWorkingCopy(".");
String[] expectedCommand = new String[] {
"cvs",
"-q",
"log",
"-N",
"-S",
"-d" + ConcurrentVersionsSystem.formatCVSDate(lastBuildTime) + "<"
+ ConcurrentVersionsSystem.formatCVSDate(lastBuildTime), "-b" };
String[] actualCommand = element.buildHistoryCommand(lastBuildTime, lastBuildTime).getCommandline();
assertCommandsEqual(expectedCommand, actualCommand);
}
public void testParseLogDate() throws ParseException {
TimeZone tz = TimeZone.getDefault();
Date may18SixPM2001 = new GregorianCalendar(2001, 4, 18, 18, 0, 0).getTime();
assertEquals(may18SixPM2001, new SimpleDateFormat(ConcurrentVersionsSystem.LOG_DATE_FORMAT)
.parse("2001/05/18 18:00:00 " + tz.getDisplayName(tz.inDaylightTime(may18SixPM2001), TimeZone.SHORT)));
}
public void testFormatCVSDateGMTPlusZero() {
TimeZone.setDefault(TimeZone.getTimeZone("GMT+0:00"));
Date mayEighteenSixPM2001 = new GregorianCalendar(2001, 4, 18, 18, 0, 0).getTime();
assertEquals("2001-05-18 18:00:00 GMT", ConcurrentVersionsSystem.formatCVSDate(mayEighteenSixPM2001));
}
public void testFormatCVSDateGMTPlusTen() {
TimeZone.setDefault(TimeZone.getTimeZone("GMT+10:00"));
Date mayEighteenSixPM2001 = new GregorianCalendar(2001, 4, 18, 18, 0, 0).getTime();
assertEquals("2001-05-18 08:00:00 GMT", ConcurrentVersionsSystem.formatCVSDate(mayEighteenSixPM2001));
Date may18EightAM2001 = new GregorianCalendar(2001, 4, 18, 8, 0, 0).getTime();
assertEquals("2001-05-17 22:00:00 GMT", ConcurrentVersionsSystem.formatCVSDate(may18EightAM2001));
}
public void testFormatCVSDateGMTMinusTen() {
TimeZone.setDefault(TimeZone.getTimeZone("GMT-10:00"));
Date may18SixPM2001 = new GregorianCalendar(2001, 4, 18, 18, 0, 0).getTime();
assertEquals("2001-05-19 04:00:00 GMT", ConcurrentVersionsSystem.formatCVSDate(may18SixPM2001));
Date may18EightAM2001 = new GregorianCalendar(2001, 4, 18, 8, 0, 0).getTime();
assertEquals("2001-05-18 18:00:00 GMT", ConcurrentVersionsSystem.formatCVSDate(may18EightAM2001));
}
public void testAddAliasToMap() {
ConcurrentVersionsSystem cvs = new ConcurrentVersionsSystem();
final Hashtable<String, String> aliasMap = new Hashtable<String, String>();
cvs.setMailAliases(aliasMap);
String userline = "roberto:'Roberto DaMana <damana@cs.unipr.it>'";
cvs.addAliasToMap(userline);
userline = "hill:hill@cs.unipr.it";
cvs.addAliasToMap(userline);
userline = "zolo:zolo";
cvs.addAliasToMap(userline);
assertEquals("'Roberto DaMana <damana@cs.unipr.it>'", aliasMap.get("roberto"));
assertEquals("hill@cs.unipr.it", aliasMap.get("hill"));
assertEquals("zolo", aliasMap.get("zolo"));
userline = "me";
cvs.addAliasToMap(userline);
assertNull(aliasMap.get("me"));
}
public void testGetCvsServerVersionDifferingClientServerVersions() throws IOException {
String logName = "cvslog1-1xversion.txt";
final BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("differing client & server version", getOfficialCVSVersion("1.11.16"), cvs.getCvsServerVersion());
assertEquals("differing client & server version", false, cvs.isCvsNewOutputFormat());
input.close();
}
public void testGetCvsServerVersionIdenticalClientServerVersions1() throws IOException {
String logName = "cvslog1-11version.txt";
final BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("identical client & server version 1.11.16", getOfficialCVSVersion("1.11.16"), cvs
.getCvsServerVersion());
assertEquals("old output format", false, cvs.isCvsNewOutputFormat());
input.close();
}
public void testGetCvsServerVersionIdenticalClientServerVersions2() throws IOException {
String logName = "cvslog1-12version.txt";
final BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("identical client & server version 1.12.9", getOfficialCVSVersion("1.12.9"), cvs
.getCvsServerVersion());
assertEquals("new output format", true, cvs.isCvsNewOutputFormat());
input.close();
}
public void testGetCvsNTServerVersionDifferingClientServerVersions() throws IOException {
String logName = "cvsntlog2-0xversion.txt";
final BufferedInputStream input = new BufferedInputStream(loadTestLog(logName));
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("differing client & server version", new ConcurrentVersionsSystem.Version("CVSNT", "2.0.14"),
cvs.getCvsServerVersion());
assertEquals("differing client & server version", false, cvs.isCvsNewOutputFormat());
input.close();
}
public void testIsCVSNewVersion() {
Object[] array = new Object[] { new SpecificVersionCVS(getOfficialCVSVersion("1.11.16")), Boolean.FALSE,
new SpecificVersionCVS(getOfficialCVSVersion("1.12.8")), Boolean.FALSE,
new SpecificVersionCVS(getOfficialCVSVersion("1.12.9")), Boolean.TRUE,
new SpecificVersionCVS(getOfficialCVSVersion("1.12.81")), Boolean.TRUE,
new SpecificVersionCVS(new ConcurrentVersionsSystem.Version("cvsnt", "2.0.14")), Boolean.FALSE };
for (int i = 0; i < array.length; i += 2) {
SpecificVersionCVS cvs = (SpecificVersionCVS) array[i];
Boolean b = (Boolean) array[i + 1];
assertEquals("output format " + cvs.getCvsServerVersion() + " is new?", b.booleanValue(), cvs
.isCvsNewOutputFormat());
}
}
/**
* on 1.10 version, "version" argument doesn't exist hence the output is empty.
* @throws IOException if something fails
*/
public void testGetCvsServerVersion1_10version() throws IOException {
String logContent = "";
final InputStream input = new ByteArrayInputStream(logContent.getBytes());
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("assuming default cvs version upon empty output",
ConcurrentVersionsSystem.DEFAULT_CVS_SERVER_VERSION, cvs.getCvsServerVersion());
assertEquals("assuming old format upon empty output", false, cvs.isCvsNewOutputFormat());
input.close();
}
/**
* What if the output is broken? This can happen for various reasons. It is simulated here by truncating the output.
* @throws IOException if something fails
*/
public void testGetCvsServerVersion_brokenOutput() throws IOException {
String logContent = "Server: Concurrent Versions System (CVS) ";
final InputStream input = new ByteArrayInputStream(logContent.getBytes());
final ConcurrentVersionsSystem cvs = new InputBasedCommandLineMockCVS(input, CVS_VERSION_COMMANDLINE, null);
assertEquals("assuming default cvs version upon broken output",
ConcurrentVersionsSystem.DEFAULT_CVS_SERVER_VERSION, cvs.getCvsServerVersion());
assertEquals("assuming old format upon broken output", false, cvs.isCvsNewOutputFormat());
input.close();
}
public void testUseHead() {
ConcurrentVersionsSystem cvs = new ConcurrentVersionsSystem();
assertTrue(cvs.useHead());
cvs.setTag("");
assertTrue(cvs.useHead());
cvs.setTag(null);
assertTrue(cvs.useHead());
cvs.setTag("HEAD");
assertTrue(cvs.useHead());
cvs.setTag("tagName");
assertFalse(cvs.useHead());
}
public void testCompressionValidation() {
ConcurrentVersionsSystem cvs = new ConcurrentVersionsSystem();
cvs.setCvsRoot("bar");
cvs.setModule("foo");
assertCompressionLevelInvalid("A", cvs);
assertCompressionLevelInvalid("-1", cvs);
assertCompressionLevelInvalid("1.1", cvs);
assertCompressionLevelInvalid("10", cvs);
assertCompressionLevelInvalid("", cvs);
assertCompressionLevelInvalid(" ", cvs);
assertCompressionLevelInvalid("\n\n\t\r", cvs);
assertCompressionLevelValid("1", cvs);
assertCompressionLevelValid("2", cvs);
assertCompressionLevelValid("3", cvs);
assertCompressionLevelValid("4", cvs);
assertCompressionLevelValid("5", cvs);
assertCompressionLevelValid("6", cvs);
assertCompressionLevelValid("7", cvs);
assertCompressionLevelValid("8", cvs);
assertCompressionLevelValid("9", cvs);
assertCompressionLevelValid(null, cvs);
}
public void testShouldRecurseToFindCvsDirectories() throws Exception {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File rootDir = new File(tmpDir, "testShouldRecurseToFindCvsDirectories");
filesToDelete.add(rootDir);
File subDir = new File(rootDir, "subDir");
filesToDelete.add(subDir);
File subSubDir = new File(subDir, "subSubDir");
filesToDelete.add(subSubDir);
File cvsDir = new File(subSubDir, "CVS");
filesToDelete.add(cvsDir);
assertTrue(cvsDir.mkdirs());
final Modification mod = new Modification();
ConcurrentVersionsSystem cvs = new ConcurrentVersionsSystem() {
@Override
List<Modification> execHistoryCommand(Commandline command) throws Exception {
final List<Modification> mods = new ArrayList<Modification>();
mods.add(mod);
return mods;
}
};
cvs.setLocalWorkingCopy(rootDir.getAbsolutePath());
cvs.setRecurseLocalWorkingCopy(true);
cvs.setSkipEmailsFetching(true);
List modifications = cvs.getModifications(new Date(), new Date());
assertEquals(1, modifications.size());
}
private void assertCompressionLevelValid(String candidate, ConcurrentVersionsSystem cvs) {
cvs.setCompression(candidate);
try {
cvs.validate();
} catch (CruiseControlException e) {
e.printStackTrace();
fail("validate() should NOT throw exception on '" + candidate + "' compression value.");
}
}
private void assertCompressionLevelInvalid(String candidate, ConcurrentVersionsSystem cvs) {
cvs.setCompression(candidate);
try {
cvs.validate();
fail("validate() should throw exception on '" + candidate + "' compression value.");
} catch (CruiseControlException e) {
// expected
}
}
private InputStream loadTestLog(String name) {
InputStream testStream = getClass().getResourceAsStream(name);
assertNotNull("failed to load resource " + name + " in class " + getClass().getName(), testStream);
return testStream;
}
private Date parseLogDateFormat(String dateString) throws ParseException {
return new SimpleDateFormat(ConcurrentVersionsSystem.LOG_DATE_FORMAT).parse(dateString);
}
private static class SpecificVersionCVS extends ConcurrentVersionsSystem {
private final Version vers;
public SpecificVersionCVS(Version cvsVersion) {
this.vers = cvsVersion;
}
protected Version getCvsServerVersion() {
return vers;
}
}
private ConcurrentVersionsSystem.Version getOfficialCVSVersion(final String cvsVersion) {
return new ConcurrentVersionsSystem.Version(ConcurrentVersionsSystem.OFFICIAL_CVS_NAME, cvsVersion);
}
/**
* Overrides the getCommandLine() method by returnning a MockCommandLine whose process input stream will read its
* contents from the specific input stream.
*/
private static class InputBasedCommandLineMockCVS extends ConcurrentVersionsSystem {
private final InputStream inputStream;
private final String[] expectedCommandline;
private final String expectedWorkingDirectory;
public InputBasedCommandLineMockCVS(final InputStream inputStream, final String[] expectedCommandLine,
final String expectedWorkingDirectory) {
this.inputStream = inputStream;
expectedCommandline = expectedCommandLine;
this.expectedWorkingDirectory = expectedWorkingDirectory;
}
// factory method for mock...
protected Commandline getCommandline() {
final MockCommandline mockCommandline = new MockCommandline();
mockCommandline.setExpectedCommandline(expectedCommandline);
mockCommandline.setExpectedWorkingDirectory(expectedWorkingDirectory);
mockCommandline.setProcessErrorStream(new PipedInputStream());
mockCommandline.setProcessInputStream(inputStream);
mockCommandline.setProcessOutputStream(new PipedOutputStream());
return mockCommandline;
}
}
}