Browse Source

bz-62621 get the mail task tests working

master
Jaikiran Pai 6 years ago
parent
commit
96573e64c8
5 changed files with 413 additions and 262 deletions
  1. +7
    -3
      src/etc/testcases/taskdefs/email/mail.xml
  2. +201
    -0
      src/tests/junit/org/apache/tools/ant/DummyMailServer.java
  3. +54
    -0
      src/tests/junit/org/apache/tools/ant/TestHelper.java
  4. +35
    -8
      src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java
  5. +116
    -251
      src/tests/junit/org/apache/tools/mail/MailMessageTest.java

+ 7
- 3
src/etc/testcases/taskdefs/email/mail.xml View File

@@ -20,7 +20,7 @@

<target name="test1">
<!-- this test is supposed to bring a build exception because user and password is not allowed with plain encoding -->
<mail host="localhost" port="25" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" user="joe" password="secret">
<mail mailhost="localhost" mailport="25" from="joe@abc.com" tolist="laura@xyz.com" subject="hello" encoding="plain" user="joe" password="secret">
<message>
Hi Laura, how are you doing ?
</message>
@@ -28,7 +28,7 @@
</target>
<target name="test2">
<!-- this test is supposed to bring a build exception because SSL is not allowed with plain encoding -->
<mail host="localhost" port="465" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" ssl="true">
<mail mailhost="localhost" mailport="465" from="joe@abc.com" tolist="laura@xyz.com" subject="hello" encoding="plain" ssl="true">
<message>
Hi Laura, how are you doing ?
</message>
@@ -36,5 +36,9 @@
</target>



<target name="test3">
<mail mailhost="localhost" mailport="${EmailTaskTest.test3.port}" from="test3" subject="just a test">
<to address="whoami" />
</mail>
</target>
</project>

+ 201
- 0
src/tests/junit/org/apache/tools/ant/DummyMailServer.java View File

@@ -0,0 +1,201 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;

/**
* A utility class that pretends to be a mail transfer agent. This
* has minimal functionality and is meant to be used only in tests
*/
public class DummyMailServer implements Runnable, Callable<Void> {

private final String host;
private final int port;


private StringBuilder sb = null;
private volatile boolean stop = false;

ServerSocket ssock = null;
Socket sock = null;
BufferedWriter out = null;
BufferedReader in = null;
private boolean data = false; // state engine: false=envelope, true=message

public DummyMailServer(int port) {
this("localhost", port);
}

public DummyMailServer(final String host, final int port) {
this.host = host;
this.port = port;
}

public int getPort() {
return this.port;
}

public String getHost() {
return this.host;
}

@Override
public void run() {
call();
}

@Override
public Void call() {

try {
ssock = new ServerSocket(port);
sock = ssock.accept(); // wait for connection
in = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(
sock.getOutputStream()));
sb = new StringBuilder();
send("220 test SMTP EmailTaskTest\r\n");
while (!stop) {
String response = in.readLine();
if (response == null) {
stop = true;
break;
}
sb.append(response).append("\r\n");

if (!data && response.startsWith("EHLO")) {
// reject Extended HLO semantics, since we don't support it
send("500 EHLO unsupported\r\n");
} else if (!data && response.startsWith("HELO")) {
send("250 " + host + " Hello " + host + " "
+ "[127.0.0.1], pleased to meet you\r\n");
} else if (!data && response.startsWith("MAIL")) {
send("250\r\n");
} else if (!data && response.startsWith("RCPT")) {
send("250\r\n");
} else if (!data && response.startsWith("DATA")) {
send("354\r\n");
data = true;
} else if (data && response.equals(".")) {
send("250\r\n");
data = false;
} else if (!data && response.startsWith("QUIT")) {
send("221\r\n");
stop = true;
} else if (!data) {
send("500 5.5.1 Command unrecognized: \""
+ response + "\"\r\n");
stop = true;
} else {
// sb.append(response + "\r\n");
}
} // while
} catch (IOException ioe) {
if (stop) {
// asked to stop, so ignore the exception and move on
return null;
}
throw new BuildException(ioe);
} finally {
disconnect();
}
return null;
}

private void send(String retmsg) throws IOException {
out.write(retmsg);
out.flush();
sb.append(retmsg);
}

public void disconnect() {
this.stop = true;
if (out != null) {
try {
out.flush();
out.close();
out = null;
} catch (IOException e) {
// ignore
}
}
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
// ignore
}
}
if (sock != null) {
try {
sock.close();
sock = null;
} catch (IOException e) {
// ignore
}
}
if (ssock != null) {
try {
ssock.close();
ssock = null;
} catch (IOException e) {
// ignore
}
}
}

public synchronized String getResult() {
this.stop = true;
return sb.toString();
}

/**
* Starts and returns a new dummy mail server to be used in tests
*
* @return
*/
public static DummyMailServer startMailServer() {
return startMailServer("localhost");
}

/**
* Starts and returns a new dummy mail server to be used in tests
*
* @param host The host on which the mail server will open a server socket to listen on
* @return
*/
public static DummyMailServer startMailServer(final String host) {
final int port = TestHelper.getMaybeAvailablePort();
final DummyMailServer mailServer = new DummyMailServer(host, port);
final Thread thread = new Thread(mailServer);
thread.setDaemon(true);
thread.start();
return mailServer;
}
}

+ 54
- 0
src/tests/junit/org/apache/tools/ant/TestHelper.java View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant;

import java.io.IOException;
import java.net.ServerSocket;

/**
* As the name suggests, utility class used in tests
*/
public class TestHelper {

/**
* Find a TCP/IP port which may continue to be available.
* <br />
* The returned port is available since a socket has successfully bind to it, but this availability is not ensured
* after this method since the associated socket is released and some other process can now use it.
*/
public static int getMaybeAvailablePort() {
final ServerSocket s;
try {
s = new ServerSocket(0);
s.setReuseAddress(true);
int port = s.getLocalPort();
try {
s.close();
} catch (IOException e) {
// ignore
}
return port;
} catch (IOException e) {
// ignore
} finally {

}
throw new IllegalStateException("No TCP/IP port available");
}
}

+ 35
- 8
src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java View File

@@ -20,12 +20,12 @@ package org.apache.tools.ant.taskdefs.email;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildFileRule;
import org.apache.tools.ant.DummyMailServer;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import static org.junit.Assert.fail;

/**
* TODO : develop these testcases - the email task needs to have attributes allowing
* to simulate sending mail and to catch the output in text files or streams
@@ -40,24 +40,51 @@ public class EmailTaskTest {
buildRule.configureProject("src/etc/testcases/taskdefs/email/mail.xml");
}

/**
* Expected failure attempting SMTP auth without MIME
*/
@Test
public void test1() {
try {
buildRule.executeTarget("test1");
fail("Build exception expected: SMTP auth only possibly with MIME mail");
} catch(BuildException ex) {
//TODO assert exception message
} catch (BuildException e) {
// assert it's the expected one
if (!e.getMessage().equals("SMTP auth only possible with MIME mail")) {
throw e;
}
}
}

/**
* Expected failure attempting SSL without MIME
*/
@Test
public void test2() {
try {
buildRule.executeTarget("test2");
fail("Build exception expected: SSL only possibly with MIME mail");
} catch(BuildException ex) {
//TODO assert exception message
} catch (BuildException e) {
// assert it's the expected one
if (!e.getMessage().equals("SSL and STARTTLS only possible with MIME mail")) {
throw e;
}
}
}

/**
* Tests that a basic email sending works
*/
@Test
public void test3() {
final DummyMailServer mailServer = DummyMailServer.startMailServer();
try {
buildRule.getProject().setProperty("EmailTaskTest.test3.port", String.valueOf(mailServer.getPort()));
buildRule.executeTarget("test3");
} finally {
mailServer.disconnect();
}
final String smtpInteraction = mailServer.getResult();
Assert.assertNotNull("No mail received by mail server", smtpInteraction);
// just a basic check
Assert.assertTrue("Unexpected recipients on the sent mail", smtpInteraction.contains("RCPT TO:<whoami>"));
}
}

+ 116
- 251
src/tests/junit/org/apache/tools/mail/MailMessageTest.java View File

@@ -18,24 +18,18 @@

package org.apache.tools.mail;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import org.apache.tools.ant.DummyMailServer;
import org.junit.AssumptionViolatedException;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.junit.Before;
import org.junit.Test;
import org.junit.internal.AssumptionViolatedException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

@@ -46,9 +40,6 @@ import static org.junit.Assert.assertFalse;
*/
public class MailMessageTest {

// 27224 = magic (a random port which is unlikely to be in use)
private static int TEST_PORT = 27224;

private String local = null;

@Before
@@ -69,28 +60,27 @@ public class MailMessageTest {
*/
@Test
public void testAPIExample() throws InterruptedException {
final int port = TEST_PORT + 1;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.cc("cc1@you.com");
testMailClient.cc("cc2@you.com");
testMailClient.bcc("bcc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n"
+ "test line 2");

Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s

final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;
try {
testMailClient = new ClientThread(testMailServer.getPort());

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.cc("cc1@you.com");
testMailClient.cc("cc2@you.com");
testMailClient.bcc("bcc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n"
+ "test line 2");

Thread client = new Thread(testMailClient);
client.start();
client.join(30 * 1000); // a further 30s

} finally {
testMailServer.disconnect();
}
String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
+ "HELO " + local + "\r\n"
@@ -129,23 +119,23 @@ public class MailMessageTest {
*/
@Test
public void testToOnly() throws InterruptedException {
final int port = TEST_PORT + 2;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;
try {
testMailClient = new ClientThread(testMailServer.getPort());

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();
Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -179,23 +169,22 @@ public class MailMessageTest {
*/
@Test
public void testCcOnly() throws InterruptedException {
final int port = TEST_PORT + 3;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.cc("cc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;
try {
testMailClient = new ClientThread(testMailServer.getPort());
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.cc("cc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();

client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -229,23 +218,21 @@ public class MailMessageTest {
*/
@Test
public void testBccOnly() throws InterruptedException {
final int port = TEST_PORT + 4;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.bcc("bcc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;
try {
testMailClient = new ClientThread(testMailServer.getPort());
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.bcc("bcc@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();
client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -279,22 +266,22 @@ public class MailMessageTest {
*/
@Test
public void testNoSubject() throws InterruptedException {
final int port = TEST_PORT + 5;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setMessage("test line 1\n" + "test line 2");
try {
testMailClient = new ClientThread(testMailServer.getPort());
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setMessage("test line 1\n" + "test line 2");

Thread client = new Thread(testMailClient);
client.start();
Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -327,23 +314,22 @@ public class MailMessageTest {
*/
@Test
public void testEmptyBody() throws InterruptedException {
final int port = TEST_PORT + 6;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("");

Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;
try {
testMailClient = new ClientThread(testMailServer.getPort());
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("to@you.com");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("");

Thread client = new Thread(testMailClient);
client.start();

client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -378,23 +364,23 @@ public class MailMessageTest {
*/
@Test
public void testAsciiCharset() throws InterruptedException {
final int port = TEST_PORT + 7;
ServerThread testMailServer = new ServerThread(port);
Thread server = new Thread(testMailServer);
server.start();

ClientThread testMailClient = new ClientThread(port);

testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("Ceki G\u00fclc\u00fc <abuse@mail-abuse.org>");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("");
final DummyMailServer testMailServer = DummyMailServer.startMailServer(this.local);
final ClientThread testMailClient;

Thread client = new Thread(testMailClient);
client.start();

server.join(60 * 1000); // 60s
client.join(30 * 1000); // a further 30s
try {
testMailClient = new ClientThread(testMailServer.getPort());
testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
testMailClient.to("Ceki G\u00fclc\u00fc <abuse@mail-abuse.org>");
testMailClient.setSubject("Test subject");
testMailClient.setMessage("");

Thread client = new Thread(testMailClient);
client.start();

client.join(30 * 1000); // a further 30s
} finally {
testMailServer.disconnect();
}

String result = testMailServer.getResult();
String expectedResult = "220 test SMTP EmailTaskTest\r\n"
@@ -430,127 +416,6 @@ public class MailMessageTest {
assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
}


/**
* A private test class that pretends to be a mail transfer agent
*/
private class ServerThread implements Runnable {

private final int port;
private StringBuilder sb = null;
private boolean loop = false;
ServerSocket ssock = null;
Socket sock = null;
BufferedWriter out = null;
BufferedReader in = null;
private boolean data = false; // state engine: false=envelope, true=message

ServerThread(int port) {
this.port = port;
}

public void run() {

try {
ssock = new ServerSocket(port);
sock = ssock.accept(); // wait for connection
in = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(
sock.getOutputStream()));
sb = new StringBuilder();
send("220 test SMTP EmailTaskTest\r\n");
loop = true;
while (loop) {
String response = in.readLine();
if (response == null) {
loop = false;
break;
}
sb.append(response).append("\r\n");

if (!data && response.startsWith("HELO")) {
send("250 " + local + " Hello " + local + " "
+ "[127.0.0.1], pleased to meet you\r\n");
} else if (!data && response.startsWith("MAIL")) {
send("250\r\n");
} else if (!data && response.startsWith("RCPT")) {
send("250\r\n");
} else if (!data && response.startsWith("DATA")) {
send("354\r\n");
data = true;
} else if (data && response.equals(".")) {
send("250\r\n");
data = false;
} else if (!data && response.startsWith("QUIT")) {
send("221\r\n");
loop = false;
} else if (!data) {
//throw new IllegalStateException("Command unrecognized: "
// + response);
send("500 5.5.1 Command unrecognized: \""
+ response + "\"\r\n");
loop = false;
} else {
// sb.append(response + "\r\n");
}
} // while
} catch (IOException ioe) {
throw new BuildException(ioe);
} finally {
disconnect();
}
}

private void send(String retmsg) throws IOException {
out.write(retmsg);
out.flush();
sb.append(retmsg);
}

private void disconnect() {
if (out != null) {
try {
out.flush();
out.close();
out = null;
} catch (IOException e) {
// ignore
}
}
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
// ignore
}
}
if (sock != null) {
try {
sock.close();
sock = null;
} catch (IOException e) {
// ignore
}
}
if (ssock != null) {
try {
ssock.close();
ssock = null;
} catch (IOException e) {
// ignore
}
}
}

public synchronized String getResult() {
loop = false;
return sb.toString();
}

}

/**
* A private test class that wraps MailMessage
*/


Loading…
Cancel
Save