changeset 352:1b3be513520e

TW-13178 clean tmp dir when cat command fails
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 18 Jan 2012 13:07:14 +0400
parents 8458ac11efb4
children 15c86ab0046c
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommandTest.java mercurial-tests/src/testng.xml
diffstat 4 files changed, 88 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java	Wed Jan 18 12:23:14 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java	Wed Jan 18 13:07:14 2012 +0400
@@ -26,6 +26,8 @@
 import java.util.List;
 import java.util.Queue;
 
+import static com.intellij.openapi.util.io.FileUtil.delete;
+
 public class CatCommand extends VcsRootCommand {
   private String myRevId;
   private final static int MAX_CMD_LEN = 900;
@@ -43,19 +45,36 @@
   }
 
   public File execute(List<String> relPaths, boolean checkFailure) throws VcsException {
-    File tempDir;
+    File tempDir = null;
     try {
-      tempDir = FileUtil.createTempDirectory("mercurial", "catresult");
+      tempDir = createTmpDir();
+      createDirectories(relPaths, tempDir);
+      catFiles(relPaths, checkFailure, tempDir);
+      return tempDir;
+    } catch (VcsException e) {
+      if (tempDir != null)
+        delete(tempDir);
+      throw e;
+    }
+  }
+
+  private File createTmpDir() throws VcsException {
+    try {
+      return FileUtil.createTempDirectory("mercurial", "catresult");
     } catch (IOException e) {
       throw new VcsException("Unable to create temporary directory");
     }
+  }
+
+  private void createDirectories(List<String> relPaths, File tempDir) throws VcsException {
     for (String path: relPaths) {
-      final File parentFile = new File(tempDir, path).getParentFile();
-      if (!parentFile.isDirectory() && !parentFile.mkdirs()) {
+      File parentFile = new File(tempDir, path).getParentFile();
+      if (!parentFile.isDirectory() && !parentFile.mkdirs())
         throw new VcsException("Failed to create directory: " + parentFile.getAbsolutePath());
-      }
     }
+  }
 
+  private void catFiles(List<String> relPaths, boolean checkFailure, File tempDir) throws VcsException {
     Queue<String> paths = new LinkedList<String>(relPaths);
     while (!paths.isEmpty()) {
       GeneralCommandLine cli = createCommandLine(tempDir);
@@ -69,8 +88,6 @@
 
       runCommand(cli, checkFailure);
     }
-
-    return tempDir;
   }
 
   private GeneralCommandLine createCommandLine(final File tempDir) {
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Jan 18 12:23:14 2012 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Jan 18 13:07:14 2012 +0400
@@ -399,9 +399,8 @@
     File dir = getWorkingDir(settings);
     CatCommand cat = new CatCommand(settings, dir);
     cat.setRevId(cset.getId());
-    File parentDir = null;
+    File parentDir = cat.execute(Collections.singletonList(path), false);
     try {
-      parentDir = cat.execute(Collections.singletonList(path), false);
       File f = new File(parentDir, path);
       if (f.isFile())
         return FileUtil.readText(f);
@@ -410,8 +409,7 @@
     } catch (Exception e) {
       return "";
     } finally {
-      if (parentDir != null)
-        deleteTmpDir(parentDir);
+      deleteTmpDir(parentDir);
     }
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommandTest.java	Wed Jan 18 13:07:14 2012 +0400
@@ -0,0 +1,61 @@
+package jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.List;
+
+import static com.intellij.openapi.util.io.FileUtil.delete;
+import static java.util.Arrays.asList;
+
+/**
+ * @author dmitry.neverov
+ */
+@Test
+public class CatCommandTest extends BaseCommandTestCase {
+
+  //TW-13178
+  public void command_should_not_leave_garbage_in_temp_dir() throws IOException, VcsException {
+    cleanCatResultDirs();
+    setRepository("mercurial-tests/testData/rep1", true);
+    try {
+      runCat(asList("/non/existing/path"));
+      fail("exception should be thrown for non-existing path");
+    } catch (VcsException e) {
+      checkTempDirDoesNotContainCatResults();
+    }
+  }
+
+  private void cleanCatResultDirs() {
+    for (File f : getCatResultDirs())
+      delete(f);
+  }
+
+  private void checkTempDirDoesNotContainCatResults() throws IOException {
+    File[] catresults = getCatResultDirs();
+    assertTrue("cat result dirs are not cleaned: " + asList(catresults), catresults.length == 0);
+  }
+
+  private File[] getCatResultDirs() {
+    String tempDirPath = FileUtil.getTempDirectory();
+    return new File(tempDirPath).listFiles(new FilenameFilter() {
+      public boolean accept(File dir, String name) {
+        return name.startsWith("mercurial") && name.endsWith("catresult");
+      }
+    });
+  }
+
+  private File runCat(@NotNull final List<String> paths) throws IOException, VcsException {
+    return runCommand(new CommandExecutor<File>() {
+      public File execute(@NotNull final Settings settings, @NotNull final File workingDir) throws VcsException {
+        CatCommand cat = new CatCommand(settings, workingDir);
+        return cat.execute(paths);
+      }
+    });
+  }
+}
--- a/mercurial-tests/src/testng.xml	Wed Jan 18 12:23:14 2012 +0400
+++ b/mercurial-tests/src/testng.xml	Wed Jan 18 13:07:14 2012 +0400
@@ -3,6 +3,7 @@
   <test name="Mercurial Tests">
     <classes>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.BaseCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CatCommandTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CloneCommandTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommandTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.StatusCommandTest"/>