/******************************************************************************** * CruiseControl, a Continuous Integration Toolkit * Copyright (c) 2001-2003, 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.publishers; import java.io.File; import java.io.FileOutputStream; import java.io.StringReader; import java.net.InetAddress; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import junit.framework.TestCase; import net.sourceforge.cruisecontrol.CruiseControlException; import net.sourceforge.cruisecontrol.Modification; import net.sourceforge.cruisecontrol.PluginXMLHelper; import net.sourceforge.cruisecontrol.ProjectXMLHelper; import net.sourceforge.cruisecontrol.ResolverHolder; import net.sourceforge.cruisecontrol.publishers.EmailPublisher.Alert; import net.sourceforge.cruisecontrol.publishers.EmailPublisher.Always; import net.sourceforge.cruisecontrol.publishers.EmailPublisher.Ignore; import net.sourceforge.cruisecontrol.publishers.email.DropLetterEmailAddressMapper; import net.sourceforge.cruisecontrol.publishers.email.PropertiesMapper; import net.sourceforge.cruisecontrol.testutil.TestUtil; import net.sourceforge.cruisecontrol.util.XMLLogHelper; import org.jdom.Element; import org.jdom.input.SAXBuilder; public class EmailPublisherTest extends TestCase { private XMLLogHelper successLogHelper; private XMLLogHelper fixedLogHelper; private XMLLogHelper failureLogHelper; private XMLLogHelper firstFailureLogHelper; private EmailPublisher emailPublisher; private EmailPublisher noAlertsEmailPublisher; private File tmpFile; protected XMLLogHelper createLogHelper(boolean success, boolean lastBuildSuccess) { Element cruisecontrolElement = TestUtil.createElement(success, lastBuildSuccess, "2 minutes 20 seconds", 5, null); return new XMLLogHelper(cruisecontrolElement); } public void setUp() throws Exception { PropertiesMapper propertiesMapper = new PropertiesMapper(); // create a temp file to test propertiesmapper Properties props = new Properties(); tmpFile = File.createTempFile("cruise", "Test"); tmpFile.deleteOnExit(); props.setProperty("always1", "always1"); final FileOutputStream fos = new FileOutputStream(tmpFile); try { props.store(fos, null); } finally { fos.close(); } String xml = generateXML(true); emailPublisher = initPublisher(propertiesMapper, xml); emailPublisher.setMailHost("mailhost"); emailPublisher.setReturnAddress("returnaddress"); xml = generateXML(false); noAlertsEmailPublisher = initPublisher(propertiesMapper, xml); successLogHelper = createLogHelper(true, true); failureLogHelper = createLogHelper(false, false); fixedLogHelper = createLogHelper(true, false); firstFailureLogHelper = createLogHelper(false, true); } protected EmailPublisher initPublisher(PropertiesMapper propMapper, String xml) throws Exception { SAXBuilder builder = new SAXBuilder("org.apache.xerces.parsers.SAXParser"); Element emailPublisherElement = builder.build(new StringReader(xml)).getRootElement(); PluginXMLHelper xmlHelper = new PluginXMLHelper(new ProjectXMLHelper(new ResolverHolder.DummeResolvers())); EmailPublisher ePublisher = (MockEmailPublisher) xmlHelper.configure( emailPublisherElement, Class.forName("net.sourceforge.cruisecontrol.publishers.MockEmailPublisher"), false); ePublisher.add(new DropLetterEmailAddressMapper()); propMapper.setFile(tmpFile.getPath()); ePublisher.add(propMapper); return ePublisher; } protected String generateXML(final boolean includeAlerts) { final StringBuilder xml = new StringBuilder(); xml.append("<email defaultsuffix='@host.com'>"); xml.append("<always address='always1'/>"); xml.append("<always address='always1@host.com'/>"); xml.append("<always address='always2@host.com'/>"); xml.append("<always address='dropletteruser1'/>"); xml.append("<failure address='failure1'/>"); xml.append("<failure address='failure2@host.com' reportWhenFixed='true'/>"); xml.append("<success address='success1' />"); xml.append("<success address='success2@host.com' />"); xml.append("<map alias='user3' address='user3@host2.com'/>"); xml.append("<ignore user='user4'/>"); if (includeAlerts) { //xml.append("<alert file='.*' address='anyFileMod@host.com' />"); xml.append("<alert fileRegExpr='filename1' address='filename1@host.com' />"); xml.append("<alert fileRegExpr='basedir/subdirectory2/.*' address='subdir2@host.com' />"); xml.append("<alert fileRegExpr='basedir/subdirectory3/filename3' address='filename3@host.com' />"); xml.append("<alert fileRegExpr='basedir/subdirectory5/.*' address='basedirSubdirectory5@host.com' />"); xml.append("<alert fileRegExpr='' address='empty' />"); } xml.append("</email>"); return xml.toString(); } public void testValidate() throws CruiseControlException { EmailPublisher publisher = new MockEmailPublisher(); try { publisher.validate(); fail("EmailPublisher should throw exceptions when required fields are not set."); } catch (CruiseControlException e) { } publisher.setReturnAddress("returnaddress"); publisher.validate(); } public void testEmailValidator() { assertTrue(emailPublisher.isValid("jerome@coffeebreaks.org")); assertFalse(emailPublisher.isValid("jerome@coffeebreaks.")); assertTrue(emailPublisher.isValid("\"email with space\"@test.com")); assertTrue(emailPublisher.isValid("emailWith$Sign@test.com")); } public void testValidateAlwaysAddresses() throws CruiseControlException { Always always = emailPublisher.createAlways(); try { emailPublisher.validate(); fail("unconfigured always elements should fail validation"); } catch (CruiseControlException expected) { } always.setAddress(""); try { emailPublisher.validate(); fail("empty string should not be a valid address"); } catch (CruiseControlException expected) { } always.setAddress("address"); emailPublisher.validate(); } public void testValidateAlerts() throws CruiseControlException { Alert alert = emailPublisher.createAlert(); try { emailPublisher.validate(); fail("unconfigured alert elements should fail validation"); } catch (CruiseControlException expected) { } alert.setFileRegExpr("regex"); try { emailPublisher.validate(); fail("alert elements without addresses should fail validation"); } catch (CruiseControlException expected) { } alert.setAddress("address"); emailPublisher.validate(); alert = emailPublisher.createAlert(); alert.setAddress("address"); try { emailPublisher.validate(); fail("alert elements without file regex should fail validation"); } catch (CruiseControlException expected) { } } public void testValidateIgnore() throws CruiseControlException { Ignore ignore = emailPublisher.createIgnore(); try { emailPublisher.validate(); fail("unconfigured ignore elements should fail validation"); } catch (CruiseControlException expected) { } ignore.setUser("user"); emailPublisher.validate(); } public void testShouldSend() throws Exception { //build not necessary, spam while broken=true emailPublisher.setSpamWhileBroken(true); emailPublisher.setReportSuccess("success"); assertEquals(true, emailPublisher.shouldSend(successLogHelper)); assertEquals(true, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(true, emailPublisher.shouldSend(failureLogHelper)); emailPublisher.setReportSuccess("fixes"); assertEquals(false, emailPublisher.shouldSend(successLogHelper)); assertEquals(true, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(true, emailPublisher.shouldSend(failureLogHelper)); emailPublisher.setReportSuccess("never"); assertEquals(false, emailPublisher.shouldSend(successLogHelper)); assertEquals(false, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(true, emailPublisher.shouldSend(failureLogHelper)); emailPublisher.setSpamWhileBroken(false); emailPublisher.setReportSuccess("success"); assertEquals(true, emailPublisher.shouldSend(successLogHelper)); assertEquals(true, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(false, emailPublisher.shouldSend(failureLogHelper)); assertEquals(true, emailPublisher.shouldSend(firstFailureLogHelper)); emailPublisher.setReportSuccess("fixes"); assertEquals(false, emailPublisher.shouldSend(successLogHelper)); assertEquals(true, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(false, emailPublisher.shouldSend(failureLogHelper)); assertEquals(true, emailPublisher.shouldSend(firstFailureLogHelper)); emailPublisher.setReportSuccess("never"); assertEquals(false, emailPublisher.shouldSend(successLogHelper)); assertEquals(false, emailPublisher.shouldSend(fixedLogHelper)); assertEquals(false, emailPublisher.shouldSend(failureLogHelper)); assertEquals(true, emailPublisher.shouldSend(firstFailureLogHelper)); } public void testCreateSubject() throws Exception { emailPublisher.setReportSuccess("always"); assertEquals( "someproject somelabel Build Successful", emailPublisher.createSubject(successLogHelper)); emailPublisher.setReportSuccess("fixes"); assertEquals( "someproject somelabel Build Fixed", emailPublisher.createSubject(fixedLogHelper)); assertEquals("someproject somelabel Build Failed", emailPublisher.createSubject(failureLogHelper)); emailPublisher.setSubjectPrefix("[CC]"); emailPublisher.setReportSuccess("always"); assertEquals( "[CC] someproject somelabel Build Successful", emailPublisher.createSubject(successLogHelper)); emailPublisher.setReportSuccess("fixes"); assertEquals( "[CC] someproject somelabel Build Fixed", emailPublisher.createSubject(fixedLogHelper)); assertEquals( "[CC] someproject somelabel Build Failed", emailPublisher.createSubject(failureLogHelper)); //Anytime it is a "fixed" build, the subject should read "fixed". emailPublisher.setReportSuccess("always"); assertEquals( "[CC] someproject somelabel Build Fixed", emailPublisher.createSubject(fixedLogHelper)); emailPublisher.setReportSuccess("failures"); assertEquals( "[CC] someproject somelabel Build Fixed", emailPublisher.createSubject(fixedLogHelper)); } public void testCreateUserList() throws Exception { assertEquals( "always1@host.com,always2@host.com,ropletteruser1@host.com," + "success1@host.com,success2@host.com," + "user1@host.com,user2@host.com,user3@host2.com", emailPublisher.createUserList(successLogHelper)); assertEquals( "always1@host.com,always2@host.com,failure1@host.com," + "failure2@host.com,ropletteruser1@host.com,user1@host.com,user2@host.com,user3@host2.com", emailPublisher.createUserList(failureLogHelper)); assertEquals( "always1@host.com,always2@host.com," + "failure2@host.com,ropletteruser1@host.com," + "success1@host.com,success2@host.com," + "user1@host.com,user2@host.com,user3@host2.com", emailPublisher.createUserList(fixedLogHelper)); emailPublisher.setSkipUsers(true); assertEquals( "always1@host.com,always2@host.com,ropletteruser1@host.com,success1@host.com,success2@host.com", emailPublisher.createUserList(successLogHelper)); assertEquals( "always1@host.com,always2@host.com,failure1@host.com,failure2@host.com,ropletteruser1@host.com", emailPublisher.createUserList(failureLogHelper)); emailPublisher.setSkipUsers(false); assertEquals( "always1@host.com,always2@host.com,failure2@host.com," + "ropletteruser1@host.com,success1@host.com,success2@host.com," + "user1@host.com,user2@host.com,user3@host2.com", emailPublisher.createUserList(fixedLogHelper)); } public void testGetFromAddress() throws AddressException { String returnAddress = "me@you.com"; String returnName = "Me you Me"; emailPublisher.setReturnAddress(returnAddress); emailPublisher.setReturnName(returnName); InternetAddress fromAddress = emailPublisher.getFromAddress(); assertEquals(returnAddress, fromAddress.getAddress()); assertEquals(returnName, fromAddress.getPersonal()); } public void testSendMail() throws Exception { assertFalse(emailPublisher.sendMail(null, "subject", "message", false)); assertFalse(emailPublisher.sendMail(" ", "subject", "message", false)); } public void testCreateUserSet() throws Exception { emailPublisher.setReportSuccess("success"); Set userSet = emailPublisher.createUserSet(successLogHelper); assertNotNull(userSet); assertTrue(userSet.contains("always1")); assertTrue(userSet.contains("always2@host.com")); assertTrue(userSet.contains("ropletteruser1")); assertTrue(userSet.contains("success1")); assertTrue(userSet.contains("user1")); assertTrue(userSet.contains("user2")); assertTrue(userSet.contains("user3@host2.com")); } /** * The following unit test ensures TestUtil.createModsElement * creates a full XMLLogHelper object * * @throws Exception if a failure occurs */ public void testCreateModsElement() throws Exception { final Set<Modification> modSet = successLogHelper.getModifications(); for (final Modification mod : modSet) { assertNotNull("getFileName should not return null", mod.getFileName()); assertNotNull("getFullPath should not return null", mod.getFullPath()); if ("filename1".equalsIgnoreCase(mod.getFileName())) { assertNull(mod.getFolderName()); } } } public void testCreateAlertUserSet() throws Exception { emailPublisher.validate(); Set<String> alertUsers = emailPublisher.createAlertUserSet(successLogHelper); //assertTrue(alertUsers.contains("anyFileMod@host.com")); assertTrue(alertUsers.contains("filename1@host.com")); assertTrue(alertUsers.contains("filename3@host.com")); assertFalse(alertUsers.contains("")); // assertTrue(alertUsers.contains("subdir2@host.com")); // assertEquals(3, alertUsers.size()); assertEquals(2, alertUsers.size()); alertUsers = noAlertsEmailPublisher.createAlertUserSet(failureLogHelper); assertEquals(0, alertUsers.size()); } public void testCreateEmailString() { final Set<String> emailSet = new TreeSet<String>(); emailSet.add("always1@host.com"); emailSet.add("always2@host.com"); emailSet.add("always1@host.com"); emailSet.add("always3@host.com"); assertEquals("always1@host.com,always2@host.com,always3@host.com", emailPublisher.createEmailString(emailSet)); } public void testBuildResultsURLShouldDefaultToTheDashboardAppRunningOnTheSameServer() throws Exception { final InetAddress localhost = InetAddress.getLocalHost(); System.setProperty("cc.webport", "123456789"); final String expectedBuildResultsURL = "http://" + localhost.getCanonicalHostName() + ":123456789/dashboard"; final EmailPublisher defaultPublisher = new EmailPublisher() { @Override protected String createMessage(final XMLLogHelper logHelper) { return ""; } }; assertEquals(expectedBuildResultsURL, defaultPublisher.getBuildResultsURL()); } public void testDefaultBuildResultsURLShouldNotIncludeExplicitPortWhenWebPortPropertyIsNotSet() throws Exception { final InetAddress localhost = InetAddress.getLocalHost(); System.getProperties().remove("cc.webport"); final String expectedBuildResultsURL = "http://" + localhost.getCanonicalHostName() + "/dashboard"; final EmailPublisher defaultPublisher = new EmailPublisher() { @Override protected String createMessage(final XMLLogHelper logHelper) { return ""; } }; assertEquals(expectedBuildResultsURL, defaultPublisher.getBuildResultsURL()); } public void testBuildResultsURLShouldNotDefaultWhenExplicitlySet() throws Exception { final EmailPublisher publisher = new EmailPublisher() { @Override protected String createMessage(final XMLLogHelper logHelper) { return ""; } }; publisher.setBuildResultsURL("http://cruise/cruisecontrol"); assertEquals("http://cruise/cruisecontrol", publisher.getBuildResultsURL()); } }