/******************************************************************************** * CruiseControl, a Continuous Integration Toolkit * Copyright (c) 2007, 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 junit.framework.TestCase; import net.sourceforge.cruisecontrol.CruiseControlException; import net.sourceforge.cruisecontrol.Modification; import org.jdom.JDOMException; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.TimeZone; /** * @see <a href="http://smalltalk.cincom.com/">smalltalk.cincom.com</a> * @author <a href="rcoulman@gmail.com">Randy Coulman</a> */ public class StoreTest extends TestCase { private Store store; private TimeZone originalTimeZone; protected void setUp() throws Exception { store = new Store(); originalTimeZone = TimeZone.getDefault(); } protected void tearDown() throws Exception { TimeZone.setDefault(originalTimeZone); } public void testValidate() throws IOException { try { store.validate(); fail("should throw an exception when no attributes are set"); } catch (CruiseControlException e) { // expected } store.setWorkingDirectory("."); store.setProfile("local"); store.setPackages("PackageA,PackageB"); store.setScript("notThere"); try { store.validate(); fail("should throw an exception when an invalid 'script' attribute is set"); } catch (CruiseControlException e) { // expected } File tempFile = File.createTempFile("temp", "sh"); tempFile.deleteOnExit(); store.setScript(tempFile.getAbsolutePath()); try { store.validate(); } catch (CruiseControlException e) { fail( "should not throw an exception when a valid 'script' " + "attribute is set"); } store.setWorkingDirectory("notthere"); try { store.validate(); fail("should throw an exception when an invalid 'workingDirectory' attribute is set"); } catch (CruiseControlException e) { // expected } store.setProfile(null); try { store.validate(); fail("should throw an exception when no profile is set"); } catch (CruiseControlException e) { // expected } store = new Store(); store.setScript(tempFile.getAbsolutePath()); store.setProfile("local"); try { store.validate(); fail("should throw an exception when no packages are set"); } catch (CruiseControlException e) { // expected } store.setPackages(""); try { store.validate(); fail("should throw an exception when an empty package list is set"); } catch (CruiseControlException e) { // expected } } public void testBuildHistoryCommand() throws CruiseControlException { store.setScript("store"); store.setProfile("local"); store.setPackages("PackageA,Package B,Package C"); Date checkTime = new Date(); long tenMinutes = 10 * 60 * 1000; Date lastBuild = new Date(checkTime.getTime() - tenMinutes); String[] expectedCmd = new String[] { "store", "-profile", "local", "-packages", "PackageA", "Package B", "Package C", "-lastBuild", Store.formatDate(lastBuild), "-now", Store.formatDate(checkTime), "-check" }; String[] actualCmd = store.buildCommand(lastBuild, checkTime).getCommandline(); assertArraysEquals(expectedCmd, actualCmd); store.setVersionRegex("7.5 [0-9]+"); expectedCmd = new String[] { "store", "-profile", "local", "-packages", "PackageA", "Package B", "Package C", "-versionRegex", "7.5 [0-9]+", "-lastBuild", Store.formatDate(lastBuild), "-now", Store.formatDate(checkTime), "-check" }; actualCmd = store.buildCommand(lastBuild, checkTime).getCommandline(); assertArraysEquals(expectedCmd, actualCmd); store.setMinimumBlessingLevel("Work In Progress"); expectedCmd = new String[] { "store", "-profile", "local", "-packages", "PackageA", "Package B", "Package C", "-versionRegex", "7.5 [0-9]+", "-blessedAtLeast", "Work In Progress", "-lastBuild", Store.formatDate(lastBuild), "-now", Store.formatDate(checkTime), "-check" }; actualCmd = store.buildCommand(lastBuild, checkTime).getCommandline(); assertArraysEquals(expectedCmd, actualCmd); store.setParcelBuilderFile("/path/to/parcelsToBuild"); expectedCmd = new String[] { "store", "-profile", "local", "-packages", "PackageA", "Package B", "Package C", "-versionRegex", "7.5 [0-9]+", "-blessedAtLeast", "Work In Progress", "-lastBuild", Store.formatDate(lastBuild), "-now", Store.formatDate(checkTime), "-parcelBuilderFile", "/path/to/parcelsToBuild", "-check" }; actualCmd = store.buildCommand(lastBuild, checkTime).getCommandline(); assertArraysEquals(expectedCmd, actualCmd); } public void testParseModifications() throws JDOMException, ParseException, IOException { String log = "<?xml version=\"1.0\"?>\n" + "<log>\n" + " <package action=\"modified\" name=\"PackageA\" version=\"44\">\n" + " <blessing timestamp=\"04/27/2007 15:05:52.000\" user=\"fred\">blah</blessing>\n" + " </package>\n" + " <package action=\"modified\" name=\"PackageA\" version=\"43\">\n" + " <blessing timestamp=\"04/27/2007 5:58:47.000\" user=\"fred\">" + "Replicated by: fred from: psql_public_cst to: local</blessing>\n" + " <blessing timestamp=\"03/27/2007 5:05:52.000\" user=\"barney\">did something</blessing>\n" + " </package>\n" + " <package action=\"added\" name=\"PackageB\" version=\"7.5 1\">\n" + " <blessing timestamp=\"04/26/2007 17:16:23.000\" user=\"wilma\">initial</blessing>\n" + " </package>\n" + "</log>"; List modifications = Store.StoreLogXMLParser.parse(new StringReader(log)); assertEquals(4, modifications.size()); Modification modification = createModification( Store.getDateFormatter().parse("04/27/2007 15:05:52.000"), "fred", "blah", "44", "PackageA", "modified"); assertEquals(modification, modifications.get(0)); modification = createModification( Store.getDateFormatter().parse("04/27/2007 5:58:47.000"), "fred", "Replicated by: fred from: psql_public_cst to: local", "43", "PackageA", "modified"); assertEquals(modification, modifications.get(1)); modification = createModification( Store.getDateFormatter().parse("03/27/2007 5:05:52.000"), "barney", "did something", "43", "PackageA", "modified"); assertEquals(modification, modifications.get(2)); modification = createModification( Store.getDateFormatter().parse("04/26/2007 17:16:23.000"), "wilma", "initial", "7.5 1", "PackageB", "added"); assertEquals(modification, modifications.get(3)); } public void testParseEmptyModifications() throws JDOMException, ParseException, IOException { String log = "<?xml version=\"1.0\"?>\n " + "<log>\n" + "</log>"; List modifications = Store.StoreLogXMLParser.parse(new StringReader(log)); assertEquals(0, modifications.size()); } public void testFormatDatesForSvnLog() { TimeZone.setDefault(TimeZone.getTimeZone("GMT+10:00")); Date maySeventeenSixPM2001 = new GregorianCalendar(2001, Calendar.MAY, 17, 18, 0, 0).getTime(); assertEquals( "05/17/2001 08:00:00.000", Store.formatDate(maySeventeenSixPM2001)); Date maySeventeenEightAM2001 = new GregorianCalendar(2001, Calendar.MAY, 17, 8, 0, 0).getTime(); assertEquals( "05/16/2001 22:00:00.000", Store.formatDate(maySeventeenEightAM2001)); TimeZone.setDefault(TimeZone.getTimeZone("GMT-10:00")); Date marchTwelfFourPM2003 = new GregorianCalendar(2003, Calendar.MARCH, 12, 16, 0, 0).getTime(); assertEquals( "03/13/2003 02:00:00.000", Store.formatDate(marchTwelfFourPM2003)); Date marchTwelfTenAM2003 = new GregorianCalendar(2003, Calendar.MARCH, 12, 10, 0, 0).getTime(); assertEquals("03/12/2003 20:00:00.000", Store.formatDate(marchTwelfTenAM2003)); } public void testSetProperty() throws ParseException { store.setProperty("hasChanges?"); final List<Modification> noModifications = new ArrayList<Modification>(); store.fillPropertiesIfNeeded(noModifications); assertEquals(null, store.getProperties().get("hasChanges?")); final List<Modification> hasModifications = new ArrayList<Modification>(); hasModifications.add(createModification( Store.getDateFormatter().parse("04/27/2007 15:05:52.000"), "fred", "blah", "44", "PackageA", "modified")); store.fillPropertiesIfNeeded(hasModifications); assertEquals("true", store.getProperties().get("hasChanges?")); } private static Modification createModification( Date date, String user, String comment, String revision, String file, String type) { Modification modification = new Modification("store"); Modification.ModifiedFile modifiedFile = modification.createModifiedFile(file, ""); modifiedFile.action = type; modifiedFile.revision = revision; modification.modifiedTime = date; modification.userName = user; modification.comment = comment; modification.revision = revision; return modification; } private static void assertArraysEquals(Object[] expected, Object[] actual) { assertEquals("array lengths mismatch!", expected.length, actual.length); for (int i = 0; i < expected.length; i++) { assertEquals(expected[i], actual[i]); } } }