Monday, October 19, 2009

A Symbolic Puzzler

Update: If you're reading this post in Google Reader, view the original page to participate in the survey.

Here's a little Java puzzler I encountered back in August. Essentially, the test below creates a symlink to /testdir/file, and validates that the symlink is in fact pointing to it.

This test was run on a Mac Book Pro running OSX 10.5.8 using a 1.5.0 JVM, though I originally discovered this problem using Linux and a Java 1.6 VM. The path /testdir is not a symbolic link to another directory, and the user running the test also owns /testdir.

import java.io.*;
import junit.framework.TestCase;

public class ATest extends TestCase {
  public void testSymlink() throws Exception {
    // Setup
    run("/bin/rm", "/testdir/file", "/testdir/symlink");
    run("/usr/bin/touch", "/testdir/file");

    File TESTDIR_SYMLINK = new File("/testdir/symlink");

    // Symlink doesn't exist yet
    assertFalse(TESTDIR_SYMLINK.exists());

    // And so its canonical path points to itself.
    assertEquals("/testdir/symlink", TESTDIR_SYMLINK.getCanonicalPath());

    // Now point the symlink to the file.
    run("/bin/ln", "-s", "/testdir/file", "/testdir/symlink");

    // The symlink exists
    assertTrue(TESTDIR_SYMLINK.exists());

    // The canonical path should be up to date.
    assertEquals("/testdir/file", TESTDIR_SYMLINK.getCanonicalPath());
  }

  private static void run(String... args)
      throws IOException, InterruptedException {
    new ProcessBuilder(args).start().waitFor();
  }
}

These are your choices. Try to determine the answer by solely looking at the sample code. Vote for your preference, and I'll publish the results along with the correct answer.

Voting is open until some time early Wednesday morning, Oct 21.