AS_IF([test -r "$jnih"], [
EXTRA_JDK_INC_DIR=`dirname $jnih`])])
+ # cephfs_java_test only makes sense if java is already turned on
+ # setup CLASSPATH for Debian default junit4.jar package
+ AS_IF([test "x$with_debug" = "xyes"], [
+ dir='/usr/share/java'
+ junit4_jar=`find $dir -name junit4.jar | head -n 1`
+ AS_IF([test -r "$junit4_jar"], [
+ EXTRA_CLASSPATH_JAR=`dirname $junit4_jar`/junit4.jar
+ AC_SUBST(EXTRA_CLASSPATH_JAR)])])
+
# Check for Java programs: javac, javah, jar
PATH_save=$PATH
PATH="$PATH:$EXTRA_JDK_BIN_DIR"
CEPH_PROXY=java/com/ceph/fs/CephMount.class
$(CEPH_PROXY): $(JAVA_SRC)
- export CLASSPATH=java/ ;
+ export CLASSPATH=java/ ; \
$(JAVAC) -source 1.5 -target 1.5 java/com/ceph/fs/*.java
$(JAVA_H): $(CEPH_PROXY)
$(JAVAH) -jni -o $@ com.ceph.fs.CephMount
libcephfs.jar: $(CEPH_PROXY)
- $(JAR) cf $@ $(JAVA_CLASSES:%=-C java %) # $(ESCAPED_JAVA_CLASSES:%=-C java %)
+ $(JAR) cf $@ $(JAVA_CLASSES:%=-C java %)
javadir = $(libdir)
java_DATA = libcephfs.jar
+CLEANFILES = -rf java/com/ceph/fs/*.class $(JAVA_H) libcephfs.jar
+
BUILT_SOURCES = $(JAVA_H)
-CLEANFILES = -rf java/com/ceph/fs/*.class $(JAVA_H) libcephfs.jar
+# build the tests if *both* --enable-cephfs-java and --with-debug were specifed
+if WITH_DEBUG
+
+JAVA_TEST_CLASSES = $(JAVA_TEST_SRC:test/%.java=%.class)
+
+JAVA_TEST_SRC = \
+ test/com/ceph/fs/CephDoubleMountTest.java \
+ test/com/ceph/fs/CephMountCreateTest.java \
+ test/com/ceph/fs/CephMountTest.java \
+ test/com/ceph/fs/CephUnmountedTest.java
+
+EXTRA_DIST += $(JAVA_TEST_SRC)
+
+java_test_src: $(JAVA_TEST_SRC) $(CEPH_PROXY)
+ export CLASSPATH=$(CLASSPATH):$(EXTRA_CLASSPATH_JAR):java/:test/ ; \
+ $(JAVAC) -source 1.5 -target 1.5 test/com/ceph/fs/*.java
+
+libcephfs-test.jar: java_test_src
+ $(JAR) cf $@ $(JAVA_TEST_CLASSES:%=-C test %)
+
+java_DATA += libcephfs-test.jar
-endif
+CLEANFILES += test/com/ceph/fs/*.class libcephfs-test.jar
+endif # WITH_DEBUG
+endif #ENABLE_CEPHFS_JAVA
Testing
-------
-These tests assume a live cluster, and depend on JUnit and Ant.
+These tests assume a live cluster, and depend on JUnit4 and Ant.
-To run the tests make sure that the JUnit JAR is available in the lib/
-directory. For example:
+To run the tests make sure that the JUnit4 JAR is installed.
+Install it via a package manager or like this:
$ mkdir lib
$ cd lib
- $ curl -O https://github.com/downloads/KentBeck/junit/junit-4.8.2.jar
+ $ wget https://github.com/downloads/KentBeck/junit/junit-4.8.2.jar
+
+And then add the jar to the CLASSPATH.
+*NOTE* for now, configure is only looking for this jar in the
+/usr/share/java directory as junit4.jar. So create a softlink
+to that location from wherever the junit jar is installed.
Ant is used to run the unit test (apt-get install ant). For example:
$ cd src/
$ ./vstart -d -n --localhost
$ cd java
- $ CEPHFS_CONF=../ceph.conf ant test
+ $ CEPHFS_CONF=../ceph.conf CLASSPATH=/usr/share/java/junit4.jar ant test
1. The tests depend on the compiled wrappers. If the wrappers are installed as
part of a package (e.g. Debian package) then this should 'just work'. Ant will
-also look in the current directory for 'libcephfs.jar' and in ../.libs for the
+also look in the current directory for 'libcephfs.jar' and 'libcephfs-test.jar';
+and in ../.libs for the
JNI library. If all else fails, set the environment variables CEPHFS_JAR, and
CEPHFS_JNI_LIB accordingly.
<property name="src.dir" location="java" />
<property name="doc.dir" location="doc" />
- <property name="lib.dir" location="lib" />
- <property name="test.src.dir" location="test" />
- <property name="test.build.dir" location="test_build" />
+ <property name="test.dir" location="test" />
<property environment="env"/>
<target name="clean">
<delete dir="${doc.dir}" />
- <delete dir="${test.build.dir}" />
+ <delete>
+ <fileset dir="${test.dir}" includes="**/*.class" />
+ </delete>
</target>
<target name="makedir">
<mkdir dir="${doc.dir}" />
- <mkdir dir="${test.build.dir}" />
</target>
<target name="docs" depends="makedir">
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${doc.dir}">
<fileset dir="${src.dir}">
+ <include name="**/*.java" />
+ </fileset>
+ <fileset dir="${test.dir}">
<include name="**/*.java" />
</fileset>
</javadoc>
</target>
- <target name="compile-tests" depends="makedir">
- <javac srcdir="${test.src.dir}" destdir="${test.build.dir}"
- includeantruntime="false" source="1.5" target="1.5">
+ <target name="compile-tests-jar">
+ <javac srcdir="${test.dir}" destdir="${test.dir}"
+ includeantruntime="false" source="1.5" target="1.5">
<classpath>
<pathelement location="${env.CEPHFS_JAR}"/>
<pathelement location="libcephfs.jar"/>
- <fileset dir="${lib.dir}">
- <include name="**/*.jar"/>
- </fileset>
+ <pathelement location="${env.CLASSPATH}" />
</classpath>
</javac>
+ <jar basedir="test" destfile="./libcephfs-test.jar">
+ </jar>
</target>
- <target name="test" depends="compile-tests">
+ <target name="test-compat" depends="compile-tests-jar,test">
+ </target>
+
+ <target name="test">
<junit printsummary="yes" haltonfailure="yes" showoutput="yes">
<sysproperty key="java.library.path" path="${env.CEPHFS_JNI_LIB}:../.libs/"/>
<sysproperty key="CEPH_CONF_FILE" path="${env.CEPHFS_CONF}"/>
<classpath>
- <fileset dir="${lib.dir}">
- <include name="**/*.jar"/>
- </fileset>
<pathelement location="${env.CEPHFS_JAR}"/>
<pathelement location="libcephfs.jar"/>
- <pathelement path="${test.build.dir}"/>
- <pathelement path="${test.src.dir}"/>
+ <pathelement location="libcephfs-test.jar"/>
</classpath>
<formatter type="plain"/>
<batchtest fork="yes">
- <fileset dir="${test.src.dir}">
- <include name="**/*Test.java"/>
- </fileset>
+ <zipfileset src="libcephfs-test.jar">
+ <include name="**/*Test.class"/>
+ </zipfileset>
</batchtest>
</junit>
</target>
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.UUID;
-import org.junit.*;
-import static org.junit.Assert.*;
-
-import com.ceph.fs.*;
-
-public class CephDoubleMountTest {
-
- @Test(expected=CephAlreadyMountedException.class)
- public void test_double_mount() throws Exception {
- CephMount mount = new CephMount("admin");
- String conf_file = System.getProperty("CEPH_CONF_FILE");
- if (conf_file != null)
- mount.conf_read_file(conf_file);
- mount.mount(null);
- try {
- mount.mount(null);
- } finally {
- mount.unmount();
- }
- }
-
-}
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-import java.io.FileNotFoundException;
-import org.junit.*;
-import java.util.UUID;
-import static org.junit.Assert.*;
-
-import com.ceph.fs.*;
-
-/*
- * This tests the mount root dir functionality. It creates an empty
- * directory in the real root, then it re-mounts the file system
- * with the empty directory specified as the root. Assertions are
- * that the "/" in the normal mount is non-empty, and that "/" is
- * empty in the mount with the empty directory as the root.
- */
-public class CephMountCreateTest {
-
- private static String conf_file;
-
- @BeforeClass
- public static void class_setup() throws Exception {
- conf_file = System.getProperty("CEPH_CONF_FILE");
- }
-
- private CephMount setupMount(String root) throws Exception {
- CephMount mount = new CephMount("admin");
- if (conf_file != null)
- mount.conf_read_file(conf_file);
- mount.mount(root);
- return mount;
- }
-
- @Test
- public void test_CephMountCreate() throws Exception {
- CephMount mount;
- boolean found;
-
- String dir = "libcephfs_junit_" + UUID.randomUUID();
-
- /* root dir has more than one dir */
- mount = setupMount("/");
-
- try {
- mount.rmdir("/" + dir);
- } catch (FileNotFoundException e) {}
- mount.mkdirs("/" + dir, 777);
- String[] subdirs = mount.listdir("/");
- found = false;
- for (String d : subdirs) {
- if (d.compareTo(dir) == 0)
- found = true;
- }
- assertTrue(found);
- mount.unmount();
-
- /* changing root to empty dir */
- mount = setupMount("/" + dir);
-
- subdirs = mount.listdir("/");
- found = false;
- for (String d : subdirs) {
- found = true;
- }
- assertFalse(found);
- mount.unmount();
-
- /* cleanup */
- mount = setupMount("/");
- mount.rmdir("/" + dir);
- mount.unmount();
- }
-}
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.UUID;
-import org.junit.*;
-import static org.junit.Assert.*;
-
-import com.ceph.fs.*;
-
-/*
- * Coverage
- * - Everything is covered in at least success cases.
- * - link/symlink/readlink/l[set,get,remove]xattr are not working
- */
-
-public class CephMountTest {
-
- private static CephMount mount;
- private static String basedir = null;
-
- @BeforeClass
- public static void setup() throws Exception {
- mount = new CephMount("admin");
-
- String conf_file = System.getProperty("CEPH_CONF_FILE");
- if (conf_file != null)
- mount.conf_read_file(conf_file);
-
- mount.mount(null);
-
- basedir = "/libcephfs_junit_" + UUID.randomUUID();
- mount.mkdir(basedir, 0777);
- }
-
- @AfterClass
- public static void destroy() throws Exception {
- String[] list = mount.listdir(basedir);
- for (String l : list)
- System.out.println(l);
- mount.rmdir(basedir);
- mount.unmount();
- }
-
- /*
- * Helper function to construct a unique path.
- */
- public String makePath() {
- String path = basedir + "/" + UUID.randomUUID();
- return path;
- }
-
- /*
- * Helper function to create a file with the given path and size. The file
- * is filled with size bytes and the file descriptor is returned.
- */
- public int createFile(String path, int size) throws Exception {
- int fd = mount.open(path, CephMount.O_RDWR|CephMount.O_CREAT, 0600);
- byte[] buf = new byte[4096];
- int left = size;
- while (left > 0) {
- size = Math.min(buf.length, left);
- long ret = mount.write(fd, buf, size, -1);
- left -= ret;
- }
- return fd;
- }
-
- /*
- * Helper function to create a unique file and fill it with size bytes. The
- * file descriptor is returned.
- */
- public int createFile(int size) throws Exception {
- return createFile(makePath(), size);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_mount_dne() throws Exception {
- CephMount mount2 = new CephMount("admin");
- String conf_file = System.getProperty("CEPH_CONF_FILE");
- if (conf_file != null)
- mount2.conf_read_file(conf_file);
- mount2.mount("/wlfkjwlekfjwlejfwe");
- mount2.unmount();
- }
-
- /*
- * Test loading of conf file that doesn't exist.
- *
- * FIXME:
- * Ceph returns -ENOSYS rather than -ENOENT. Correct?
- */
- //@Test(expected=FileNotFoundException.class)
- @Test
- public void test_conf_read_file_dne() throws Exception {
- //mount.conf_read_file("/this_file_does_not_exist");
- }
-
- /*
- * Test loading of conf file that isn't valid
- *
- * FIXME: implement
- */
- @Test
- public void test_conf_read_file_invalid() throws Exception {
- }
-
- @Test(expected=NullPointerException.class)
- public void test_conf_read_file_null() throws Exception {
- mount.conf_read_file(null);
- }
-
- /*
- * conf_set/conf_get
- */
-
- @Test(expected=NullPointerException.class)
- public void test_conf_set_null_opt() throws Exception {
- mount.conf_set(null, "value");
- }
-
- @Test(expected=NullPointerException.class)
- public void test_conf_set_null_val() throws Exception {
- mount.conf_set("option", null);
- }
-
- @Test(expected=NullPointerException.class)
- public void test_conf_get_null_opt() throws Exception {
- mount.conf_get(null);
- }
-
- @Test
- public void test_conf() throws Exception {
- String opt = "log to stderr";
- String val1, val2, val3;
-
- /* get the current value */
- val1 = mount.conf_get(opt);
-
- /*
- * flip the value. this may make some debug information be dumped to the
- * console when the value becomes true. TODO: find a better config option
- * to toggle.
- */
- if (val1.compareTo("true") == 0)
- val2 = "false";
- else
- val2 = "true";
- mount.conf_set(opt, val2);
-
- /* verify the change */
- val3 = mount.conf_get(opt);
- assertTrue(val3.compareTo(val2) == 0);
-
- /* reset to original value */
- mount.conf_set(opt, val1);
- val3 = mount.conf_get(opt);
- assertTrue(val3.compareTo(val1) == 0);
- }
-
- /*
- * statfs
- */
-
- @Test
- public void test_statfs() throws Exception {
- CephStatVFS st1 = new CephStatVFS();
- mount.statfs("/", st1);
-
- /*
- * FIXME: a better test here is to see if changes to the file system are
- * reflected through statfs (e.g. increasing number of files). However, it
- * appears that the updates aren't immediately visible.
- */
- assertTrue(st1.bsize > 0);
- assertTrue(st1.frsize > 0);
- assertTrue(st1.blocks > 0);
- assertTrue(st1.bavail > 0);
- assertTrue(st1.namemax > 0);
- }
-
- /*
- * getcwd/chdir
- */
-
- @Test
- public void test_getcwd() throws Exception {
- mount.chdir(basedir);
- String cwd = mount.getcwd();
- assertTrue(cwd.compareTo(basedir) == 0);
-
- /* Make sure to reset cwd to root */
- mount.chdir("/");
- cwd = mount.getcwd();
- assertTrue(cwd.compareTo("/") == 0);
- }
-
- @Test(expected=NullPointerException.class)
- public void test_chdir_null() throws Exception {
- mount.chdir(null);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_chdir_dne() throws Exception {
- mount.chdir("/this/path/does/not/exist/");
- }
-
- /*
- * FIXME: this test should throw an error (but does not)?
- */
- //@Test(expected=IOException.class)
- @Test
- public void test_chdir_not_dir() throws Exception {
- String path = makePath();
- int fd = createFile(path, 1);
- mount.close(fd);
- //mount.chdir(path); shouldn't be able to do this?
- mount.unlink(path);
-
- /*
- * Switch back. Other tests seem to be sensitive to the current directory
- * being something other than "/". This shouldn't happen once this tests
- * passes and the call to chdir fails anyway.
- */
- mount.chdir("/");
- }
-
- /*
- * listdir
- */
-
- @Test(expected=NullPointerException.class)
- public void test_listdir_null() throws Exception {
- mount.listdir(null);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_listdir_dne() throws Exception {
- mount.listdir("/this/path/does/not/exist/");
- }
-
- @Test(expected=IOException.class)
- public void test_listdir_not_dir() throws Exception {
- String path = makePath();
- int fd = createFile(path, 1);
- mount.close(fd);
- try {
- mount.listdir(path);
- } finally {
- mount.unlink(path);
- }
- }
-
- @Test
- public void test_listdir() throws Exception {
- String dir = makePath();
- mount.mkdir(dir, 0777);
- /* test that new directory is empty */
- String[] list = mount.listdir(dir);
- assertTrue(list.length == 0);
- /* test that new directories are seen */
- for (int i = 0; i < 3; i++)
- mount.mkdir(dir + "/" + i, 777);
- list = mount.listdir(dir);
- assertTrue(list.length == 3);
- /* test that more new directories are seen */
- for (int i = 0; i < 30; i++)
- mount.mkdir(dir + "/x" + i, 777);
- list = mount.listdir(dir);
- assertTrue(list.length == 33);
-
- /* remove */
- for (int i = 0; i < 30; i++)
- mount.rmdir(dir + "/x" + i);
- for (int i = 0; i < 3; i++)
- mount.rmdir(dir + "/" + i);
- mount.rmdir(dir);
- }
-
- /*
- * Missing
- *
- * ceph_link
- * ceph_unlink
- */
-
- /*
- * rename
- */
-
- @Test(expected=NullPointerException.class)
- public void test_rename_null_from() throws Exception {
- mount.rename(null, "to");
- }
-
- @Test(expected=NullPointerException.class)
- public void test_rename_null_to() throws Exception {
- mount.rename("from", null);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_rename_dne() throws Exception {
- mount.rename("/this/doesnt/exist", "/this/neither");
- }
-
- @Test
- public void test_rename() throws Exception {
- /* create a file */
- String path = makePath();
- int fd = createFile(path, 1);
- mount.close(fd);
-
- /* move it to a new name */
- String newpath = makePath();
- mount.rename(path, newpath);
-
- /* verfiy the sizes are the same */
- CephStat st = new CephStat();
- mount.lstat(newpath, st);
- assertTrue(st.size == 1);
-
- /* remove the file */
- mount.unlink(newpath);
- }
-
- /*
- * mkdir/mkdirs/rmdir
- */
-
- @Test(expected=IOException.class)
- public void test_mkdir_exists() throws Exception {
- String path = makePath();
- mount.mkdir(path, 0777);
- try {
- mount.mkdir(path, 0777);
- } finally {
- mount.rmdir(path);
- }
- }
-
- @Test(expected=IOException.class)
- public void test_mkdirs_exists() throws Exception {
- String path = makePath();
- mount.mkdirs(path, 0777);
- try {
- mount.mkdirs(path, 0777);
- } finally {
- mount.rmdir(path);
- }
- }
-
- @Test
- public void test_mkdir() throws Exception {
- String path = makePath();
- mount.mkdir(path, 0777);
- CephStat st = new CephStat();
- mount.lstat(path, st);
- assertTrue(st.isDir());
- mount.rmdir(path);
- }
-
- @Test
- public void test_mkdirs() throws Exception {
- String path = makePath();
- mount.mkdirs(path + "/x/y", 0777);
-
- CephStat st = new CephStat();
- mount.lstat(path, st);
- assertTrue(st.isDir());
-
- mount.lstat(path + "/x", st);
- assertTrue(st.isDir());
-
- mount.lstat(path + "/x/y", st);
- assertTrue(st.isDir());
-
- mount.rmdir(path + "/x/y");
- mount.rmdir(path + "/x");
- mount.rmdir(path);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_rmdir() throws Exception {
- /* make a new directory */
- String path = makePath();
- mount.mkdir(path, 0777);
- CephStat st = new CephStat();
- mount.lstat(path, st);
- assertTrue(st.isDir());
- /* remove it */
- mount.rmdir(path);
- /* should not exist now */
- mount.lstat(path, st);
- }
-
- /*
- * Missing
- *
- * readlink
- * symlink
- */
-
- /*
- * lstat
- */
-
- @Test(expected=NullPointerException.class)
- public void test_lstat_null_path() throws Exception {
- mount.lstat(null, new CephStat());
- }
-
- @Test(expected=NullPointerException.class)
- public void test_lstat_null_stat() throws Exception {
- mount.lstat("/path", null);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_lstat_null_dne() throws Exception {
- mount.lstat("/path/does/not/exist", new CephStat());
- }
-
- /*
- * test_stat covers lstat and fstat
- */
-
- @Test
- public void test_stat() throws Exception {
- /* create a new file */
- String path = makePath();
- int size = 12345;
- int fd = createFile(path, size);
- mount.close(fd);
-
- /* test some basic info about the new file */
- CephStat orig_st = new CephStat();
- mount.lstat(path, orig_st);
- assertTrue(orig_st.size == size);
- assertTrue(orig_st.blksize > 0);
- assertTrue(orig_st.blocks > 0);
-
- /* now try fstat */
- CephStat other_st = new CephStat();
- fd = mount.open(path, CephMount.O_RDWR, 0);
- mount.fstat(fd, other_st);
- mount.close(fd);
-
- mount.unlink(path);
-
- assertTrue(orig_st.mode == other_st.mode);
- assertTrue(orig_st.uid == other_st.uid);
- assertTrue(orig_st.gid == other_st.gid);
- assertTrue(orig_st.size == other_st.size);
- assertTrue(orig_st.blksize == other_st.blksize);
- assertTrue(orig_st.blocks == other_st.blocks);
- }
-
- /*
- * setattr
- */
-
- @Test(expected=NullPointerException.class)
- public void test_setattr_null_path() throws Exception {
- mount.setattr(null, new CephStat(), 0);
- }
-
- @Test(expected=NullPointerException.class)
- public void test_setattr_null_stat() throws Exception {
- mount.setattr("/path", null, 0);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_setattr_dne() throws Exception {
- mount.setattr("/path/does/not/exist", new CephStat(), 0);
- }
-
- @Test
- public void test_setattr() throws Exception {
- /* create a file */
- String path = makePath();
- int fd = createFile(path, 1);
- mount.close(fd);
-
- CephStat st1 = new CephStat();
- mount.lstat(path, st1);
-
- st1.uid += 1;
- st1.gid += 1;
- mount.setattr(path, st1, mount.SETATTR_UID|mount.SETATTR_GID);
-
- CephStat st2 = new CephStat();
- mount.lstat(path, st2);
-
- assertTrue(st2.uid == st1.uid);
- assertTrue(st2.gid == st1.gid);
-
- /* remove the file */
- mount.unlink(path);
- }
-
- /*
- * chmod
- */
-
- @Test(expected=NullPointerException.class)
- public void test_chmod_null_path() throws Exception {
- mount.chmod(null, 0);
- }
-
- @Test(expected=FileNotFoundException.class)
- public void test_chmod_dne() throws Exception {
- mount.chmod("/path/does/not/exist", 0);
- }
-
- @Test
- public void test_chmod() throws Exception {
- /* create a file */
- String path = makePath();
- int fd = createFile(path, 1);
- mount.close(fd);
-
- CephStat st = new CephStat();
- mount.lstat(path, st);
-
- /* flip a bit */
- int mode = st.mode;
- if ((mode & 1) != 0)
- mode -= 1;
- else
- mode += 1;
-
- mount.chmod(path, mode);
- CephStat st2 = new CephStat();
- mount.lstat(path, st2);
- assertTrue(st2.mode == mode);
-
- mount.unlink(path);
- }
-
- /*
- * truncate
- */
-
- @Test(expected=FileNotFoundException.class)
- public void test_truncate_dne() throws Exception {
- mount.truncate("/path/does/not/exist", 0);
- }
-
- @Test(expected=NullPointerException.class)
- public void test_truncate_null_path() throws Exception {
- mount.truncate(null, 0);
- }
-
- @Test
- public void test_truncate() throws Exception {
- // make file
- String path = makePath();
- int orig_size = 1398331;
- int fd = createFile(path, orig_size);
- mount.close(fd);
-
- // check file size
- CephStat st = new CephStat();
- mount.lstat(path, st);
- assertTrue(st.size == orig_size);
-
- // truncate and check
- int crop_size = 333333;
- mount.truncate(path, crop_size);
- mount.lstat(path, st);
- assertTrue(st.size == crop_size);
-
- // check after re-open
- fd = mount.open(path, CephMount.O_RDWR, 0);
- mount.fstat(fd, st);
- assertTrue(st.size == crop_size);
- mount.close(fd);
-
- mount.unlink(path);
- }
-
- /*
- * open/close
- */
-
- @Test(expected=FileNotFoundException.class)
- public void test_open_dne() throws Exception {
- mount.open("/path/doesnt/exist", 0, 0);
- }
-
- /*
- * lseek
- */
-
- @Test
- public void test_lseek() throws Exception {
- /* create a new file */
- String path = makePath();
- int size = 12345;
- int fd = createFile(path, size);
- mount.close(fd);
-
- /* open and check size */
- fd = mount.open(path, CephMount.O_RDWR, 0);
- long end = mount.lseek(fd, 0, CephMount.SEEK_END);
- mount.close(fd);
-
- mount.unlink(path);
-
- assertTrue(size == (int)end);
- }
-
- /*
- * read/write
- */
-
- @Test
- public void test_read() throws Exception {
- String path = makePath();
- int fd = createFile(path, 1500);
- byte[] buf = new byte[1500];
- long ret = mount.read(fd, buf, 1500, 0);
- assertTrue(ret == 1500);
- mount.unlink(path);
- }
-
- /*
- * ftruncate
- */
-
- @Test
- public void test_ftruncate() throws Exception {
- // make file
- String path = makePath();
- int orig_size = 1398331;
- int fd = createFile(path, orig_size);
-
- // check file size
- CephStat st = new CephStat();
- mount.fstat(fd, st);
- assertTrue(st.size == orig_size);
-
- // truncate and check
- int crop_size = 333333;
- mount.ftruncate(fd, crop_size);
- mount.fstat(fd, st);
- assertTrue(st.size == crop_size);
- mount.close(fd);
-
- // check after re-open
- fd = mount.open(path, CephMount.O_RDWR, 0);
- mount.fstat(fd, st);
- assertTrue(st.size == crop_size);
- mount.close(fd);
-
- mount.unlink(path);
- }
-
- /*
- * fsync
- */
-
- @Test
- public void test_fsync() throws Exception {
- String path = makePath();
- int fd = createFile(path, 123);
- mount.fsync(fd, false);
- mount.fsync(fd, true);
- mount.close(fd);
- mount.unlink(path);
- }
-
- /*
- * fstat
- *
- * success case is handled in test_stat along with lstat.
- */
-
- /*
- * sync_fs
- */
-
- @Test
- public void test_sync_fs() throws Exception {
- mount.sync_fs();
- }
-
- /*
- * get/set/list/remove xattr
- */
-
- @Test
- public void test_xattr() throws Exception {
- /* make file */
- String path = makePath();
- int fd = createFile(path, 123);
- mount.close(fd);
-
- /* make xattrs */
- String val1 = "This is a new xattr";
- String val2 = "This is a different xattr";
- byte[] buf1 = val1.getBytes();
- byte[] buf2 = val2.getBytes();
- mount.setxattr(path, "attr1", buf1, buf1.length, mount.XATTR_CREATE);
- mount.setxattr(path, "attr2", buf2, buf2.length, mount.XATTR_CREATE);
-
- /* list xattrs */
- String[] xattrs = mount.listxattr(path);
- assertTrue(xattrs.length == 2);
- int found = 0;
- for (String xattr : xattrs) {
- if (xattr.compareTo("attr1") == 0) {
- found++;
- continue;
- }
- if (xattr.compareTo("attr2") == 0) {
- found++;
- continue;
- }
- System.out.println("found unwanted xattr: " + xattr);
- }
- assertTrue(found == 2);
-
- /* get first xattr by looking up length */
- long attr1_len = mount.getxattr(path, "attr1", null);
- byte[] out = new byte[(int)attr1_len];
- mount.getxattr(path, "attr1", out);
- String outStr = new String(out);
- assertTrue(outStr.compareTo(val1) == 0);
-
- /* get second xattr assuming original length */
- out = new byte[buf2.length];
- mount.getxattr(path, "attr2", out);
- outStr = new String(out);
- assertTrue(outStr.compareTo(val2) == 0);
-
- /* remove the attributes */
- /* FIXME: the MDS returns ENODATA for removexattr */
- /*
- mount.removexattr(path, "attr1");
- xattrs = mount.listxattr(path);
- assertTrue(xattrs.length == 1);
- mount.removexattr(path, "attr2");
- xattrs = mount.listxattr(path);
- assertTrue(xattrs.length == 0);
- */
-
- mount.unlink(path);
- }
-
- /*
- * get/set/list/remove symlink xattr
- *
- * Currently not working. Code is the same as for regular xattrs, so there
- * might be a deeper issue.
- */
-
- @Test
- public void test_get_stripe_unit() throws Exception {
- String path = makePath();
- int fd = createFile(path, 1);
- assertTrue(mount.get_file_stripe_unit(fd) > 0);
- mount.close(fd);
- mount.unlink(path);
- }
-
- @Test
- public void test_get_repl() throws Exception {
- String path = makePath();
- int fd = createFile(path, 1);
- assertTrue(mount.get_file_replication(fd) > 0);
- mount.close(fd);
- mount.unlink(path);
- }
-
- @Test
- public void test_set_def_obj_size() throws Exception {
- mount.set_default_object_size(1 << 21);
- }
-
- @Test
- public void test_set_def_file_stripe_count() throws Exception {
- mount.set_default_file_stripe_count(2);
- }
-
- @Test
- public void test_set_def_file_stripe_unit() throws Exception {
- mount.set_default_file_stripe_unit(1 << 10);
- }
-
-}
+++ /dev/null
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-import org.junit.*;
-import static org.junit.Assert.*;
-
-import com.ceph.fs.*;
-
-public class CephUnmountedTest {
-
- private CephMount mount;
-
- @Before
- public void setup() throws Exception {
- mount = new CephMount("admin");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_unmount() throws Exception {
- mount.unmount();
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_statfs() throws Exception {
- CephStatVFS stat = new CephStatVFS();
- mount.statfs("/a/path", stat);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_getcwd() throws Exception {
- mount.getcwd();
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_chdir() throws Exception {
- mount.chdir("/a/path");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_listdir() throws Exception {
- mount.listdir("/a/path");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_unlink() throws Exception {
- mount.unlink("/a/path");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_rename() throws Exception {
- mount.rename("/a/path", "/another/path");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_mkdirs() throws Exception {
- mount.mkdirs("/a/path", 0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_rmdir() throws Exception {
- mount.rmdir("/a/path");
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_lstat() throws Exception {
- CephStat stat = new CephStat();
- mount.lstat("/a/path", stat);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_setattr() throws Exception {
- CephStat stat = new CephStat();
- mount.setattr("/a/path", stat, 0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_open() throws Exception {
- mount.open("/a/path", 0, 0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_close() throws Exception {
- mount.close(0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_lseek() throws Exception {
- mount.lseek(0, 0, CephMount.SEEK_CUR);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_read() throws Exception {
- byte[] buf = new byte[1];
- mount.read(0, buf, 1, 0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_write() throws Exception {
- byte[] buf = new byte[1];
- mount.write(0, buf, 1, 0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_get_stripe_unit() throws Exception {
- mount.get_file_stripe_unit(0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_get_repl() throws Exception {
- mount.get_file_replication(0);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_set_def_stripe_unit() throws Exception {
- mount.set_default_file_stripe_unit(1);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_set_def_stripe_count() throws Exception {
- mount.set_default_file_stripe_count(1);
- }
-
- @Test(expected=CephNotMountedException.class)
- public void test_set_def_obj_size() throws Exception {
- mount.set_default_object_size(1);
- }
-}
--- /dev/null
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package com.ceph.fs;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.UUID;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+
+public class CephDoubleMountTest {
+
+ @Test(expected=CephAlreadyMountedException.class)
+ public void test_double_mount() throws Exception {
+ CephMount mount = new CephMount("admin");
+ String conf_file = System.getProperty("CEPH_CONF_FILE");
+ if (conf_file != null)
+ mount.conf_read_file(conf_file);
+ mount.mount(null);
+ try {
+ mount.mount(null);
+ } finally {
+ mount.unmount();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package com.ceph.fs;
+
+import java.io.FileNotFoundException;
+import org.junit.*;
+import java.util.UUID;
+import static org.junit.Assert.*;
+
+/*
+ * This tests the mount root dir functionality. It creates an empty
+ * directory in the real root, then it re-mounts the file system
+ * with the empty directory specified as the root. Assertions are
+ * that the "/" in the normal mount is non-empty, and that "/" is
+ * empty in the mount with the empty directory as the root.
+ */
+public class CephMountCreateTest {
+
+ private static String conf_file;
+
+ @BeforeClass
+ public static void class_setup() throws Exception {
+ conf_file = System.getProperty("CEPH_CONF_FILE");
+ }
+
+ private CephMount setupMount(String root) throws Exception {
+ CephMount mount = new CephMount("admin");
+ if (conf_file != null)
+ mount.conf_read_file(conf_file);
+ mount.mount(root);
+ return mount;
+ }
+
+ @Test
+ public void test_CephMountCreate() throws Exception {
+ CephMount mount;
+ boolean found;
+
+ String dir = "libcephfs_junit_" + UUID.randomUUID();
+
+ /* root dir has more than one dir */
+ mount = setupMount("/");
+
+ try {
+ mount.rmdir("/" + dir);
+ } catch (FileNotFoundException e) {}
+ mount.mkdirs("/" + dir, 777);
+ String[] subdirs = mount.listdir("/");
+ found = false;
+ for (String d : subdirs) {
+ if (d.compareTo(dir) == 0)
+ found = true;
+ }
+ assertTrue(found);
+ mount.unmount();
+
+ /* changing root to empty dir */
+ mount = setupMount("/" + dir);
+
+ subdirs = mount.listdir("/");
+ found = false;
+ for (String d : subdirs) {
+ found = true;
+ }
+ assertFalse(found);
+ mount.unmount();
+
+ /* cleanup */
+ mount = setupMount("/");
+ mount.rmdir("/" + dir);
+ mount.unmount();
+ }
+}
--- /dev/null
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package com.ceph.fs;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.UUID;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/*
+ * Coverage
+ * - Everything is covered in at least success cases.
+ * - link/symlink/readlink/l[set,get,remove]xattr are not working
+ */
+
+public class CephMountTest {
+
+ private static CephMount mount;
+ private static String basedir = null;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ mount = new CephMount("admin");
+
+ String conf_file = System.getProperty("CEPH_CONF_FILE");
+ if (conf_file != null)
+ mount.conf_read_file(conf_file);
+
+ mount.mount(null);
+
+ basedir = "/libcephfs_junit_" + UUID.randomUUID();
+ mount.mkdir(basedir, 0777);
+ }
+
+ @AfterClass
+ public static void destroy() throws Exception {
+ String[] list = mount.listdir(basedir);
+ for (String l : list)
+ System.out.println(l);
+ mount.rmdir(basedir);
+ mount.unmount();
+ }
+
+ /*
+ * Helper function to construct a unique path.
+ */
+ public String makePath() {
+ String path = basedir + "/" + UUID.randomUUID();
+ return path;
+ }
+
+ /*
+ * Helper function to create a file with the given path and size. The file
+ * is filled with size bytes and the file descriptor is returned.
+ */
+ public int createFile(String path, int size) throws Exception {
+ int fd = mount.open(path, CephMount.O_RDWR|CephMount.O_CREAT, 0600);
+ byte[] buf = new byte[4096];
+ int left = size;
+ while (left > 0) {
+ size = Math.min(buf.length, left);
+ long ret = mount.write(fd, buf, size, -1);
+ left -= ret;
+ }
+ return fd;
+ }
+
+ /*
+ * Helper function to create a unique file and fill it with size bytes. The
+ * file descriptor is returned.
+ */
+ public int createFile(int size) throws Exception {
+ return createFile(makePath(), size);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_mount_dne() throws Exception {
+ CephMount mount2 = new CephMount("admin");
+ String conf_file = System.getProperty("CEPH_CONF_FILE");
+ if (conf_file != null)
+ mount2.conf_read_file(conf_file);
+ mount2.mount("/wlfkjwlekfjwlejfwe");
+ mount2.unmount();
+ }
+
+ /*
+ * Test loading of conf file that doesn't exist.
+ *
+ * FIXME:
+ * Ceph returns -ENOSYS rather than -ENOENT. Correct?
+ */
+ //@Test(expected=FileNotFoundException.class)
+ @Test
+ public void test_conf_read_file_dne() throws Exception {
+ //mount.conf_read_file("/this_file_does_not_exist");
+ }
+
+ /*
+ * Test loading of conf file that isn't valid
+ *
+ * FIXME: implement
+ */
+ @Test
+ public void test_conf_read_file_invalid() throws Exception {
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_conf_read_file_null() throws Exception {
+ mount.conf_read_file(null);
+ }
+
+ /*
+ * conf_set/conf_get
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_conf_set_null_opt() throws Exception {
+ mount.conf_set(null, "value");
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_conf_set_null_val() throws Exception {
+ mount.conf_set("option", null);
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_conf_get_null_opt() throws Exception {
+ mount.conf_get(null);
+ }
+
+ @Test
+ public void test_conf() throws Exception {
+ String opt = "log to stderr";
+ String val1, val2, val3;
+
+ /* get the current value */
+ val1 = mount.conf_get(opt);
+
+ /*
+ * flip the value. this may make some debug information be dumped to the
+ * console when the value becomes true. TODO: find a better config option
+ * to toggle.
+ */
+ if (val1.compareTo("true") == 0)
+ val2 = "false";
+ else
+ val2 = "true";
+ mount.conf_set(opt, val2);
+
+ /* verify the change */
+ val3 = mount.conf_get(opt);
+ assertTrue(val3.compareTo(val2) == 0);
+
+ /* reset to original value */
+ mount.conf_set(opt, val1);
+ val3 = mount.conf_get(opt);
+ assertTrue(val3.compareTo(val1) == 0);
+ }
+
+ /*
+ * statfs
+ */
+
+ @Test
+ public void test_statfs() throws Exception {
+ CephStatVFS st1 = new CephStatVFS();
+ mount.statfs("/", st1);
+
+ /*
+ * FIXME: a better test here is to see if changes to the file system are
+ * reflected through statfs (e.g. increasing number of files). However, it
+ * appears that the updates aren't immediately visible.
+ */
+ assertTrue(st1.bsize > 0);
+ assertTrue(st1.frsize > 0);
+ assertTrue(st1.blocks > 0);
+ assertTrue(st1.bavail > 0);
+ assertTrue(st1.namemax > 0);
+ }
+
+ /*
+ * getcwd/chdir
+ */
+
+ @Test
+ public void test_getcwd() throws Exception {
+ mount.chdir(basedir);
+ String cwd = mount.getcwd();
+ assertTrue(cwd.compareTo(basedir) == 0);
+
+ /* Make sure to reset cwd to root */
+ mount.chdir("/");
+ cwd = mount.getcwd();
+ assertTrue(cwd.compareTo("/") == 0);
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_chdir_null() throws Exception {
+ mount.chdir(null);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_chdir_dne() throws Exception {
+ mount.chdir("/this/path/does/not/exist/");
+ }
+
+ /*
+ * FIXME: this test should throw an error (but does not)?
+ */
+ //@Test(expected=IOException.class)
+ @Test
+ public void test_chdir_not_dir() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 1);
+ mount.close(fd);
+ //mount.chdir(path); shouldn't be able to do this?
+ mount.unlink(path);
+
+ /*
+ * Switch back. Other tests seem to be sensitive to the current directory
+ * being something other than "/". This shouldn't happen once this tests
+ * passes and the call to chdir fails anyway.
+ */
+ mount.chdir("/");
+ }
+
+ /*
+ * listdir
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_listdir_null() throws Exception {
+ mount.listdir(null);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_listdir_dne() throws Exception {
+ mount.listdir("/this/path/does/not/exist/");
+ }
+
+ @Test(expected=IOException.class)
+ public void test_listdir_not_dir() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 1);
+ mount.close(fd);
+ try {
+ mount.listdir(path);
+ } finally {
+ mount.unlink(path);
+ }
+ }
+
+ @Test
+ public void test_listdir() throws Exception {
+ String dir = makePath();
+ mount.mkdir(dir, 0777);
+ /* test that new directory is empty */
+ String[] list = mount.listdir(dir);
+ assertTrue(list.length == 0);
+ /* test that new directories are seen */
+ for (int i = 0; i < 3; i++)
+ mount.mkdir(dir + "/" + i, 777);
+ list = mount.listdir(dir);
+ assertTrue(list.length == 3);
+ /* test that more new directories are seen */
+ for (int i = 0; i < 30; i++)
+ mount.mkdir(dir + "/x" + i, 777);
+ list = mount.listdir(dir);
+ assertTrue(list.length == 33);
+
+ /* remove */
+ for (int i = 0; i < 30; i++)
+ mount.rmdir(dir + "/x" + i);
+ for (int i = 0; i < 3; i++)
+ mount.rmdir(dir + "/" + i);
+ mount.rmdir(dir);
+ }
+
+ /*
+ * Missing
+ *
+ * ceph_link
+ * ceph_unlink
+ */
+
+ /*
+ * rename
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_rename_null_from() throws Exception {
+ mount.rename(null, "to");
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_rename_null_to() throws Exception {
+ mount.rename("from", null);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_rename_dne() throws Exception {
+ mount.rename("/this/doesnt/exist", "/this/neither");
+ }
+
+ @Test
+ public void test_rename() throws Exception {
+ /* create a file */
+ String path = makePath();
+ int fd = createFile(path, 1);
+ mount.close(fd);
+
+ /* move it to a new name */
+ String newpath = makePath();
+ mount.rename(path, newpath);
+
+ /* verfiy the sizes are the same */
+ CephStat st = new CephStat();
+ mount.lstat(newpath, st);
+ assertTrue(st.size == 1);
+
+ /* remove the file */
+ mount.unlink(newpath);
+ }
+
+ /*
+ * mkdir/mkdirs/rmdir
+ */
+
+ @Test(expected=IOException.class)
+ public void test_mkdir_exists() throws Exception {
+ String path = makePath();
+ mount.mkdir(path, 0777);
+ try {
+ mount.mkdir(path, 0777);
+ } finally {
+ mount.rmdir(path);
+ }
+ }
+
+ @Test(expected=IOException.class)
+ public void test_mkdirs_exists() throws Exception {
+ String path = makePath();
+ mount.mkdirs(path, 0777);
+ try {
+ mount.mkdirs(path, 0777);
+ } finally {
+ mount.rmdir(path);
+ }
+ }
+
+ @Test
+ public void test_mkdir() throws Exception {
+ String path = makePath();
+ mount.mkdir(path, 0777);
+ CephStat st = new CephStat();
+ mount.lstat(path, st);
+ assertTrue(st.isDir());
+ mount.rmdir(path);
+ }
+
+ @Test
+ public void test_mkdirs() throws Exception {
+ String path = makePath();
+ mount.mkdirs(path + "/x/y", 0777);
+
+ CephStat st = new CephStat();
+ mount.lstat(path, st);
+ assertTrue(st.isDir());
+
+ mount.lstat(path + "/x", st);
+ assertTrue(st.isDir());
+
+ mount.lstat(path + "/x/y", st);
+ assertTrue(st.isDir());
+
+ mount.rmdir(path + "/x/y");
+ mount.rmdir(path + "/x");
+ mount.rmdir(path);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_rmdir() throws Exception {
+ /* make a new directory */
+ String path = makePath();
+ mount.mkdir(path, 0777);
+ CephStat st = new CephStat();
+ mount.lstat(path, st);
+ assertTrue(st.isDir());
+ /* remove it */
+ mount.rmdir(path);
+ /* should not exist now */
+ mount.lstat(path, st);
+ }
+
+ /*
+ * Missing
+ *
+ * readlink
+ * symlink
+ */
+
+ /*
+ * lstat
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_lstat_null_path() throws Exception {
+ mount.lstat(null, new CephStat());
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_lstat_null_stat() throws Exception {
+ mount.lstat("/path", null);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_lstat_null_dne() throws Exception {
+ mount.lstat("/path/does/not/exist", new CephStat());
+ }
+
+ /*
+ * test_stat covers lstat and fstat
+ */
+
+ @Test
+ public void test_stat() throws Exception {
+ /* create a new file */
+ String path = makePath();
+ int size = 12345;
+ int fd = createFile(path, size);
+ mount.close(fd);
+
+ /* test some basic info about the new file */
+ CephStat orig_st = new CephStat();
+ mount.lstat(path, orig_st);
+ assertTrue(orig_st.size == size);
+ assertTrue(orig_st.blksize > 0);
+ assertTrue(orig_st.blocks > 0);
+
+ /* now try fstat */
+ CephStat other_st = new CephStat();
+ fd = mount.open(path, CephMount.O_RDWR, 0);
+ mount.fstat(fd, other_st);
+ mount.close(fd);
+
+ mount.unlink(path);
+
+ assertTrue(orig_st.mode == other_st.mode);
+ assertTrue(orig_st.uid == other_st.uid);
+ assertTrue(orig_st.gid == other_st.gid);
+ assertTrue(orig_st.size == other_st.size);
+ assertTrue(orig_st.blksize == other_st.blksize);
+ assertTrue(orig_st.blocks == other_st.blocks);
+ }
+
+ /*
+ * setattr
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_setattr_null_path() throws Exception {
+ mount.setattr(null, new CephStat(), 0);
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_setattr_null_stat() throws Exception {
+ mount.setattr("/path", null, 0);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_setattr_dne() throws Exception {
+ mount.setattr("/path/does/not/exist", new CephStat(), 0);
+ }
+
+ @Test
+ public void test_setattr() throws Exception {
+ /* create a file */
+ String path = makePath();
+ int fd = createFile(path, 1);
+ mount.close(fd);
+
+ CephStat st1 = new CephStat();
+ mount.lstat(path, st1);
+
+ st1.uid += 1;
+ st1.gid += 1;
+ mount.setattr(path, st1, mount.SETATTR_UID|mount.SETATTR_GID);
+
+ CephStat st2 = new CephStat();
+ mount.lstat(path, st2);
+
+ assertTrue(st2.uid == st1.uid);
+ assertTrue(st2.gid == st1.gid);
+
+ /* remove the file */
+ mount.unlink(path);
+ }
+
+ /*
+ * chmod
+ */
+
+ @Test(expected=NullPointerException.class)
+ public void test_chmod_null_path() throws Exception {
+ mount.chmod(null, 0);
+ }
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_chmod_dne() throws Exception {
+ mount.chmod("/path/does/not/exist", 0);
+ }
+
+ @Test
+ public void test_chmod() throws Exception {
+ /* create a file */
+ String path = makePath();
+ int fd = createFile(path, 1);
+ mount.close(fd);
+
+ CephStat st = new CephStat();
+ mount.lstat(path, st);
+
+ /* flip a bit */
+ int mode = st.mode;
+ if ((mode & 1) != 0)
+ mode -= 1;
+ else
+ mode += 1;
+
+ mount.chmod(path, mode);
+ CephStat st2 = new CephStat();
+ mount.lstat(path, st2);
+ assertTrue(st2.mode == mode);
+
+ mount.unlink(path);
+ }
+
+ /*
+ * truncate
+ */
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_truncate_dne() throws Exception {
+ mount.truncate("/path/does/not/exist", 0);
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void test_truncate_null_path() throws Exception {
+ mount.truncate(null, 0);
+ }
+
+ @Test
+ public void test_truncate() throws Exception {
+ // make file
+ String path = makePath();
+ int orig_size = 1398331;
+ int fd = createFile(path, orig_size);
+ mount.close(fd);
+
+ // check file size
+ CephStat st = new CephStat();
+ mount.lstat(path, st);
+ assertTrue(st.size == orig_size);
+
+ // truncate and check
+ int crop_size = 333333;
+ mount.truncate(path, crop_size);
+ mount.lstat(path, st);
+ assertTrue(st.size == crop_size);
+
+ // check after re-open
+ fd = mount.open(path, CephMount.O_RDWR, 0);
+ mount.fstat(fd, st);
+ assertTrue(st.size == crop_size);
+ mount.close(fd);
+
+ mount.unlink(path);
+ }
+
+ /*
+ * open/close
+ */
+
+ @Test(expected=FileNotFoundException.class)
+ public void test_open_dne() throws Exception {
+ mount.open("/path/doesnt/exist", 0, 0);
+ }
+
+ /*
+ * lseek
+ */
+
+ @Test
+ public void test_lseek() throws Exception {
+ /* create a new file */
+ String path = makePath();
+ int size = 12345;
+ int fd = createFile(path, size);
+ mount.close(fd);
+
+ /* open and check size */
+ fd = mount.open(path, CephMount.O_RDWR, 0);
+ long end = mount.lseek(fd, 0, CephMount.SEEK_END);
+ mount.close(fd);
+
+ mount.unlink(path);
+
+ assertTrue(size == (int)end);
+ }
+
+ /*
+ * read/write
+ */
+
+ @Test
+ public void test_read() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 1500);
+ byte[] buf = new byte[1500];
+ long ret = mount.read(fd, buf, 1500, 0);
+ assertTrue(ret == 1500);
+ mount.unlink(path);
+ }
+
+ /*
+ * ftruncate
+ */
+
+ @Test
+ public void test_ftruncate() throws Exception {
+ // make file
+ String path = makePath();
+ int orig_size = 1398331;
+ int fd = createFile(path, orig_size);
+
+ // check file size
+ CephStat st = new CephStat();
+ mount.fstat(fd, st);
+ assertTrue(st.size == orig_size);
+
+ // truncate and check
+ int crop_size = 333333;
+ mount.ftruncate(fd, crop_size);
+ mount.fstat(fd, st);
+ assertTrue(st.size == crop_size);
+ mount.close(fd);
+
+ // check after re-open
+ fd = mount.open(path, CephMount.O_RDWR, 0);
+ mount.fstat(fd, st);
+ assertTrue(st.size == crop_size);
+ mount.close(fd);
+
+ mount.unlink(path);
+ }
+
+ /*
+ * fsync
+ */
+
+ @Test
+ public void test_fsync() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 123);
+ mount.fsync(fd, false);
+ mount.fsync(fd, true);
+ mount.close(fd);
+ mount.unlink(path);
+ }
+
+ /*
+ * fstat
+ *
+ * success case is handled in test_stat along with lstat.
+ */
+
+ /*
+ * sync_fs
+ */
+
+ @Test
+ public void test_sync_fs() throws Exception {
+ mount.sync_fs();
+ }
+
+ /*
+ * get/set/list/remove xattr
+ */
+
+ @Test
+ public void test_xattr() throws Exception {
+ /* make file */
+ String path = makePath();
+ int fd = createFile(path, 123);
+ mount.close(fd);
+
+ /* make xattrs */
+ String val1 = "This is a new xattr";
+ String val2 = "This is a different xattr";
+ byte[] buf1 = val1.getBytes();
+ byte[] buf2 = val2.getBytes();
+ mount.setxattr(path, "attr1", buf1, buf1.length, mount.XATTR_CREATE);
+ mount.setxattr(path, "attr2", buf2, buf2.length, mount.XATTR_CREATE);
+
+ /* list xattrs */
+ String[] xattrs = mount.listxattr(path);
+ assertTrue(xattrs.length == 2);
+ int found = 0;
+ for (String xattr : xattrs) {
+ if (xattr.compareTo("attr1") == 0) {
+ found++;
+ continue;
+ }
+ if (xattr.compareTo("attr2") == 0) {
+ found++;
+ continue;
+ }
+ System.out.println("found unwanted xattr: " + xattr);
+ }
+ assertTrue(found == 2);
+
+ /* get first xattr by looking up length */
+ long attr1_len = mount.getxattr(path, "attr1", null);
+ byte[] out = new byte[(int)attr1_len];
+ mount.getxattr(path, "attr1", out);
+ String outStr = new String(out);
+ assertTrue(outStr.compareTo(val1) == 0);
+
+ /* get second xattr assuming original length */
+ out = new byte[buf2.length];
+ mount.getxattr(path, "attr2", out);
+ outStr = new String(out);
+ assertTrue(outStr.compareTo(val2) == 0);
+
+ /* remove the attributes */
+ /* FIXME: the MDS returns ENODATA for removexattr */
+ /*
+ mount.removexattr(path, "attr1");
+ xattrs = mount.listxattr(path);
+ assertTrue(xattrs.length == 1);
+ mount.removexattr(path, "attr2");
+ xattrs = mount.listxattr(path);
+ assertTrue(xattrs.length == 0);
+ */
+
+ mount.unlink(path);
+ }
+
+ /*
+ * get/set/list/remove symlink xattr
+ *
+ * Currently not working. Code is the same as for regular xattrs, so there
+ * might be a deeper issue.
+ */
+
+ @Test
+ public void test_get_stripe_unit() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 1);
+ assertTrue(mount.get_file_stripe_unit(fd) > 0);
+ mount.close(fd);
+ mount.unlink(path);
+ }
+
+ @Test
+ public void test_get_repl() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 1);
+ assertTrue(mount.get_file_replication(fd) > 0);
+ mount.close(fd);
+ mount.unlink(path);
+ }
+
+ @Test
+ public void test_set_def_obj_size() throws Exception {
+ mount.set_default_object_size(1 << 21);
+ }
+
+ @Test
+ public void test_set_def_file_stripe_count() throws Exception {
+ mount.set_default_file_stripe_count(2);
+ }
+
+ @Test
+ public void test_set_def_file_stripe_unit() throws Exception {
+ mount.set_default_file_stripe_unit(1 << 10);
+ }
+
+}
--- /dev/null
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package com.ceph.fs;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+public class CephUnmountedTest {
+
+ private CephMount mount;
+
+ @Before
+ public void setup() throws Exception {
+ mount = new CephMount("admin");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_unmount() throws Exception {
+ mount.unmount();
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_statfs() throws Exception {
+ CephStatVFS stat = new CephStatVFS();
+ mount.statfs("/a/path", stat);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_getcwd() throws Exception {
+ mount.getcwd();
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_chdir() throws Exception {
+ mount.chdir("/a/path");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_listdir() throws Exception {
+ mount.listdir("/a/path");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_unlink() throws Exception {
+ mount.unlink("/a/path");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_rename() throws Exception {
+ mount.rename("/a/path", "/another/path");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_mkdirs() throws Exception {
+ mount.mkdirs("/a/path", 0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_rmdir() throws Exception {
+ mount.rmdir("/a/path");
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_lstat() throws Exception {
+ CephStat stat = new CephStat();
+ mount.lstat("/a/path", stat);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_setattr() throws Exception {
+ CephStat stat = new CephStat();
+ mount.setattr("/a/path", stat, 0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_open() throws Exception {
+ mount.open("/a/path", 0, 0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_close() throws Exception {
+ mount.close(0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_lseek() throws Exception {
+ mount.lseek(0, 0, CephMount.SEEK_CUR);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_read() throws Exception {
+ byte[] buf = new byte[1];
+ mount.read(0, buf, 1, 0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_write() throws Exception {
+ byte[] buf = new byte[1];
+ mount.write(0, buf, 1, 0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_get_stripe_unit() throws Exception {
+ mount.get_file_stripe_unit(0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_get_repl() throws Exception {
+ mount.get_file_replication(0);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_set_def_stripe_unit() throws Exception {
+ mount.set_default_file_stripe_unit(1);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_set_def_stripe_count() throws Exception {
+ mount.set_default_file_stripe_count(1);
+ }
+
+ @Test(expected=CephNotMountedException.class)
+ public void test_set_def_obj_size() throws Exception {
+ mount.set_default_object_size(1);
+ }
+}