无法删除 junit TemporaryFolderRule 创建的文件夹

发布于 2024-10-25 07:23:15 字数 3377 浏览 4 评论 0原文

我有一个类来管理一些文件的存档,我们对这些文件进行一些传入处理。当尝试测试归档过程时,我使用了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

捎一片雪花 2024-11-01 07:23:15

事实证明,原来的问题没有足够的细节。 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文