Add file system persistence tests:
[pintos-anon] / src / tests / filesys / extended / dir-rm-cwd.c
index 7f81a0bef234c5e18030fda20dd0f34b77309f54..78e13dea23492dd5f69953220c53d25b898f2b95 100644 (file)
@@ -1,19 +1,75 @@
-/* Tries to remove the current directory.
-   This is allowed to succeed or fail.
-   Then creates a file in the root to make sure that we haven't
-   corrupted any directory state. */
+/* Tries to remove the current directory, which may succeed or
+   fail.  The requirements in each case are different; refer to
+   the assignment for details. */
 
 #include <syscall.h>
 #include "tests/lib.h"
 #include "tests/main.h"
 
+static int
+wrap_open (const char *name) 
+{
+  static int fds[8], fd_cnt;
+  int fd, i;
+
+  CHECK ((fd = open (name)) > 1, "open \"%s\"", name);
+  for (i = 0; i < fd_cnt; i++)
+    if (fds[i] == fd)
+      fail ("fd returned is not unique");
+  fds[fd_cnt++] = fd;
+  return fd;
+}
+
 void
 test_main (void) 
 {
+  int root_fd, a_fd0;
+  char name[READDIR_MAX_LEN + 1];
+
+  root_fd = wrap_open ("/");
   CHECK (mkdir ("a"), "mkdir \"a\"");
+
+  a_fd0 = wrap_open ("/a");
+  CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty");
+  CHECK (inumber (root_fd) != inumber (a_fd0),
+         "\"/\" and \"/a\" must have different inumbers");
+
   CHECK (chdir ("a"), "chdir \"a\"");
-  msg ("remove \"/a\" (must not crash)");
-  remove ("/a");
-  msg ("create \"b\" (must not crash)");
-  create ("b", 123);
+
+  msg ("try to remove \"/a\"");
+  if (remove ("/a"))
+    {
+      msg ("remove successful");
+
+      CHECK (open ("/a") == -1, "open \"/a\" (must fail)");
+      CHECK (open (".") == -1, "open \".\" (must fail)");
+      CHECK (open ("..") == -1, "open \"..\" (must fail)");
+      CHECK (!create ("x", 512), "create \"x\" (must fail)");
+    }
+  else
+    {
+      int a_fd1, a_fd2, a_fd3;
+
+      msg ("remove failed");
+
+      CHECK (!remove ("../a"), "try to remove \"../a\" (must fail)");
+      CHECK (!remove (".././a"), "try to remove \".././a\" (must fail)");
+      CHECK (!remove ("/./a"), "try to remove \"/./a\" (must fail)");
+
+      a_fd1 = wrap_open ("/a");
+      a_fd2 = wrap_open (".");
+      CHECK (inumber (a_fd1) == inumber (a_fd2),
+             "\"/a\" and \".\" must have same inumber");
+      CHECK (inumber (root_fd) != inumber (a_fd1),
+             "\"/\" and \"/a\" must have different inumbers");
+
+      CHECK (chdir ("/a"), "chdir \"/a\"");
+      a_fd3 = wrap_open (".");
+      CHECK (inumber (a_fd3) == inumber (a_fd1),
+             "\".\" must have same inumber as before");
+
+      CHECK (chdir ("/"), "chdir \"/\"");
+      CHECK (!remove ("a"), "try to remove \"a\" (must fail: still open)");
+    }
+  CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty");
 }