Add a test with a threaded TempFileCreationStrategy, remove duplicated constant.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1835182 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
834f34c41d
commit
d2c3c7e004
@ -21,6 +21,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link TempFileCreationStrategy} used by {@link TempFile}:
|
* Default implementation of the {@link TempFileCreationStrategy} used by {@link TempFile}:
|
||||||
* Files are collected into one directory and by default are deleted on exit from the VM.
|
* Files are collected into one directory and by default are deleted on exit from the VM.
|
||||||
@ -34,9 +36,6 @@ import java.security.SecureRandom;
|
|||||||
* processes or limited temporary storage.
|
* processes or limited temporary storage.
|
||||||
*/
|
*/
|
||||||
public class DefaultTempFileCreationStrategy implements TempFileCreationStrategy {
|
public class DefaultTempFileCreationStrategy implements TempFileCreationStrategy {
|
||||||
/** Define a constant for this property as it is sometimes mistypes as "tempdir" otherwise
|
|
||||||
* This is private to avoid having two public-visible constants ({@link TempFile#JAVA_IO_TMPDIR}). */
|
|
||||||
private static final String JAVA_IO_TMPDIR = TempFile.JAVA_IO_TMPDIR;
|
|
||||||
/*package*/ static final String POIFILES = "poifiles";
|
/*package*/ static final String POIFILES = "poifiles";
|
||||||
|
|
||||||
/** To keep files after JVM exit, set the <code>-Dpoi.keep.tmp.files</code> JVM property */
|
/** To keep files after JVM exit, set the <code>-Dpoi.keep.tmp.files</code> JVM property */
|
||||||
|
@ -0,0 +1,188 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.poi.util;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFSheet;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.poi.util.DefaultTempFileCreationStrategy.POIFILES;
|
||||||
|
import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class TestTempFileThreaded {
|
||||||
|
private static final int NUMBER_OF_THREADS = 10;
|
||||||
|
private static final int NUMBER_OF_TESTS = 200;
|
||||||
|
|
||||||
|
private volatile Throwable exception;
|
||||||
|
private int executions[];
|
||||||
|
|
||||||
|
// the actual thread-safe temp-file strategy
|
||||||
|
private static TempFileCreationStrategy createTempFileCreationStrategy(File poiTempFileDirectory) {
|
||||||
|
return new TempFileCreationStrategy() {
|
||||||
|
@Override
|
||||||
|
public File createTempFile(String prefix, String suffix) throws IOException {
|
||||||
|
long threadId = Thread.currentThread().getId();
|
||||||
|
File threadDir = new File(poiTempFileDirectory, Long.toString(threadId));
|
||||||
|
if (!threadDir.exists()) {
|
||||||
|
if (!threadDir.mkdirs()) {
|
||||||
|
throw new IOException("mkdir of " + threadDir + " failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = File.createTempFile(prefix, suffix, threadDir);
|
||||||
|
file.deleteOnExit();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File createTempDirectory(String prefix) {
|
||||||
|
throw new UnsupportedOperationException("createTempDirectory");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() throws IOException {
|
||||||
|
String tmpDir = System.getProperty(JAVA_IO_TMPDIR);
|
||||||
|
if (tmpDir == null) {
|
||||||
|
throw new IOException("Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!");
|
||||||
|
}
|
||||||
|
|
||||||
|
TempFile.setTempFileCreationStrategy(createTempFileCreationStrategy(new File(new File(tmpDir, POIFILES), "TestTempFileThreaded")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
// Initialize array to allow to summarize afterwards
|
||||||
|
executions = new int[NUMBER_OF_THREADS];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void runTest() throws Throwable {
|
||||||
|
List<Thread> threads = new LinkedList<>();
|
||||||
|
|
||||||
|
// start all threads
|
||||||
|
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||||
|
Thread t = startThread(i, new TestRunnable());
|
||||||
|
threads.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for all threads
|
||||||
|
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||||
|
threads.get(i).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// report exceptions if there were any
|
||||||
|
if (exception != null) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the resulting number of executions is correct
|
||||||
|
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||||
|
// check if enough items were performed
|
||||||
|
assertEquals("Thread " + i
|
||||||
|
+ " did not execute all iterations", NUMBER_OF_TESTS,
|
||||||
|
executions[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestRunnable {
|
||||||
|
Map<Integer, List<File>> files = new HashMap<>();
|
||||||
|
|
||||||
|
public TestRunnable() {
|
||||||
|
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||||
|
files.put(i, new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doEnd(int threadNum) {
|
||||||
|
for (File file : files.get(threadNum)) {
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new IllegalStateException("File " + file + " does not exist");
|
||||||
|
}
|
||||||
|
if (!file.delete()) {
|
||||||
|
throw new IllegalStateException("Deletion of " + file + " failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(int threadNum, int iter) throws Exception {
|
||||||
|
try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
|
||||||
|
SXSSFSheet sheet = wb.createSheet("test");
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
Row row = sheet.createRow(i);
|
||||||
|
for (int j = 0; j < 10; j++) {
|
||||||
|
Cell cell = row.createCell(j);
|
||||||
|
cell.setCellValue("123");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = TempFile.createTempFile("TestTempFile-" + threadNum + "-" + iter + "-", ".xlsx");
|
||||||
|
try (OutputStream outputStream = new FileOutputStream(file)) {
|
||||||
|
wb.write(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
files.get(threadNum).add(file);
|
||||||
|
|
||||||
|
if (iter % 30 == 0) {
|
||||||
|
System.out.println("thread: " + threadNum + ", iter: " + iter + ": " + file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Thread startThread(final int threadNum, final TestRunnable run) {
|
||||||
|
Thread t1 = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
for (int iter = 0; iter < NUMBER_OF_TESTS && exception == null; iter++) {
|
||||||
|
// call the actual test-code
|
||||||
|
run.run(threadNum, iter);
|
||||||
|
|
||||||
|
executions[threadNum]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do end-work here, we don't do this in a finally as we log
|
||||||
|
// Exception
|
||||||
|
// then anyway
|
||||||
|
run.doEnd(threadNum);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, "ThreadTestHelper-Thread " + threadNum + ": " + run.getClass().getName());
|
||||||
|
|
||||||
|
t1.start();
|
||||||
|
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user