If we fail to bind to port 2500 when starting an EmailServer try the next port up.

This change employs the same kind of logic that `HttpClientTest` uses to find an open port for it's server. This should prevent the rare build failures we have seen.

Original commit: elastic/x-pack-elasticsearch@f3b68adad5
This commit is contained in:
Brian Murphy 2015-04-23 15:03:10 -04:00
parent d319fdef1b
commit f39da21905
3 changed files with 50 additions and 15 deletions

View File

@ -5,10 +5,10 @@
*/
package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.watcher.actions.email.service.support.EmailServer;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.actions.email.service.support.EmailServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -35,8 +35,7 @@ public class AccountTests extends ElasticsearchTestCase {
@Before
public void init() throws Exception {
server = new EmailServer("localhost", 2500, USERNAME, PASSWORD);
server.start();
server = EmailServer.localhost("2500-2600", USERNAME, PASSWORD, logger);
}
@After
@ -155,7 +154,7 @@ public class AccountTests extends ElasticsearchTestCase {
public void testSend() throws Exception {
Account account = new Account(new Account.Config("default", ImmutableSettings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", 2500)
.put("smtp.port", server.port())
.put("smtp.user", USERNAME)
.put("smtp.password", PASSWORD)
.build()), logger);
@ -195,7 +194,7 @@ public class AccountTests extends ElasticsearchTestCase {
public void testSend_CC_BCC() throws Exception {
Account account = new Account(new Account.Config("default", ImmutableSettings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", 2500)
.put("smtp.port", server.port())
.put("smtp.user", USERNAME)
.put("smtp.password", PASSWORD)
.build()), logger);
@ -240,7 +239,7 @@ public class AccountTests extends ElasticsearchTestCase {
public void testSend_Authentication() throws Exception {
Account account = new Account(new Account.Config("default", ImmutableSettings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", 2500)
.put("smtp.port", server.port())
.build()), logger);
Email email = Email.builder()

View File

@ -5,6 +5,9 @@
*/
package org.elasticsearch.watcher.actions.email.service.support;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.transport.PortsRange;
import org.elasticsearch.watcher.WatcherException;
import org.subethamail.smtp.TooMuchDataException;
import org.subethamail.smtp.auth.EasyAuthenticationHandlerFactory;
import org.subethamail.smtp.auth.LoginFailedException;
@ -18,9 +21,11 @@ import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.InputStream;
import java.net.BindException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@ -72,6 +77,13 @@ public class EmailServer {
server.setPort(port);
}
/**
* @return the port that the underlying server is listening on
*/
public int port() {
return server.getPort();
}
public void start() {
server.start();
}
@ -86,6 +98,34 @@ public class EmailServer {
return new Listener.Handle(listeners, listener);
}
public static EmailServer localhost(String portRangeStr, final String username, final String password, final ESLogger logger) {
final AtomicReference<EmailServer> emailServer = new AtomicReference<>();
boolean bound = new PortsRange(portRangeStr).iterate(new PortsRange.PortCallback() {
@Override
public boolean onPortNumber(int port) {
try {
EmailServer server = new EmailServer("localhost", port, username, password);
server.start();
emailServer.set(server);
return true;
} catch (RuntimeException re) {
if (re.getCause() instanceof BindException) {
logger.warn("port [{}] was already in use trying next port", re, port);
return false;
} else {
throw re;
}
}
}
});
if (!bound || emailServer.get() == null) {
throw new WatcherException("could not bind to any of the port in [{}]" + portRangeStr);
}
return emailServer.get();
}
public static interface Listener {
void on(MimeMessage message) throws Exception;
@ -106,5 +146,4 @@ public class EmailServer {
}
}
}

View File

@ -14,7 +14,6 @@ import org.elasticsearch.watcher.client.WatcherClient;
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
import org.elasticsearch.watcher.trigger.schedule.IntervalSchedule;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.mail.internet.MimeMessage;
@ -42,12 +41,6 @@ public class EmailActionIntegrationTests extends AbstractWatcherIntegrationTests
private EmailServer server;
@Before
public void init() throws Exception {
server = new EmailServer("localhost", 2500, USERNAME, PASSWORD);
server.start();
}
@After
public void cleanup() throws Exception {
server.stop();
@ -55,12 +48,16 @@ public class EmailActionIntegrationTests extends AbstractWatcherIntegrationTests
@Override
protected Settings nodeSettings(int nodeOrdinal) {
if(server == null) {
//Need to construct the Email Server here as this happens before init()
server = EmailServer.localhost("2500-2600", USERNAME, PASSWORD, logger);
}
return ImmutableSettings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("watcher.actions.email.service.account.test.smtp.auth", true)
.put("watcher.actions.email.service.account.test.smtp.user", USERNAME)
.put("watcher.actions.email.service.account.test.smtp.password", PASSWORD)
.put("watcher.actions.email.service.account.test.smtp.port", 2500)
.put("watcher.actions.email.service.account.test.smtp.port", server.port())
.put("watcher.actions.email.service.account.test.smtp.host", "localhost")
.build();
}