001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2001-2003, 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;
037:
038: import java.io.File;
039: import java.io.FilenameFilter;
040: import java.io.IOException;
041: import java.io.StringReader;
042: import java.text.ParseException;
043: import java.util.Calendar;
044: import java.util.Date;
045:
046: import junit.framework.TestCase;
047: import net.sourceforge.cruisecontrol.logmanipulators.DeleteManipulator;
048: import net.sourceforge.cruisecontrol.logmanipulators.GZIPManipulator;
049: import net.sourceforge.cruisecontrol.testutil.TestUtil.FilesToDelete;
050: import net.sourceforge.cruisecontrol.testutil.TestUtil;
051: import net.sourceforge.cruisecontrol.util.DateUtil;
052:
053: import org.jdom.Element;
054: import org.jdom.JDOMException;
055: import org.jdom.input.SAXBuilder;
056: import org.jdom.output.Format;
057: import org.jdom.output.XMLOutputter;
058:
059: public class LogTest extends TestCase {
060: private final FilesToDelete filesToDelete = new FilesToDelete();
061: private static final String LOG_DIR = "target/LogTest";
062:
063: protected void setUp() {
064: filesToDelete.add(new File(TestUtil.getTargetDir(), LOG_DIR));
065: }
066:
067: protected void tearDown() {
068: filesToDelete.delete();
069: }
070:
071: public void testSetProjectNameShouldThrowIAEIfPassedNull() {
072: Log log = new Log();
073: try {
074: log.setProjectName(null);
075: fail();
076: } catch (IllegalArgumentException expected) {
077: assertEquals("projectName can't be null", expected
078: .getMessage());
079: }
080: }
081:
082: public void testValidateShouldFailWhenProjectNameNotSet() {
083: Log log = new Log();
084: try {
085: log.validate();
086: fail();
087: } catch (CruiseControlException expected) {
088: assertEquals("projectName must be set", expected
089: .getMessage());
090: }
091: }
092:
093: public void testDefaultLogLocation() {
094: Log log = new Log();
095: log.setProjectName("foo");
096: assertEquals("logs" + File.separatorChar + "foo", log
097: .getLogDir());
098: }
099:
100: public void testFormatLogFileName() {
101: Calendar augTweleveCalendar = Calendar.getInstance();
102: augTweleveCalendar.set(2004, 7, 12, 1, 1, 1);
103: Date augTweleve = augTweleveCalendar.getTime();
104:
105: String expected = "log20040812010101.xml";
106: String actual = Log.formatLogFileName(augTweleve);
107: assertEquals(expected + "--" + actual, expected, actual);
108: assertEquals("log20040812010101Lbuild.1.xml", Log
109: .formatLogFileName(augTweleve, "build.1"));
110: }
111:
112: public void testWasSuccessfulBuild() {
113: assertTrue(Log
114: .wasSuccessfulBuild("log20040812010101Lbuild.1.xml"));
115: assertFalse(Log.wasSuccessfulBuild("log20040812010101.xml"));
116: assertFalse(Log.wasSuccessfulBuild(null));
117: }
118:
119: public void testParseDateFromLogFileName() throws ParseException {
120: Calendar augTweleveCalendar = Calendar.getInstance();
121: augTweleveCalendar.set(2004, 7, 12, 1, 1, 1);
122: Date augTweleve = augTweleveCalendar.getTime();
123:
124: assertEquals(augTweleve.toString(), Log
125: .parseDateFromLogFileName(
126: "log20040812010101Lbuild.1.xml").toString());
127: assertEquals(augTweleve.toString(), Log
128: .parseDateFromLogFileName("log20040812010101.xml")
129: .toString());
130: }
131:
132: public void testParseLabelFromLogFileName() {
133: assertEquals(
134: "build.1",
135: Log
136: .parseLabelFromLogFileName("log20040812010101Lbuild.1.xml"));
137: assertEquals("", Log
138: .parseLabelFromLogFileName("log20040812010101.xml"));
139: }
140:
141: public void testXMLEncoding() throws CruiseControlException,
142: IOException, JDOMException {
143: String[] encodings = { "UTF-8", "ISO-8859-1", null };
144:
145: SAXBuilder builder = new SAXBuilder(
146: "org.apache.xerces.parsers.SAXParser");
147: XMLOutputter outputter = new XMLOutputter(Format
148: .getPrettyFormat());
149: for (int i = 0; i < encodings.length; i++) {
150: Log log = new Log();
151: log.setProjectName("testXMLEncoding");
152: log.setDir(LOG_DIR);
153: if (encodings[i] != null) {
154: log.setEncoding(encodings[i]);
155: }
156: log.validate();
157:
158: // Add a minimal buildLog
159: log.addContent(getBuildLogInfo());
160: Element build = new Element("build");
161: log.addContent(build);
162: log.addContent(new Element("modifications"));
163:
164: // Add 8-bit characters
165: build
166: .setText("Something with special characters: \u00c6\u00d8\u00c5");
167:
168: Date now = new Date();
169: // Write and read the file
170: log.writeLogFile(now);
171:
172: String expectFilename = "log"
173: + DateUtil.getFormattedTime(now) + "L.xml";
174: File logFile = new File(LOG_DIR, expectFilename);
175: assertTrue(logFile.isFile());
176: filesToDelete.add(logFile);
177:
178: Element actualContent = builder.build(logFile)
179: .getRootElement();
180:
181: // content.toString() only returns the root element but not the
182: // children: [Element: <cruisecontrol/>]
183: // Use an XMLOutputter (that trims whitespace) instead.
184: String expected = outputter.outputString(log.getContent());
185: String actual = outputter.outputString(actualContent);
186: assertEquals(expected, actual);
187: }
188: }
189:
190: public void testManipulateLog() throws Exception {
191: String testProjectName = "testBackupLog";
192:
193: // Test backup of 12 Months
194: Calendar date = Calendar.getInstance();
195: date.set(Calendar.YEAR, date.get(Calendar.YEAR) - 1);
196: date.set(Calendar.MONTH, date.get(Calendar.MONTH) - 13);
197: GZIPManipulator gzip = new GZIPManipulator();
198: gzip.setEvery(12);
199: gzip.setUnit("month");
200: // create old log
201: getWrittenTestLog(testProjectName, LOG_DIR, date.getTime());
202: // create new log
203: Log log = getWrittenTestLog(testProjectName, LOG_DIR,
204: new Date());
205: log.add(gzip);
206: log.validate();
207: assertBackupsHelper(log, 2, 1, 1);
208:
209: // Test Backup of 2 days
210: date = Calendar.getInstance();
211: date.set(Calendar.DAY_OF_MONTH,
212: date.get(Calendar.DAY_OF_MONTH) - 2);
213: gzip = new GZIPManipulator();
214: gzip.setEvery(2);
215: gzip.setUnit("day");
216: log = getWrittenTestLog(testProjectName, LOG_DIR, date
217: .getTime());
218: log.add(gzip);
219: log.validate();
220: assertBackupsHelper(log, 3, 1, 2);
221:
222: // Test delete of logfile
223: date = Calendar.getInstance();
224: date.set(Calendar.DAY_OF_MONTH,
225: date.get(Calendar.DAY_OF_MONTH) - 2);
226: DeleteManipulator deleteManipulator = new DeleteManipulator();
227: deleteManipulator.setEvery(2);
228: deleteManipulator.setUnit("day");
229: log = getWrittenTestLog(testProjectName, LOG_DIR, date
230: .getTime());
231: log.add(deleteManipulator);
232: log.validate();
233: assertBackupsHelper(log, 3, 1, 2);
234:
235: date = Calendar.getInstance();
236: date.set(Calendar.DAY_OF_MONTH,
237: date.get(Calendar.DAY_OF_MONTH) - 2);
238: deleteManipulator = new DeleteManipulator();
239: deleteManipulator.setEvery(2);
240: deleteManipulator.setUnit("day");
241: // This should delete the gz-files too
242: deleteManipulator.setIgnoreSuffix(true);
243: log = getWrittenTestLog(testProjectName, LOG_DIR, date
244: .getTime());
245: log.add(deleteManipulator);
246: log.validate();
247: assertBackupsHelper(log, 1, 1, 0);
248:
249: //Validation Error
250: gzip = new GZIPManipulator();
251: gzip.setUnit("day");
252: log = getWrittenTestLog(testProjectName, LOG_DIR, date
253: .getTime());
254: log.add(gzip);
255: try {
256: log.validate();
257: fail("Validation should fail!");
258: } catch (CruiseControlException e) {
259: assertTrue(true);
260: }
261:
262: }
263:
264: private void assertBackupsHelper(Log log, int expectedLength,
265: int expectedXML, int expectedGZIP) {
266: log.callManipulators();
267: File[] logfiles = new File(log.getLogDir())
268: .listFiles(new FilenameFilter() {
269:
270: public boolean accept(File file, String fileName) {
271: return fileName.startsWith("log20")
272: && (fileName.endsWith(".xml") || fileName
273: .endsWith(".gz"));
274: }
275:
276: });
277: int countGzip = 0;
278: int countXML = 0;
279: for (int i = 0; i < logfiles.length; i++) {
280: File file = logfiles[i];
281: if (file.getName().endsWith(".gz")) {
282: filesToDelete.add(file);
283: countGzip++;
284: } else if (file.getName().endsWith(".xml")) {
285: countXML++;
286: } else {
287: fail("Other log files exists");
288: }
289: }
290: assertEquals(expectedGZIP, countGzip);
291: assertEquals(expectedXML, countXML);
292: assertEquals(expectedLength, logfiles.length);
293: }
294:
295: private Log getWrittenTestLog(String projectName,
296: String testLogDir, Date date)
297: throws CruiseControlException, JDOMException, IOException {
298: Log log;
299: Element build;
300: log = new Log();
301: log.setProjectName(projectName);
302: log.setDir(testLogDir);
303: log.validate();
304: log.addContent(getBuildLogInfo());
305: build = new Element("build");
306: log.addContent(build);
307: log.addContent(new Element("modifications"));
308: log.writeLogFile(date);
309:
310: String expectFilename = "log" + DateUtil.getFormattedTime(date)
311: + "L.xml";
312: File logFile = new File(testLogDir, expectFilename);
313: assertTrue(logFile.isFile());
314: filesToDelete.add(logFile);
315:
316: return log;
317: }
318:
319: // Get a minimal info element for the buildLog
320: private Element getBuildLogInfo() throws JDOMException, IOException {
321: SAXBuilder builder = new SAXBuilder(
322: "org.apache.xerces.parsers.SAXParser");
323: String infoXML = "<info><property name=\"label\" value=\"\"/>"
324: + "<property name=\"lastbuildtime\" value=\"\"/>"
325: + "<property name=\"lastgoodbuildtime\" value=\"\"/>"
326: + "<property name=\"lastbuildsuccessful\" value=\"\"/>"
327: + "<property name=\"buildfile\" value=\"\"/>"
328: + "<property name=\"buildtarget\" value=\"\"/>"
329: + "</info>";
330: Element info = builder.build(new StringReader(infoXML))
331: .getRootElement();
332: return (Element) info.clone();
333: }
334: }
|