You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestTempFileThreaded.java 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.util.tests;
  16. import static org.apache.poi.util.DefaultTempFileCreationStrategy.POIFILES;
  17. import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR;
  18. import static org.junit.jupiter.api.Assertions.assertEquals;
  19. import java.io.File;
  20. import java.io.FileOutputStream;
  21. import java.io.IOException;
  22. import java.io.OutputStream;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.LinkedList;
  26. import java.util.List;
  27. import java.util.Map;
  28. import org.apache.poi.ss.usermodel.Cell;
  29. import org.apache.poi.ss.usermodel.Row;
  30. import org.apache.poi.util.TempFile;
  31. import org.apache.poi.util.TempFileCreationStrategy;
  32. import org.apache.poi.xssf.streaming.SXSSFSheet;
  33. import org.apache.poi.xssf.streaming.SXSSFWorkbook;
  34. import org.junit.jupiter.api.BeforeAll;
  35. import org.junit.jupiter.api.BeforeEach;
  36. import org.junit.jupiter.api.Test;
  37. class TestTempFileThreaded {
  38. private static final int NUMBER_OF_THREADS = 10;
  39. private static final int NUMBER_OF_TESTS = 200;
  40. private volatile Throwable exception;
  41. private int[] executions;
  42. // the actual thread-safe temp-file strategy
  43. private static TempFileCreationStrategy createTempFileCreationStrategy(File poiTempFileDirectory) {
  44. return new TempFileCreationStrategy() {
  45. @Override
  46. public File createTempFile(String prefix, String suffix) throws IOException {
  47. long threadId = Thread.currentThread().getId();
  48. File threadDir = new File(poiTempFileDirectory, Long.toString(threadId));
  49. if (!threadDir.exists()) {
  50. if (!threadDir.mkdirs()) {
  51. throw new IOException("mkdir of " + threadDir + " failed");
  52. }
  53. }
  54. File file = File.createTempFile(prefix, suffix, threadDir);
  55. file.deleteOnExit();
  56. return file;
  57. }
  58. @Override
  59. public File createTempDirectory(String prefix) {
  60. throw new UnsupportedOperationException("createTempDirectory");
  61. }
  62. };
  63. }
  64. @BeforeAll
  65. public static void setUpClass() throws IOException {
  66. String tmpDir = System.getProperty(JAVA_IO_TMPDIR);
  67. if (tmpDir == null) {
  68. throw new IOException("Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!");
  69. }
  70. TempFile.setTempFileCreationStrategy(createTempFileCreationStrategy(new File(new File(tmpDir, POIFILES), "TestTempFileThreaded")));
  71. }
  72. @BeforeEach
  73. void setUp() {
  74. // Initialize array to allow to summarize afterwards
  75. executions = new int[NUMBER_OF_THREADS];
  76. }
  77. @Test
  78. void runTest() throws Throwable {
  79. List<Thread> threads = new LinkedList<>();
  80. // start all threads
  81. for (int i = 0; i < NUMBER_OF_THREADS; i++) {
  82. Thread t = startThread(i, new TestRunnable());
  83. threads.add(t);
  84. }
  85. // wait for all threads
  86. for (int i = 0; i < NUMBER_OF_THREADS; i++) {
  87. threads.get(i).join();
  88. }
  89. // report exceptions if there were any
  90. if (exception != null) {
  91. throw exception;
  92. }
  93. // make sure the resulting number of executions is correct
  94. for (int i = 0; i < NUMBER_OF_THREADS; i++) {
  95. // check if enough items were performed
  96. assertEquals(NUMBER_OF_TESTS, executions[i], "Thread " + i + " did not execute all iterations");
  97. }
  98. }
  99. private static class TestRunnable {
  100. Map<Integer, List<File>> files = new HashMap<>();
  101. public TestRunnable() {
  102. for (int i = 0; i < NUMBER_OF_THREADS; i++) {
  103. files.put(i, new ArrayList<>());
  104. }
  105. }
  106. void doEnd(int threadNum) {
  107. for (File file : files.get(threadNum)) {
  108. if (!file.exists()) {
  109. throw new IllegalStateException("File " + file + " does not exist");
  110. }
  111. if (!file.delete()) {
  112. throw new IllegalStateException("Deletion of " + file + " failed");
  113. }
  114. }
  115. }
  116. void run(int threadNum, int iter) throws Exception {
  117. try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
  118. SXSSFSheet sheet = wb.createSheet("test");
  119. for (int i = 0; i < 100; i++) {
  120. Row row = sheet.createRow(i);
  121. for (int j = 0; j < 10; j++) {
  122. Cell cell = row.createCell(j);
  123. cell.setCellValue("123");
  124. }
  125. }
  126. File file = TempFile.createTempFile("TestTempFile-" + threadNum + "-" + iter + "-", ".xlsx");
  127. try (OutputStream outputStream = new FileOutputStream(file)) {
  128. wb.write(outputStream);
  129. }
  130. files.get(threadNum).add(file);
  131. }
  132. }
  133. }
  134. private Thread startThread(final int threadNum, final TestRunnable run) {
  135. Thread t1 = new Thread(() -> {
  136. try {
  137. for (int iter = 0; iter < NUMBER_OF_TESTS && exception == null; iter++) {
  138. // call the actual test-code
  139. run.run(threadNum, iter);
  140. executions[threadNum]++;
  141. }
  142. // do end-work here, we don't do this in a finally as we log
  143. // Exception
  144. // then anyway
  145. run.doEnd(threadNum);
  146. } catch (Throwable e) {
  147. exception = e;
  148. }
  149. }, "ThreadTestHelper-Thread " + threadNum + ": " + run.getClass().getName());
  150. t1.start();
  151. return t1;
  152. }
  153. }