1   /*
2    * $Id: AbstractMailConnectorFunctionalTestCase.java 7968 2007-08-21 12:01:57Z holger $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.email;
12  
13  import org.mule.tck.providers.AbstractConnectorTestCase;
14  import org.mule.umo.provider.UMOConnector;
15  
16  import com.icegreen.greenmail.util.Servers;
17  
18  import javax.mail.Message;
19  import javax.mail.internet.MimeMessage;
20  
21  /**
22   * Start a (greenmail) mail server with a known message, for use in subclasses.
23   * Each test gets a new set of ports to avoid conflicts (shouldn't be needed, but
24   * greenmail doesn't seem to be closing ports).  Also contains utility methods
25   * for comparing emails, building endpoints, etc.
26   */
27  public abstract class AbstractMailConnectorFunctionalTestCase extends AbstractConnectorTestCase
28  {
29  
30      // ie must succeed within RETRY_LIMIT attempts
31      public static final int RETRY_LIMIT = 2;
32      public static final String LOCALHOST = "127.0.0.1";
33      public static final String USER = AbstractGreenMailSupport.BOB;
34      public static final String FROM = AbstractGreenMailSupport.BOB_EMAIL;
35      public static final String TO = AbstractGreenMailSupport.ALICE_EMAIL;
36      public static final String PASSWORD = AbstractGreenMailSupport.PASSWORD;
37      
38      private boolean initialEmail = false;
39      private String connectorName;
40      private AbstractGreenMailSupport greenMailSupport = new AutoIncrementGreenMailSupport();
41      private MimeMessage message;
42  
43      protected AbstractMailConnectorFunctionalTestCase(boolean initialEmail, String connectorName)
44      {
45          this.initialEmail = initialEmail;
46          this.connectorName = connectorName;
47      }
48  
49      // @Override
50      protected void doSetUp() throws Exception
51      {
52          super.doSetUp();
53          startServers();
54      }
55  
56      // @Override
57      protected void doTearDown() throws Exception
58      {
59          stopServers();
60          super.doTearDown();
61      }
62  
63      private void storeEmail() throws Exception
64      {
65          greenMailSupport.createBobAndStoreEmail(getValidMessage());
66      }
67  
68      protected void startServers() throws Exception
69      {
70          greenMailSupport.startServers();
71          if (initialEmail)
72          {
73              storeEmail();
74          }
75      }
76  
77      protected void stopServers() throws Exception
78      {
79          greenMailSupport.stopServers();
80      }
81  
82      protected Servers getServers()
83      {
84          return greenMailSupport.getServers();
85      }
86  
87      // @Override
88      public Object getValidMessage() throws Exception
89      {
90          if (null == message)
91          {
92              message = greenMailSupport.getValidMessage(TO);
93          }
94          return message;
95      }
96      
97      public String getConnectorName() 
98      {
99          return connectorName;
100     }
101     
102     public UMOConnector createConnector() throws Exception
103     {
104         return createConnector(true);
105     }
106     
107     public abstract UMOConnector createConnector(boolean init) throws Exception;
108         
109     protected String getPop3TestEndpointURI()
110     {
111         return buildEndpoint("pop3", greenMailSupport.getServers().getPop3().getPort());
112     }
113 
114     protected String getPop3sTestEndpointURI()
115     {
116         return buildEndpoint("pop3s", greenMailSupport.getServers().getPop3s().getPort());
117     }
118 
119     protected String getImapTestEndpointURI()
120     {
121         return buildEndpoint("imap", greenMailSupport.getServers().getImap().getPort());
122     }
123     
124     protected String getImapsTestEndpointURI()
125     {
126         return buildEndpoint("imaps", greenMailSupport.getServers().getImaps().getPort());
127     }
128     
129     protected String getSmtpTestEndpointURI()
130     {
131         return buildEndpoint("smtp", greenMailSupport.getServers().getSmtp().getPort());
132     }
133     
134     protected String getSmtpsTestEndpointURI()
135     {
136         return buildEndpoint("smtps", greenMailSupport.getServers().getSmtps().getPort());
137     }
138     
139    private String buildEndpoint(String protocol, int port) 
140     {
141         return protocol + "://" + USER + ":" + PASSWORD + "@" + LOCALHOST + ":" + port +
142         "?connector=" + connectorName;
143     }
144     
145     protected void assertMessageOk(Object message) throws Exception
146     {
147         assertTrue("Did not receive a MimeMessage", message instanceof MimeMessage);
148         MimeMessage received = (MimeMessage) message;
149         // for some reason, something is adding a newline at the end of messages
150         // so we need to strip that out for comparison
151         assertTrue("Did not receive a message with String contents",
152             received.getContent() instanceof String);
153         String receivedText = ((String) received.getContent()).trim();
154         assertEquals(AbstractGreenMailSupport.MESSAGE, receivedText);
155         assertNotNull(received.getRecipients(Message.RecipientType.TO));
156         assertEquals(1, received.getRecipients(Message.RecipientType.TO).length);
157         assertEquals(received.getRecipients(Message.RecipientType.TO)[0].toString(), TO);
158     }
159 
160     /**
161      * Tests are intermittently failing due to busy ports.  Here we repeat a test a number of times
162      * (more than twice should not be necessary!) to make sure that the first failure was not due to
163      * an active port.
164      *
165      * @param method The method name of the test
166      * @throws Exception If the failure occurs repeatedly
167      */
168     protected void repeatTest(String method) throws Exception
169     {
170         boolean success = false;
171 
172         for (int count = 1; !success; ++count)
173         {
174             try
175             {
176                 getClass().getMethod(method, new Class[0]).invoke(this, new Object[0]);
177                 success = true;
178             }
179             catch (Exception e)
180             {
181                 if (count >= RETRY_LIMIT)
182                 {
183                     logger.warn("Test attempt " + count + " for " + method
184                             + " failed (will fail): " + e.getMessage());
185                     throw e;
186                 }
187                 else
188                 {
189                     logger.warn("Test attempt " + count + " for " + method
190                             + " failed (will retry): " + e.getMessage());
191                     stopServers();
192                     startServers();
193                 }
194             }
195         }
196     }
197 
198 }