TestFuseDFS.java Source code

Java tutorial

Introduction

Here is the source code for TestFuseDFS.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.hadoop.hdfs.*;
import junit.framework.TestCase;
import java.io.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.fs.permission.*;
import java.net.*;

/**
 * This class tests that the Fuse module for DFS can mount properly
 * and does a few simple commands:
 * mkdir
 * rmdir
 * ls
 * cat
 *
 * cp and touch are purposely not tested because they won't work with the current module
    
 *
 */
public class TestFuseDFS extends TestCase {

    /**
     * mount the fuse file system using assumed fuse module library installed in /usr/local/lib or somewhere else on your
     * pre-existing LD_LIBRARY_PATH
     *
     */

    static Process fuse_process;
    static String fuse_cmd;

    static private void mount(String mountpoint, URI dfs) throws IOException, InterruptedException {

        String cp = System.getProperty("java.class.path");
        Runtime r = Runtime.getRuntime();
        fuse_cmd = System.getProperty("build.test") + "/../fuse_dfs";
        String libhdfs = System.getProperty("build.test") + "/../../../libhdfs/";
        String arch = System.getProperty("os.arch");
        String jvm = System.getProperty("java.home") + "/lib/" + arch + "/server";
        String lp = System.getProperty("LD_LIBRARY_PATH") + ":" + "/usr/local/lib:" + libhdfs + ":" + jvm;
        System.err.println("LD_LIBRARY_PATH=" + lp);
        String cmd[] = { fuse_cmd, "dfs://" + dfs.getHost() + ":" + String.valueOf(dfs.getPort()), mountpoint,
                "-obig_writes", "-odebug", "-oentry_timeout=0.1", "-oattribute_timeout=0.1", "-ousetrash", "rw",
                "-oinitchecks", "-ordbuffer=32768" };
        final String[] envp = { "CLASSPATH=" + cp, "LD_LIBRARY_PATH=" + lp, "PATH=" + "/usr/bin:/bin"

        };

        // ensure the mount point is not currently mounted
        Process p = r.exec("fusermount -u " + mountpoint);
        p.waitFor();

        // clean up the mount point
        p = r.exec("rm -rf " + mountpoint);
        assertTrue(p.waitFor() == 0);

        // make the mount point if needed
        p = r.exec("mkdir -p " + mountpoint);
        assertTrue(p.waitFor() == 0);

        // mount fuse to the mount point
        fuse_process = r.exec(cmd, envp);

        // give DFS a chance to come up
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
        }
    }

    /**
     * unmounts fuse for before shutting down.
     */
    static private void umount(String mpoint) throws IOException, InterruptedException {
        Runtime r = Runtime.getRuntime();
        Process p = r.exec("fusermount -u " + mpoint);
        p.waitFor();
    }

    /**
     * Set things up - create mini dfs cluster and mount the fuse filesystem.
     */
    public TestFuseDFS() throws IOException, InterruptedException {
    }

    static private MiniDFSCluster cluster;
    static private DistributedFileSystem fileSys;
    final static private String mpoint;

    static {
        mpoint = System.getProperty("build.test") + "/mnt";
        System.runFinalizersOnExit(true);
        startStuff();
    }

    static public void startStuff() {
        try {
            Configuration conf = new Configuration();
            conf.setBoolean("dfs.permissions", false);
            cluster = new MiniDFSCluster(conf, 1, true, null);
            fileSys = (DistributedFileSystem) cluster.getFileSystem();
            assertTrue(fileSys.getFileStatus(new Path("/")).isDir());
            mount(mpoint, fileSys.getUri());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setUp() {
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testMkdir() throws IOException, InterruptedException, Exception {
        try {
            // First create a new directory with mkdirs
            Path path = new Path("/foo");
            Runtime r = Runtime.getRuntime();
            String cmd = "mkdir -p " + mpoint + path.toString();
            Process p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            // check it is there
            assertTrue(fileSys.getFileStatus(path).isDir());

            // check again through the shell
            String lsCmd = "ls " + mpoint + path.toString();
            p = r.exec(lsCmd);
            assertTrue(p.waitFor() == 0);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testWrites() throws IOException, InterruptedException {
        try {

            // write a hello file
            File file = new File(mpoint, "hello.txt");
            FileOutputStream f = new FileOutputStream(file);
            String s = "hello ";
            f.write(s.getBytes());
            s = "world";
            f.write(s.getBytes());
            f.flush();
            f.close();

            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }

            // check the file exists.
            Path myPath = new Path("/hello.txt");
            assertTrue(fileSys.exists(myPath));

            // check the data is ok
            FileInputStream fi = new FileInputStream(new File(mpoint, "hello.txt"));
            byte b[] = new byte[12];
            int length = fi.read(b, 0, 12);
            assertTrue(length > 0);
            String s2 = new String(b, 0, length);
            assertEquals("hello world", s2);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    /**
     * Test ls for dir already created in testMkdDir also tests bad ls
     */
    public void testLs() throws IOException, InterruptedException {
        try {
            // First create a new directory with mkdirs
            Runtime r = Runtime.getRuntime();

            // mkdir
            Process p = r.exec("mkdir -p " + mpoint + "/test/mkdirs");
            assertTrue(p.waitFor() == 0);

            // ls
            p = r.exec("ls " + mpoint + "/test/mkdirs");
            assertTrue(p.waitFor() == 0);

            // ls non-existant directory
            p = r.exec("ls " + mpoint + "/test/mkdirsNotThere");
            int res = p.waitFor();
            assertFalse(res == 0);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * Remove a dir using the shell and use filesys to see it no longer exists.
     */
    public void testRmdir() throws IOException, InterruptedException {
        try {
            // First create a new directory with mkdirs

            Runtime r = Runtime.getRuntime();
            Process p = r.exec("mkdir -p " + mpoint + "/test/rmdir");
            assertTrue(p.waitFor() == 0);

            Path myPath = new Path("/test/rmdir");
            assertTrue(fileSys.exists(myPath));

            // remove it
            p = r.exec("rmdir " + mpoint + "/test/rmdir");
            assertTrue(p.waitFor() == 0);

            // check it is not there
            assertFalse(fileSys.exists(myPath));

            Path trashPath = new Path("/user/root/.Trash/Current/test/rmdir");
            assertTrue(fileSys.exists(trashPath));

            // make it again to test trashing same thing twice
            p = r.exec("mkdir -p " + mpoint + "/test/rmdir");
            assertTrue(p.waitFor() == 0);

            assertTrue(fileSys.exists(myPath));

            // remove it
            p = r.exec("rmdir " + mpoint + "/test/rmdir");
            assertTrue(p.waitFor() == 0);

            // check it is not there
            assertFalse(fileSys.exists(myPath));

            trashPath = new Path("/user/root/.Trash/Current/test/rmdir.1");
            assertTrue(fileSys.exists(trashPath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testDF() throws IOException, InterruptedException, Exception {
        try {
            // First create a new directory with mkdirs
            Path path = new Path("/foo");
            Runtime r = Runtime.getRuntime();
            String cmd = "mkdir -p " + mpoint + path.toString();
            Process p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);
            File f = new File(mpoint + "/foo");

            DistributedFileSystem.DiskStatus d = fileSys.getDiskStatus();

            long fileUsedBlocks = (f.getTotalSpace() - f.getFreeSpace()) / (64 * 1024 * 1024);
            long dfsUsedBlocks = (long) Math.ceil((double) d.getDfsUsed() / (64 * 1024 * 1024));

            assertTrue(fileUsedBlocks == dfsUsedBlocks);
            assertTrue(d.getCapacity() == f.getTotalSpace());

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testChown() throws IOException, InterruptedException, Exception {
        try {
            // First create a new directory with mkdirs
            Path path = new Path("/foo");
            Runtime r = Runtime.getRuntime();
            String cmd = "mkdir -p " + mpoint + path.toString();
            Process p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            // check it is there
            assertTrue(fileSys.getFileStatus(path).isDir());

            FileStatus foo = fileSys.getFileStatus(path);
            System.err.println("DEBUG:owner=" + foo.getOwner());

            cmd = "chown nobody " + mpoint + path.toString();
            p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            //      cmd = "chgrp nobody " + mpoint + path.toString();
            //      p = r.exec(cmd);
            //      assertTrue(p.waitFor() == 0);

            foo = fileSys.getFileStatus(path);

            System.err.println("DEBUG:owner=" + foo.getOwner());

            assertTrue(foo.getOwner().equals("nobody"));
            assertTrue(foo.getGroup().equals("nobody"));

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testChmod() throws IOException, InterruptedException, Exception {
        try {
            // First create a new directory with mkdirs
            Path path = new Path("/foo");
            Runtime r = Runtime.getRuntime();
            String cmd = "mkdir -p " + mpoint + path.toString();
            Process p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            // check it is there
            assertTrue(fileSys.getFileStatus(path).isDir());

            cmd = "chmod 777 " + mpoint + path.toString();
            p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            FileStatus foo = fileSys.getFileStatus(path);
            FsPermission perm = foo.getPermission();
            assertTrue(perm.toShort() == 0777);

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * use shell to create a dir and then use filesys to see it exists.
     */
    public void testUtimes() throws IOException, InterruptedException, Exception {
        try {
            // First create a new directory with mkdirs
            Path path = new Path("/utimetest");
            Runtime r = Runtime.getRuntime();
            String cmd = "touch " + mpoint + path.toString();
            Process p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            // check it is there
            assertTrue(fileSys.exists(path));

            FileStatus foo = fileSys.getFileStatus(path);
            long oldTime = foo.getModificationTime();
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }

            cmd = "touch " + mpoint + path.toString();
            p = r.exec(cmd);
            assertTrue(p.waitFor() == 0);

            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
            foo = fileSys.getFileStatus(path);
            long newTime = foo.getModificationTime();

            assertTrue(newTime > oldTime);

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
        }
    }

    /**
     *
     * Test dfs_read on a file size that will trigger multiple internal reads. 
     * First, just check raw size reading is ok and then check with smaller reads
     * including checking the validity of the data read.
     *
     */
    public void testReads() throws IOException, InterruptedException {
        try {
            // First create a new directory with mkdirs
            Runtime r = Runtime.getRuntime();
            Process p;

            // create the file
            Path myPath = new Path("/test/hello.reads");
            FSDataOutputStream s = fileSys.create(myPath);
            String hello = "hello world!";
            int written = 0;
            int mycount = 0;
            while (written < 1024 * 9) {
                s.writeUTF(hello);
                s.writeInt(mycount++);
                written += hello.length() + 4;
            }
            s.close();

            // check it exists
            assertTrue(fileSys.exists(myPath));
            FileStatus foo = fileSys.getFileStatus(myPath);
            assertTrue(foo.getLen() >= 9 * 1024);

            {
                // cat the file
                DataInputStream is = new DataInputStream(new FileInputStream(mpoint + "/test/hello.reads"));
                byte buf[] = new byte[4096];
                // test reading 0 length
                assertTrue(is.read(buf, 0, 0) == 0);

                // test real reads
                assertTrue(is.read(buf, 0, 1024) == 1024);
                assertTrue(is.read(buf, 0, 4096) == 4096);
                assertTrue(is.read(buf, 0, 4096) == 4096);
                is.close();
            }

            {
                DataInputStream is = new DataInputStream(new FileInputStream(mpoint + "/test/hello.reads"));
                int read = 0;
                int counter = 0;
                try {
                    while (true) {
                        String s2 = DataInputStream.readUTF(is);
                        int s3 = is.readInt();
                        assertTrue(s2.equals(hello));
                        assertTrue(s3 == counter++);
                        read += hello.length() + 4;
                    }
                } catch (EOFException e) {
                    assertTrue(read >= 9 * 1024);
                }
            }

            // check reading an empty file for EOF
            {
                // create the file
                myPath = new Path("/test/hello.reads2");
                s = fileSys.create(myPath);
                s.close();

                FSDataInputStream fs = fileSys.open(myPath);
                assertEquals(-1, fs.read());

                FileInputStream f = new FileInputStream(mpoint + "/test/hello.reads2");
                assertEquals(-1, f.read());
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    /**
     * Use filesys to create the hello world! file and then cat it and see its contents are correct.
     */
    public void testCat() throws IOException, InterruptedException {
        try {
            // First create a new directory with mkdirs
            Runtime r = Runtime.getRuntime();
            Process p = r.exec("rm -rf " + mpoint + "/test/hello");
            assertTrue(p.waitFor() == 0);

            // create the file
            Path myPath = new Path("/test/hello");
            FSDataOutputStream s = fileSys.create(myPath);
            String hello = "hello world!";
            s.writeUTF(hello);
            s.writeInt(1033);
            s.close();

            // check it exists
            assertTrue(fileSys.exists(myPath));

            // cat the file
            DataInputStream is = new DataInputStream(new FileInputStream(mpoint + "/test/hello"));
            String s2 = DataInputStream.readUTF(is);
            int s3 = is.readInt();
            assertTrue(s2.equals(hello));
            assertTrue(s3 == 1033);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    /**
     * Use filesys to create the hello world! file and then cat it and see its contents are correct.
     */
    public void testAppends() throws IOException, InterruptedException {
        try {
            // First create a new directory with mkdirs
            Runtime r = Runtime.getRuntime();

            {
                FileOutputStream os = new FileOutputStream(mpoint + "/appends");
                String hello = "hello";
                os.write(hello.getBytes());
                os.flush();
                os.close();
            }

            // check it exists
            Path myPath = new Path("/appends");
            assertTrue(fileSys.exists(myPath));

            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }

            FileStatus foo = fileSys.getFileStatus(myPath);

            File f = new File(mpoint + "/appends");
            assertTrue(f.length() > 0);

            {
                FileOutputStream os = new FileOutputStream(mpoint + "/appends", true);
                String hello = " world!";
                os.write(hello.getBytes());
                os.flush();
                os.close();
            }

            // cat the file
            FileInputStream is = new FileInputStream(mpoint + "/appends");
            byte b[] = new byte[1024];
            int len = is.read(b);
            assertTrue(len > 0);
            String s2 = new String(b, 0, len);
            assertTrue(s2.equals("hello world!"));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    public void testDone() throws IOException {
        close();
    }

    /**
     * Unmount and close
     */
    protected void tearDown() throws Exception {
    }

    /**
     * Unmount and close
     */
    protected void finalize() throws Throwable {
        close();
    }

    public void close() {
        try {
            int length;

            // print out the fuse debug output
            {
                do {
                    InputStream i = fuse_process.getInputStream();
                    byte b[] = new byte[i.available()];
                    length = i.read(b);
                    System.err.println("read x bytes: " + length);
                    System.err.write(b, 0, b.length);
                } while (length > 0);
            }

            do {
                InputStream i = fuse_process.getErrorStream();
                byte b[] = new byte[i.available()];
                length = i.read(b);
                System.err.println("read x bytes: " + length);
                System.err.write(b, 0, b.length);
            } while (length > 0);

            umount(mpoint);

            fuse_process.destroy();
            fuse_process = null;
            if (fileSys != null) {
                fileSys.close();
                fileSys = null;
            }
            if (cluster != null) {
                cluster.shutdown();
                cluster = null;
            }
        } catch (Exception e) {
        }
    }
};