REPO-3424 Unit tests for docker transformers

This commit is contained in:
Alan Davis
2018-04-16 16:24:09 +01:00
parent af4950d99a
commit 0b1ffe9f29
31 changed files with 1027 additions and 61 deletions

View File

@@ -4,8 +4,6 @@
<name>Alfresco Docker LibreOffice</name>
<packaging>jar</packaging>
<version>0.9-SNAPSHOT</version>
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-docker-transformers</artifactId>
@@ -60,6 +58,14 @@
<artifactId>pdfbox</artifactId>
<version>${dependency.pdfbox.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-transformer-base</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -291,7 +291,7 @@ public class JodConverterSharedInstance implements InitializingBean, DisposableB
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception
public void afterPropertiesSet()
{
// isAvailable defaults to false afterPropertiesSet. It only becomes true on successful completion of this method.
this.isAvailable = false;

View File

@@ -71,16 +71,17 @@ public class LibreOfficeController extends AbstractTransformerController
logEnterpriseLicenseMessage();
logger.info("This transformer uses LibreOffice from The Document Foundation. See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt");
logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------");
setJodConverter(createJodConverter());
}
private static JodConverter createJodConverter() throws Exception
private static JodConverter createJodConverter(Long taskExecutionTimeout)
{
String timeout = taskExecutionTimeout <= 0 ? "120000" : taskExecutionTimeout.toString();
JodConverterSharedInstance jodconverter = new JodConverterSharedInstance();
jodconverter.setOfficeHome(OFFICE_HOME); // jodconverter.officeHome
jodconverter.setMaxTasksPerProcess("200"); // jodconverter.maxTasksPerProcess
jodconverter.setTaskExecutionTimeout("120000"); // jodconverter.maxTasksPerProcess
jodconverter.setTaskExecutionTimeout(timeout); // jodconverter.maxTaskExecutionTimeout
jodconverter.setTaskQueueTimeout("30000"); // jodconverter.taskQueueTimeout
jodconverter.setConnectTimeout("28000"); // jodconverter.connectTimeout
jodconverter.setPortNumbers("8100"); // jodconverter.portNumbers
@@ -96,6 +97,19 @@ public class LibreOfficeController extends AbstractTransformerController
this.jodconverter = jodconverter;
}
/**
* Jodconverter timeouts are per OfficeManager, so we would need multiple OfficeManagers if we
* have different timeouts. Alfresco only has one. So we delay building it until the first request.
* This was not done previously.
*/
private synchronized void setJodConverterOnFirstRequest(Long timeout)
{
if (jodconverter == null)
{
setJodConverter(createJodConverter(timeout));
}
}
@Override
protected String getTransformerName()
{
@@ -118,29 +132,30 @@ public class LibreOfficeController extends AbstractTransformerController
public ResponseEntity<Resource> transform(HttpServletRequest request,
@RequestParam("file") MultipartFile sourceMultipartFile,
@RequestParam("targetExtension") String targetExtension,
@RequestParam(value = "timeout", required = false) Long timeout)
@RequestParam(value = "timeout", required = false) Long timeout,
@RequestParam(value = "testDelay", required = false) Long testDelay)
{
String targetFilename = createTargetFileName(sourceMultipartFile, targetExtension);
File sourceFile = createSourceFile(request, sourceMultipartFile);
File targetFile = createTargetFile(request, targetFilename);
// Both files are deleted by TransformInterceptor.afterCompletion
executeTransformCommand(sourceFile, targetFile);
executeTransformCommand(sourceFile, targetFile, timeout);
return createAttachment(targetFilename, targetFile);
return createAttachment(targetFilename, targetFile, testDelay);
}
protected void executeTransformCommand(File sourceFile, File targetFile)
protected void executeTransformCommand(File sourceFile, File targetFile, Long timeout)
{
timeout = timeout != null && timeout > 0 ? timeout : 0;
try
{
OfficeManager officeManager = jodconverter.getOfficeManager();
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
converter.convert(sourceFile, targetFile);
convert(sourceFile, targetFile, timeout);
}
catch (OfficeException e)
{
throw new TransformException(500, "LibreOffice server conversion failed: \n"+
throw new TransformException(400, "LibreOffice server conversion failed: \n"+
" from file: " + sourceFile + "\n" +
" to file: " + targetFile,
e);
@@ -169,6 +184,14 @@ public class LibreOfficeController extends AbstractTransformerController
}
}
void convert(File sourceFile, File targetFile, long timeout)
{
setJodConverterOnFirstRequest(timeout);
OfficeManager officeManager = jodconverter.getOfficeManager();
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
converter.convert(sourceFile, targetFile);
}
/**
* This method produces an empty PDF file at the specified File location.
* Apache's PDFBox is used to create the PDF file.

View File

@@ -8,6 +8,7 @@
<tr><td><div style="text-align:right">file *</div></td><td><input type="file" name="file" /></td></tr>
<tr><td><div style="text-align:right">targetExtension *</div></td><td><input type="text" name="targetExtension" value="" /></td></tr>
<tr><td><div style="text-align:right">timeout</div></td><td><input type="text" name="timeout" value="" /></td></tr>
<tr><td><div style="text-align:right">testDelay</div></td><td><input type="text" name="testDelay" value="" /></td></tr>
<tr><td></td><td><input type="submit" value="Transform" /></td></tr>
</table>

View File

@@ -0,0 +1,130 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2018 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.transformer;
import org.artofsolving.jodconverter.office.OfficeException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.stubbing.Answer;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.Arrays;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Test the LibreOfficeController without a server.
* Super class includes tests for the AbstractTransformerController.
*/
@RunWith(SpringRunner.class)
@WebMvcTest(LibreOfficeControllerTest.class)
public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
{
@SpyBean
private LibreOfficeController controller;
@Before
public void before() throws IOException
{
sourceExtension = "doc";
targetExtension = "pdf";
sourceMimetype = "application/msword";
// The following is based on super.mockTransformCommand(...)
// This is because LibreOffice used JodConverter rather than a RuntimeExec
expectedSourceFileBytes = Files.readAllBytes(getTestFile("quick."+sourceExtension, true).toPath());
expectedTargetFileBytes = Files.readAllBytes(getTestFile("quick."+targetExtension, true).toPath());
sourceFile = new MockMultipartFile("file", "quick."+sourceExtension, sourceMimetype, expectedSourceFileBytes);
doAnswer((Answer) invocation ->
{
File sourceFile = invocation.getArgumentAt(0, File.class);
File targetFile = invocation.getArgumentAt(1, File.class);
assertNotNull(sourceFile);
assertNotNull(targetFile);
Long actualTimeout = invocation.getArgumentAt(2, Long.class);
assertNotNull(actualTimeout);
if (expectedTimeout != null)
{
assertEquals("expectedTimeout", expectedTimeout, actualTimeout);
}
// Copy a test file into the target file location if it exists
String actualTarget = targetFile.getAbsolutePath();
int i = actualTarget.lastIndexOf('_');
if (i >= 0)
{
String testFilename = actualTarget.substring(i+1);
File testFile = getTestFile(testFilename, false);
if (testFile != null)
{
FileChannel source = new FileInputStream(testFile).getChannel();
FileChannel target = new FileOutputStream(targetFile).getChannel();
target.transferFrom(source, 0, source.size());
}
}
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = Files.readAllBytes(sourceFile.toPath());
assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes));
return null;
}).when(controller).convert(any(), any(), anyLong());
}
@Test
@Override
public void badExitCodeTest() throws Exception
{
doThrow(OfficeException.class).when(controller).convert(any(), any(), anyLong());
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform")
.file(sourceFile)
.param("targetExtension", "xxx"))
.andExpect(status().is(400))
.andExpect(status().reason(containsString("LibreOffice - LibreOffice server conversion failed:")));
}
}

View File

@@ -0,0 +1,50 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2018 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.transformer;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Tests AlfrescoPdfRendererHttpRequestTest with a server test harness.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class LibreOfficeHttpRequestTest extends AbstractHttpRequestTest
{
@Override
protected String getTransformerName()
{
return "LibreOffice";
}
@Override
protected String getSourceExtension()
{
return "doc";
};
}