Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
JENKINS-49913 check for attachment size does not consider compression
  • Loading branch information
davidvanlaatum committed Mar 6, 2018
1 parent 8bd0b50 commit 1cde3b1
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 23 deletions.
45 changes: 24 additions & 21 deletions src/main/java/hudson/plugins/emailext/AttachmentUtils.java
Expand Up @@ -79,17 +79,15 @@ public String getName() {
return file.getName();
}
}
private static class LogFileDataSource implements DataSource {

private static class LogFileDataSource implements SizedDataSource {

private static final String DATA_SOURCE_NAME = "build.log";

private final Run<?,?> run;
private final boolean compress;

public LogFileDataSource(Run<?,?> run, boolean compress) {

public LogFileDataSource(Run<?, ?> run) {
this.run = run;
this.compress = compress;
}

public InputStream getInputStream() throws IOException {
Expand All @@ -103,10 +101,6 @@ public InputStream getInputStream() throws IOException {
}

res = new ByteArrayInputStream(bao.toByteArray());
if(compress) {
ZipDataSource z = new ZipDataSource(getName(), res);
res = z.getInputStream();
}
return res;
}

Expand All @@ -122,6 +116,11 @@ public String getContentType() {
public String getName() {
return DATA_SOURCE_NAME;
}

@Override
public long getSize() {
return run.getLogText().length();
}
}

private List<MimeBodyPart> getAttachments(final ExtendedEmailPublisherContext context)
Expand Down Expand Up @@ -201,26 +200,30 @@ private static void attachSingleLog(ExtendedEmailPublisherContext context, Run<?
File logFile = run.getLogFile();
long maxAttachmentSize = context.getPublisher().getDescriptor().getMaxAttachmentSize();

if (maxAttachmentSize > 0 && logFile.length() >= maxAttachmentSize) {
context.getListener().getLogger().println("Skipping build log attachment - "
+ " too large for maximum attachments size");
return;
}

DataSource fileSource;
SizedDataSource fileSource;
MimeBodyPart attachment = new MimeBodyPart();
if (compress) {
context.getListener().getLogger().println("Request made to compress build log");
}

fileSource = new LogFileDataSource(run, compress);

fileSource = new LogFileDataSource(run);
if (compress) {
fileSource = new ZipDataSource(fileSource.getName(), fileSource.getInputStream());
}

if (maxAttachmentSize > 0 && fileSource.getSize() >= maxAttachmentSize) {
context.getListener().getLogger().println("Skipping build log attachment - "
+ " too large for maximum attachments size");
return;
}

if(run instanceof MatrixRun)
attachment.setFileName("build" + "-" + ((MatrixRun)run).getParent().getCombination().toString('-', '-') + "." + (compress ? "zip" : "log"));
else
attachment.setFileName("build." + (compress ? "zip" : "log"));
attachment.setDataHandler(new DataHandler(fileSource));
multipart.addBodyPart(attachment);
} catch(MessagingException e) {
} catch (MessagingException | IOException e) {
context.getListener().error("Error attaching build log to message: " + e.getMessage());
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/hudson/plugins/emailext/SizedDataSource.java
@@ -0,0 +1,7 @@
package hudson.plugins.emailext;

import javax.activation.DataSource;

public interface SizedDataSource extends DataSource {
long getSize();
}
10 changes: 8 additions & 2 deletions src/main/java/hudson/plugins/emailext/plugins/ZipDataSource.java
@@ -1,6 +1,7 @@
package hudson.plugins.emailext.plugins;

import javax.activation.DataSource;
import hudson.plugins.emailext.SizedDataSource;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
Expand All @@ -12,7 +13,7 @@
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;

public class ZipDataSource implements DataSource {
public class ZipDataSource implements SizedDataSource {

private final static String MIME_TYPE = "application/zip";
private final static String FILE_EXTENSION = ".zip";
Expand Down Expand Up @@ -58,4 +59,9 @@ public String getName() {
public OutputStream getOutputStream() throws IOException {
throw new ZipException("This zip file " + name + " is not modifiable");
}

@Override
public long getSize() {
return contents.length;
}
}
79 changes: 79 additions & 0 deletions src/test/java/hudson/plugins/emailext/AttachmentUtilsTest.java
Expand Up @@ -15,6 +15,8 @@
import hudson.plugins.emailext.plugins.RecipientProvider;
import hudson.plugins.emailext.plugins.recipients.ListRecipientProvider;
import hudson.plugins.emailext.plugins.trigger.SuccessTrigger;
import org.apache.commons.io.IOUtils;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
Expand All @@ -32,7 +34,13 @@
import java.net.URL;
import java.util.Collections;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

/**
Expand All @@ -50,6 +58,77 @@ public void before() throws Throwable {
}
};

@Test
public void testBuildLogAttachment() throws Exception {
FreeStyleProject project = j.createFreeStyleProject("foo");
ExtendedEmailPublisher publisher = new ExtendedEmailPublisher();
publisher.attachBuildLog = true;
publisher.recipientList = "mickey@disney.com";
SuccessTrigger trigger = new SuccessTrigger(Collections.<RecipientProvider>singletonList(new ListRecipientProvider()), "", "", "", "", "", 0, "project");
publisher.getConfiguredTriggers().add(trigger);
project.getPublishersList().add(publisher);
FreeStyleBuild b = j.buildAndAssertSuccess(project);

Mailbox mbox = Mailbox.get("mickey@disney.com");
assertEquals("Should have an email from success", 1, mbox.size());

Message msg = mbox.get(0);
assertThat(msg, instanceOf(MimeMessage.class));
assertThat(msg.getContent(), instanceOf(MimeMultipart.class));

MimeMultipart part = (MimeMultipart) msg.getContent();

assertEquals("Should have two body items (message + attachment)", 2, part.getCount());

BodyPart attach = part.getBodyPart(1);
assertThat(attach.getSize(), greaterThan(0));
assertThat(IOUtils.toString(attach.getInputStream()), containsString("mickey@disney.com"));
assertEquals("build.log", attach.getFileName());
}

@Test
public void testBuildLogZipAttachment() throws Exception {
// check the size limit applies to the compressed size
j.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class).setMaxAttachmentSize(80000);
FreeStyleProject project = j.createFreeStyleProject("foo");
ExtendedEmailPublisher publisher = new ExtendedEmailPublisher();
publisher.attachBuildLog = true;
publisher.compressBuildLog = true;
publisher.recipientList = "mickey@disney.com";
SuccessTrigger trigger = new SuccessTrigger(Collections.<RecipientProvider>singletonList(new ListRecipientProvider()), "", "", "", "", "", 0, "project");
publisher.getConfiguredTriggers().add(trigger);
project.getPublishersList().add(publisher);
project.getBuildersList().add(new TestBuilder() {
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
for (int i = 0; i < 1000; i++) // Pad out the build log so the zip has something to compress
listener.getLogger().println("Oh Mickey, you're so fine\n" +
"You're so fine you blow my mind, hey Mickey,\n" +
"Hey Mickey\n");
return true;
}
});

FreeStyleBuild b = j.buildAndAssertSuccess(project);

Mailbox mbox = Mailbox.get("mickey@disney.com");
assertEquals("Should have an email from success", 1, mbox.size());

Message msg = mbox.get(0);
assertThat(msg, instanceOf(MimeMessage.class));
assertThat(msg.getContent(), instanceOf(MimeMultipart.class));

MimeMultipart part = (MimeMultipart) msg.getContent();

assertEquals("Should have two body items (message + attachment)", 2, part.getCount());

BodyPart attach = part.getBodyPart(1);
assertThat(attach.getSize(), allOf(greaterThan(0),
lessThanOrEqualTo((new Long(b.getLogFile().length()).intValue()))));
assertEquals("build.zip", attach.getFileName());
assertThat(IOUtils.toString(attach.getInputStream()), containsString("build.log")); // zips have plain text filename in them
}

@Test
public void testAttachmentFromWorkspace() throws Exception {
URL url = this.getClass().getResource("/test.pdf");
Expand Down

0 comments on commit 1cde3b1

Please sign in to comment.