无法删除 junit TemporaryFolderRule 创建的文件夹
我有一个类来管理一些文件的存档,我们对这些文件进行一些传入处理。当尝试测试归档过程时,我使用了 JUnit 中的 TemporaryFolder 规则。
在我们正常的 Linux 开发站上,测试运行没有任何问题,在一些团队成员拥有的一些 Windows 笔记本电脑上,但在我的 Mac 上,我最终得到以下信息:
whenFullExtractReceivedArchivesArePurged(housekeeping.ArchiveHousekeeperIntegrationTest): 无法删除/var/folders/Pl/PlAbV+EpHhW2-nPFrFrwI++++TI/-Tmp-/junit5525189319546810170/secondaryArchive
这是测试:
package housekeeping;
import static housekeeping.ArchiveHousekeeper.PRIMARY_ARCHIVE;
import static housekeeping.ArchiveHousekeeper.SECONDARY_ARCHIVE;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class ArchiveHousekeeperIntegrationTest {
private static final String LANDING_FOLDER = "landing";
private static final String PREVIOUS_FILE_NAME = "previousChild.txt";
private static final String CURRENT_FILE_NAME = "currentChild.txt";
private File primaryArchiveFolder;
private File secondaryArchiveFolder;
private File landingFolder;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
public void setUp() throws IOException {
temporaryFolder.getRoot();
primaryArchiveFolder = temporaryFolder.newFolder(PRIMARY_ARCHIVE);
secondaryArchiveFolder = temporaryFolder.newFolder(SECONDARY_ARCHIVE);
landingFolder = temporaryFolder.newFolder(LANDING_FOLDER);
createChildFile(primaryArchiveFolder, CURRENT_FILE_NAME);
createChildFile(secondaryArchiveFolder, PREVIOUS_FILE_NAME);
}
@Test
public void whenFullExtractReceivedArchivesArePurged() throws IOException {
final String extractFileName = "fullExtract0101.zip";
final File extractFile = new File(landingFolder, extractFileName);
extractFile.createNewFile();
final ArchiveHousekeeper housekeeper = new ArchiveHousekeeper(extractFile);
housekeeper.archiveFile();
assertThat(landingFolder.list().length, is(0));
assertThat(primaryArchiveFolder, containsFile(extractFileName));
assertThat(secondaryArchiveFolder, not(containsFile(PREVIOUS_FILE_NAME)));
assertThat(secondaryArchiveFolder, containsFile(CURRENT_FILE_NAME));
assertThat(primaryArchiveFolder, not(containsFile(CURRENT_FILE_NAME)));
}
@Factory
private static Matcher<File> containsFile(final String fileName) {
return new TypeSafeMatcher<File>() {
@Override
public void describeTo(final Description description) {
description.appendText("a directory containing " + fileName);
}
@Override
public boolean matchesSafely(final File item) {
return item != null && item.isDirectory() && Arrays.asList(item.list()).contains(fileName);
}
};
}
private File createChildFile(final File parent, final String child) throws IOException {
final File folder = new File(parent, child);
folder.createNewFile();
return folder;
}
}
我不确定是否看到某种奇怪的权限问题或什么,那就是什么看起来像。我只是发现这令人困惑,因为测试创建了文件夹,所以它似乎应该拥有它的权限。
值得注意的是,被测试的代码似乎确实有效,在其他平台上测试运行成功。
I have a class that manages the archive of some files that we do some incoming processing on. When trying to test the archiving process I made use of the TemporaryFolder rule in JUnit.
On our normal Linux development stations the test runs without any problems, on some Windows laptops some of the team members have, but on my Mac I end up getting the following:
whenFullExtractReceivedArchivesArePurged(housekeeping.ArchiveHousekeeperIntegrationTest): Failed to delete /var/folders/Pl/PlAbV+EpHhW2-nPFrFrwI++++TI/-Tmp-/junit5525189319546810170/secondaryArchive
Here is the test:
package housekeeping;
import static housekeeping.ArchiveHousekeeper.PRIMARY_ARCHIVE;
import static housekeeping.ArchiveHousekeeper.SECONDARY_ARCHIVE;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class ArchiveHousekeeperIntegrationTest {
private static final String LANDING_FOLDER = "landing";
private static final String PREVIOUS_FILE_NAME = "previousChild.txt";
private static final String CURRENT_FILE_NAME = "currentChild.txt";
private File primaryArchiveFolder;
private File secondaryArchiveFolder;
private File landingFolder;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
public void setUp() throws IOException {
temporaryFolder.getRoot();
primaryArchiveFolder = temporaryFolder.newFolder(PRIMARY_ARCHIVE);
secondaryArchiveFolder = temporaryFolder.newFolder(SECONDARY_ARCHIVE);
landingFolder = temporaryFolder.newFolder(LANDING_FOLDER);
createChildFile(primaryArchiveFolder, CURRENT_FILE_NAME);
createChildFile(secondaryArchiveFolder, PREVIOUS_FILE_NAME);
}
@Test
public void whenFullExtractReceivedArchivesArePurged() throws IOException {
final String extractFileName = "fullExtract0101.zip";
final File extractFile = new File(landingFolder, extractFileName);
extractFile.createNewFile();
final ArchiveHousekeeper housekeeper = new ArchiveHousekeeper(extractFile);
housekeeper.archiveFile();
assertThat(landingFolder.list().length, is(0));
assertThat(primaryArchiveFolder, containsFile(extractFileName));
assertThat(secondaryArchiveFolder, not(containsFile(PREVIOUS_FILE_NAME)));
assertThat(secondaryArchiveFolder, containsFile(CURRENT_FILE_NAME));
assertThat(primaryArchiveFolder, not(containsFile(CURRENT_FILE_NAME)));
}
@Factory
private static Matcher<File> containsFile(final String fileName) {
return new TypeSafeMatcher<File>() {
@Override
public void describeTo(final Description description) {
description.appendText("a directory containing " + fileName);
}
@Override
public boolean matchesSafely(final File item) {
return item != null && item.isDirectory() && Arrays.asList(item.list()).contains(fileName);
}
};
}
private File createChildFile(final File parent, final String child) throws IOException {
final File folder = new File(parent, child);
folder.createNewFile();
return folder;
}
}
I am not sure if I am seeing some sort of odd permission issue or what, that is what it seems like. I just find that perplexing as the test creates the folder so it seems like it should have permissions on it.
It is worth noting that the code under test does seem to work, on other platforms the test runs successfully.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,原来的问题没有足够的细节。 ArchiveHousekeeper 使用的是 Guava 中的 Files.recursivelyDelete。
文件删除的特定实现具有一些保护措施来阻止符号链接的删除。 TemporaryFolder 在 Mac 上的工作方式会创建一个符号链接,并且不会删除辅助存档的内容,因此实际文件夹的删除会失败。导致抛出异常。
As it turns out, there wasn't enough detail in the original question. The ArchiveHousekeeper was using Files.recursivelyDelete from Guava.
That particular implementation of file delete has some protections to stop the deletion of symlinks. The way TemporaryFolder works on a Mac creates a symlink and it won't delete the contents of the secondary archive so the deletion of the actual folder fails. Leading to the exception being thrown.