How to randomize the ports in greenmail for CI Server

970 views Asked by At

Using JUnit & Greenmail I want to achieve a random port used by greenmail rather than the default ports or the ports with offset. To do so I tried to get a random port with ServerSocket(0) and the start of greenmail works as designed. But when I try to send a mail during the test, I get an exception "Couldn't connect to port 3025" which is the greenmail default.

package de.itout.test.tdd.tdd.mocking;

import com.icegreen.greenmail.configuration.*;
import com.icegreen.greenmail.junit.*;
import com.icegreen.greenmail.user.*;
import com.icegreen.greenmail.util.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import org.junit.*;
import static org.junit.Assert.*;

public class MailTest
{

  GreenMail greenMailSMTPIMAP;

  public MailTest()
  {
  }

  @Before
  public void setUp() throws IOException
  {
    ServerSocket ssSMTP = new ServerSocket(0);
    ServerSocket ssIMAP = new ServerSocket(0);
    int randomPortSMTP = ssSMTP.getLocalPort();
    int randomPortIMAP = ssIMAP.getLocalPort();
    ssSMTP.close();
    ssIMAP.close();
    ServerSetup smtpSetup = new ServerSetup(randomPortSMTP, null, ServerSetup.PROTOCOL_SMTP);
    ServerSetup imapSetup = new ServerSetup(randomPortIMAP, null, ServerSetup.PROTOCOL_IMAP);
    greenMailSMTPIMAP = new GreenMail(new ServerSetup[]{smtpSetup,imapSetup});
    greenMailSMTPIMAP.start();
  }

  @After
  public void tearDown()
  {
    greenMailSMTPIMAP.stop();
  }

  @Test
  public void testSend() throws MessagingException
  {
    GreenMailUtil.sendTextEmailTest("[email protected]", "[email protected]",
      "some subject", "some body"); // --- Place your sending code here instead
    assertEquals("some body", GreenMailUtil.getBody(greenMailSMTPIMAP.getReceivedMessages()[0]));
  }

  @Test
  public void testReceive() throws MessagingException
  {
    GreenMailUser user = greenMailSMTPIMAP.setUser("[email protected]", "login-id", "password");
    user.deliver(createMimeMessage()); // You can either create a more complex message...
    GreenMailUtil.sendTextEmailTest("[email protected]", "[email protected]",
      "subject", "body"); // ...or use the default messages

    assertEquals(2, greenMailSMTPIMAP.getReceivedMessages().length); // // --- Place your POP3 or IMAP retrieve code here
  }

  private MimeMessage createMimeMessage()
  {
    return GreenMailUtil.createTextEmail("[email protected]", "[email protected]", "subject", "body", greenMailSMTPIMAP.getImap().getServerSetup());
  }
}
Running de.itout.test.tdd.tdd.mocking.MailTest
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 35.866 sec <<< FAILURE!
testSend(de.itout.test.tdd.tdd.mocking.MailTest)  Time elapsed: 35.725 sec  <<< ERROR!
java.lang.IllegalStateException: Can not send message javax.mail.internet.MimeMessage@4de5031f
    at com.icegreen.greenmail.util.GreenMailUtil.sendMimeMessage(GreenMailUtil.java:275)
    at com.icegreen.greenmail.util.GreenMailUtil.sendTextEmail(GreenMailUtil.java:263)
    at com.icegreen.greenmail.util.GreenMailUtil.sendTextEmailTest(GreenMailUtil.java:206)
    at de.itout.test.tdd.tdd.mocking.MailTest.testSend(MailTest.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:242)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:137)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: 127.0.0.1, 3025; timeout 15000;
  nested exception is:
    java.net.ConnectException: Connection refused: connect
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2118)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:712)
    at javax.mail.Service.connect(Service.java:366)
    at javax.mail.Service.connect(Service.java:246)
    at javax.mail.Service.connect(Service.java:195)
    at javax.mail.Transport.send0(Transport.java:254)
    at javax.mail.Transport.send(Transport.java:124)
    at com.icegreen.greenmail.util.GreenMailUtil.sendMimeMessage(GreenMailUtil.java:273)
    ... 34 more
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:329)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2084)
    ... 41 more

1

There are 1 answers

0
Stefan Höltker On

Simply pass the Server Setup to the methods GreenMailUtil.sendTextEmail(...,ServerSetup) And dont use the standard *Test Methods.

  @Test
  public void testSend() throws MessagingException
  {
    GreenMailUtil.sendTextEmail("[email protected]", "[email protected]",
      "some subject", "some body", greenMail.getSmtp().getServerSetup()); // --- Place your sending code here instead
    assertEquals("some body", GreenMailUtil.getBody(greenMail.getReceivedMessages()[0]));
  }