From d9bf1b18c061109315886932b7e8847a329fa957 Mon Sep 17 00:00:00 2001 From: Jacek Poreda Date: Wed, 11 Dec 2024 15:25:00 +0100 Subject: SONAR-17786 Migrate from Wiser to Greenmail email testing framework Co-authored-by: Alain Kermis --- build.gradle | 6 +- server/sonar-server-common/build.gradle | 4 +- .../email/EmailNotificationChannelTest.java | 82 ++++++++++------------ server/sonar-webserver-core/build.gradle | 4 +- .../org/sonar/server/email/ws/SendActionTest.java | 2 +- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/build.gradle b/build.gradle index 2a0374d754b..4a3eb84409b 100644 --- a/build.gradle +++ b/build.gradle @@ -518,7 +518,11 @@ subprojects { exclude 'commons-logging:commons-logging' } dependency 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.7.0' - dependency 'org.subethamail:subethasmtp:3.1.7' + dependencySet(group: 'com.icegreen', version: '2.1.2') { + entry 'greenmail' + entry 'greenmail-junit4' + entry 'greenmail-junit5' + } dependency 'org.yaml:snakeyaml:2.3' dependency 'org.hibernate.validator:hibernate-validator:8.0.1.Final' dependency 'jakarta.el:jakarta.el-api:5.0.1' diff --git a/server/sonar-server-common/build.gradle b/server/sonar-server-common/build.gradle index 737bef78032..2aefc235c70 100644 --- a/server/sonar-server-common/build.gradle +++ b/server/sonar-server-common/build.gradle @@ -33,7 +33,9 @@ dependencies { testImplementation 'org.elasticsearch.plugin:transport-netty4-client' testImplementation 'ch.qos.logback:logback-core' testImplementation 'com.github.spotbugs:spotbugs-annotations' - testImplementation 'org.subethamail:subethasmtp' + testImplementation 'com.icegreen:greenmail' + testImplementation 'com.icegreen:greenmail-junit4' + testImplementation 'com.icegreen:greenmail-junit5' testImplementation 'com.squareup.okhttp3:mockwebserver' testImplementation 'com.squareup.okhttp3:okhttp-tls' testImplementation 'com.tngtech.java:junit-dataprovider' diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java index 64ad508a0fd..152c8459698 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java @@ -19,20 +19,23 @@ */ package org.sonar.server.notification.email; +import com.icegreen.greenmail.junit4.GreenMailRule; +import com.icegreen.greenmail.smtp.SmtpServer; +import com.icegreen.greenmail.util.ServerSetup; +import com.icegreen.greenmail.util.ServerSetupTest; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import java.io.IOException; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.stream.IntStream; import java.util.stream.Stream; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; -import org.apache.commons.mail.EmailException; +import org.apache.commons.mail2.core.EmailException; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -48,8 +51,6 @@ import org.sonar.server.issue.notification.EmailMessage; import org.sonar.server.issue.notification.EmailTemplate; import org.sonar.server.notification.email.EmailNotificationChannel.EmailDeliveryRequest; import org.sonar.server.oauth.OAuthMicrosoftRestClient; -import org.subethamail.wiser.Wiser; -import org.subethamail.wiser.WiserMessage; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; @@ -70,7 +71,9 @@ public class EmailNotificationChannelTest { @Rule public LogTester logTester = new LogTester(); - private Wiser smtpServer; + @Rule + public final GreenMailRule smtpServer = new GreenMailRule(new ServerSetup[]{ServerSetupTest.SMTP, ServerSetupTest.SMTPS}); + private EmailSmtpConfiguration configuration; private Server server; private EmailNotificationChannel underTest; @@ -78,8 +81,6 @@ public class EmailNotificationChannelTest { @Before public void setUp() { logTester.setLevel(LoggerLevel.DEBUG); - smtpServer = new Wiser(0); - smtpServer.start(); configuration = mock(EmailSmtpConfiguration.class); server = mock(Server.class); @@ -118,10 +119,10 @@ public class EmailNotificationChannelTest { configure(); underTest.sendTestEmail("user@nowhere", "Test Message from SonarQube", "This is a test message from SonarQube."); - List messages = smtpServer.getMessages(); + MimeMessage[] messages = smtpServer.getReceivedMessages(); assertThat(messages).hasSize(1); - MimeMessage email = messages.get(0).getMimeMessage(); + MimeMessage email = messages[0]; assertThat(email.getHeader("Content-Type", null)).isEqualTo("text/plain; charset=UTF-8"); assertThat(email.getHeader("From", ",")).isEqualTo("SonarQube from NoWhere "); assertThat(email.getHeader("To", null)).isEqualTo(""); @@ -160,7 +161,7 @@ public class EmailNotificationChannelTest { .setSubject("Foo") .setPlainTextMessage("Bar"); boolean delivered = underTest.deliver(emailMessage); - assertThat(smtpServer.getMessages()).isEmpty(); + assertThat(smtpServer.getReceivedMessages()).isEmpty(); assertThat(delivered).isFalse(); } @@ -175,10 +176,10 @@ public class EmailNotificationChannelTest { .setPlainTextMessage("I'll take care of this violation."); boolean delivered = underTest.deliver(emailMessage); - List messages = smtpServer.getMessages(); + MimeMessage[] messages = smtpServer.getReceivedMessages(); assertThat(messages).hasSize(1); - MimeMessage email = messages.get(0).getMimeMessage(); + MimeMessage email = messages[0]; assertThat(email.getHeader("Content-Type", null)).isEqualTo("text/plain; charset=UTF-8"); @@ -204,10 +205,10 @@ public class EmailNotificationChannelTest { .setPlainTextMessage("Bar"); boolean delivered = underTest.deliver(emailMessage); - List messages = smtpServer.getMessages(); + MimeMessage[] messages = smtpServer.getReceivedMessages(); assertThat(messages).hasSize(1); - MimeMessage email = messages.get(0).getMimeMessage(); + MimeMessage email = messages[0]; assertThat(email.getHeader("Content-Type", null)).isEqualTo("text/plain; charset=UTF-8"); @@ -240,17 +241,14 @@ public class EmailNotificationChannelTest { @Test public void shouldSendTestEmailWithSTARTTLS() { - smtpServer.getServer().setEnableTLS(true); - smtpServer.getServer().setRequireTLS(true); - configure(); - when(configuration.getSecureConnection()).thenReturn("STARTTLS"); + configure(true); try { underTest.sendTestEmail("user@nowhere", "Test Message from SonarQube", "This is a test message from SonarQube."); fail("An SSL exception was expected a a proof that STARTTLS is enabled"); } catch (EmailException e) { // We don't have a SSL certificate so we are expecting a SSL error - assertThat(e.getCause().getMessage()).isEqualTo("Could not convert socket to TLS"); + assertThat(e.getCause().getMessage()).contains("Exception reading response"); } } @@ -263,7 +261,7 @@ public class EmailNotificationChannelTest { assertThat(count).isZero(); verifyNoInteractions(emailSettings); - assertThat(smtpServer.getMessages()).isEmpty(); + assertThat(smtpServer.getReceivedMessages()).isEmpty(); } @Test @@ -280,7 +278,7 @@ public class EmailNotificationChannelTest { assertThat(count).isZero(); verify(emailSettings).getSmtpHost(); verifyNoMoreInteractions(emailSettings); - assertThat(smtpServer.getMessages()).isEmpty(); + assertThat(smtpServer.getReceivedMessages()).isEmpty(); } @Test @@ -298,7 +296,7 @@ public class EmailNotificationChannelTest { assertThat(count).isZero(); verify(emailSettings).getSmtpHost(); verifyNoMoreInteractions(emailSettings); - assertThat(smtpServer.getMessages()).isEmpty(); + assertThat(smtpServer.getReceivedMessages()).isEmpty(); } @Test @@ -317,21 +315,14 @@ public class EmailNotificationChannelTest { Set requests = Stream.of(notification1, notification2, notification3) .map(t -> new EmailDeliveryRequest(recipientEmail, t)) .collect(toSet()); - EmailNotificationChannel emailNotificationChannel = - new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template1, template3}, null, mock(OAuthMicrosoftRestClient.class)); + EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(configuration, server, new EmailTemplate[]{template1, template3}, null, + mock(OAuthMicrosoftRestClient.class)); int count = emailNotificationChannel.deliverAll(requests); assertThat(count).isEqualTo(2); - assertThat(smtpServer.getMessages()).hasSize(2); - Map messagesBySubject = smtpServer.getMessages().stream() - .map(t -> { - try { - return t.getMimeMessage(); - } catch (MessagingException e) { - throw new RuntimeException(e); - } - }) + assertThat(smtpServer.getReceivedMessages()).hasSize(2); + Map messagesBySubject = Stream.of(smtpServer.getReceivedMessages()) .collect(toMap(t -> { try { return t.getSubject(); @@ -358,20 +349,20 @@ public class EmailNotificationChannelTest { when(template11.format(notification1)).thenReturn(emailMessage11); when(template12.format(notification1)).thenReturn(emailMessage12); EmailDeliveryRequest request = new EmailDeliveryRequest(recipientEmail, notification1); - EmailNotificationChannel emailNotificationChannel = - new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template11, template12}, null, mock(OAuthMicrosoftRestClient.class)); + EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(configuration, server, new EmailTemplate[]{template11, template12}, null, + mock(OAuthMicrosoftRestClient.class)); int count = emailNotificationChannel.deliverAll(Collections.singleton(request)); assertThat(count).isOne(); - assertThat(smtpServer.getMessages()).hasSize(1); - assertThat((String) smtpServer.getMessages().iterator().next().getMimeMessage().getContent()) + assertThat(smtpServer.getReceivedMessages()).hasSize(1); + assertThat((String) smtpServer.getReceivedMessages()[0].getContent()) .contains(emailMessage11.getMessage()); } @DataProvider public static Object[][] emptyStrings() { - return new Object[][] { + return new Object[][]{ {""}, {" "}, {" \n "} @@ -379,9 +370,14 @@ public class EmailNotificationChannelTest { } private void configure() { - when(configuration.getSmtpHost()).thenReturn("localhost"); - when(configuration.getSmtpPort()).thenReturn(smtpServer.getServer().getPort()); - when(configuration.getSecureConnection()).thenReturn("NONE"); + configure(false); + } + + private void configure(boolean isSecure) { + SmtpServer localSmtpServer = isSecure ? smtpServer.getSmtps() : smtpServer.getSmtp(); + when(configuration.getSmtpHost()).thenReturn(localSmtpServer.getBindTo()); + when(configuration.getSmtpPort()).thenReturn(localSmtpServer.getPort()); + when(configuration.getSecureConnection()).thenReturn(isSecure ? "STARTTLS" : "NONE"); when(configuration.getFrom()).thenReturn("server@nowhere"); when(configuration.getFromName()).thenReturn("SonarQube from NoWhere"); when(configuration.getPrefix()).thenReturn(SUBJECT_PREFIX); diff --git a/server/sonar-webserver-core/build.gradle b/server/sonar-webserver-core/build.gradle index d22956d1a26..d178f7c7fbb 100644 --- a/server/sonar-webserver-core/build.gradle +++ b/server/sonar-webserver-core/build.gradle @@ -71,7 +71,9 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-params' testImplementation 'org.mockito:mockito-core' testImplementation 'org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures' - testImplementation 'org.subethamail:subethasmtp' + testImplementation 'com.icegreen:greenmail' + testImplementation 'com.icegreen:greenmail-junit4' + testImplementation 'com.icegreen:greenmail-junit5' testImplementation testFixtures(project(':server:sonar-server-common')) testImplementation testFixtures(project(':server:sonar-webserver-auth')) testImplementation testFixtures(project(':server:sonar-webserver-es')) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/email/ws/SendActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/email/ws/SendActionTest.java index b597b1bc30f..5c8f6cbdf19 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/email/ws/SendActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/email/ws/SendActionTest.java @@ -20,7 +20,7 @@ package org.sonar.server.email.ws; import javax.annotation.Nullable; -import org.apache.commons.mail.EmailException; +import org.apache.commons.mail2.core.EmailException; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -- cgit v1.2.3