private static Inode tryToCreateIfMissing(VirtualFileSystem vfs, Inode inode, String name)
     throws IOException {
   try {
     return vfs.lookup(inode, name);
   } catch (NoEntException e) {
     return vfs.create(inode, Stat.Type.DIRECTORY, name, Subjects.ROOT, 0777);
   }
 }
  @Test
  public void testContinueReadingAfterEOF() throws Exception {

    // vfs will return only "." and ".." as contents, both leading to itself
    List<DirectoryEntry> dirContents = new ArrayList<>();
    dirContents.add(new DirectoryEntry(".", dirInode, dirStat));
    dirContents.add(new DirectoryEntry("..", dirInode, dirStat));
    Mockito.when(vfs.list(Mockito.eq(dirInode))).thenReturn(dirContents);

    // set up and execute the 1st call - no cookie, but very tight size limit
    RpcCall call =
        new RpcCallBuilder().from("1.2.3.4", "someHost.acme.com", 42).nfs3().noAuth().build();
    READDIR3args args = NfsV3Ops.readDir(dirHandle);
    READDIR3res result = nfsServer.NFSPROC3_READDIR_3(call, args);

    Assert.assertEquals(nfsstat.NFS_OK, result.status); // response ok
    Assert.assertTrue(result.resok.reply.eof); // eof
    AssertXdr.assertXdrEncodable(result);

    // client violates spec - attempts to read more
    // using cookie on last (2nd) entry and returned verifier
    long cookie = result.resok.reply.entries.nextentry.cookie.value.value;
    byte[] cookieVerifier = result.resok.cookieverf.value;
    args = NfsV3Ops.readDir(dirHandle, cookie, cookieVerifier);
    result = nfsServer.NFSPROC3_READDIR_3(call, args);

    Assert.assertEquals(nfsstat.NFSERR_BAD_COOKIE, result.status); // error response
    AssertXdr.assertXdrEncodable(result);
  }
  @Test
  public void testReadDirWithTinyLimit() throws Exception {
    // vfs will return only "." and ".." as contents, both leading to itself
    List<DirectoryEntry> dirContents = new ArrayList<>();
    dirContents.add(new DirectoryEntry(".", dirInode, dirStat));
    dirContents.add(new DirectoryEntry("..", dirInode, dirStat));
    Mockito.when(vfs.list(Mockito.eq(dirInode))).thenReturn(dirContents);

    // set up and execute the 1st call - no cookie, but very tight size limit
    RpcCall call =
        new RpcCallBuilder().from("1.2.3.4", "someHost.acme.com", 42).nfs3().noAuth().build();
    READDIR3args args = NfsV3Ops.readDir(dirHandle, 10); // 10 bytes - not enough for anything
    READDIR3res result = nfsServer.NFSPROC3_READDIR_3(call, args);

    Assert.assertEquals(nfsstat.NFSERR_TOOSMALL, result.status); // error response
  }
  @Test
  public void testReadDirWithNoResults() throws Exception {
    // vfs will return an empty list from the vfs for dir (technically legal)
    Mockito.when(vfs.list(Mockito.eq(new Inode(dirHandle))))
        .thenReturn(Collections.<DirectoryEntry>emptyList());

    // set up and execute the call
    RpcCall call =
        new RpcCallBuilder().from("1.2.3.4", "someHost.acme.com", 42).nfs3().noAuth().build();
    READDIR3args args = NfsV3Ops.readDir(dirHandle);
    READDIR3res result = nfsServer.NFSPROC3_READDIR_3(call, args);

    Assert.assertEquals(nfsstat.NFS_OK, result.status);
    Assert.assertNull(result.resok.reply.entries); // no entries
    Assert.assertTrue(result.resok.reply.eof); // eof
    AssertXdr.assertXdrEncodable(result);
  }
 public void init() throws IOException {
   Inode root = vfs.getRootInode();
   exportFile
       .getExports()
       .map(FsExport::getPath)
       .forEach(
           path -> {
             Splitter splitter = Splitter.on('/').omitEmptyStrings();
             Inode inode = root;
             for (String s : splitter.split(path)) {
               try {
                 inode = tryToCreateIfMissing(vfs, inode, s);
               } catch (IOException e) {
                 return;
               }
             }
           });
 }
 @Before
 public void setup() throws Exception {
   dirHandle = new FileHandle(0, 1, 0, new byte[] {0, 0, 0, 1}); // the dir we want to read
   dirInode = new Inode(dirHandle);
   dirStat = new Stat(); // the stat marking it as a dir
   //noinspection OctalInteger
   dirStat.setMode(Stat.S_IFDIR | 0755);
   dirStat.setMTime(System.currentTimeMillis());
   dirStat.setATime(System.currentTimeMillis());
   dirStat.setCTime(System.currentTimeMillis());
   dirStat.setGeneration(1);
   dirStat.setNlink(2);
   dirStat.setUid(1);
   dirStat.setGid(2);
   dirStat.setDev(1);
   dirStat.setFileid(1);
   dirStat.setSize(512);
   vfs = Mockito.mock(VirtualFileSystem.class); // the vfs serving it
   Mockito.when(vfs.getattr(Mockito.eq(dirInode))).thenReturn(dirStat);
   ExportFile exportFile =
       new ExportFile(this.getClass().getResource("simpleExports").toURI()); // same package as us
   nfsServer = new NfsServerV3(exportFile, vfs);
 }