summaryrefslogtreecommitdiffstats
path: root/test/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/mount.c')
-rw-r--r--test/mount.c299
1 files changed, 292 insertions, 7 deletions
diff --git a/test/mount.c b/test/mount.c
index 1898a36..c86c56b 100644
--- a/test/mount.c
+++ b/test/mount.c
@@ -168,7 +168,7 @@ test_basic(hid_t fapl)
static int
test_illegal(hid_t fapl)
{
- hid_t file1 = -1, file2 = -1, file3 = -1, file4 = -1, mnt = -1;
+ hid_t file1 = -1, file1b = -1, file2 = -1, file3 = -1, file3b = -1, mnt = -1;
char filename1[1024], filename2[1024], filename3[1024];
herr_t status;
@@ -183,7 +183,9 @@ test_illegal(hid_t fapl)
(file2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0 ||
(file3 = H5Fopen(filename3, H5F_ACC_RDONLY, fapl)) < 0)
FAIL_STACK_ERROR
- if((file4 = H5Fopen(filename3, H5F_ACC_RDONLY, fapl)) < 0)
+ if((file1b = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0)
+ FAIL_STACK_ERROR
+ if((file3b = H5Fopen(filename3, H5F_ACC_RDONLY, fapl)) < 0)
FAIL_STACK_ERROR
/* Try mounting a file on itself */
@@ -218,12 +220,12 @@ test_illegal(hid_t fapl)
* Try mounting the same file opened twice at the same place.
*
* We have to open the mount point before we mount the first file or we'll
- * end up mounting file4 at the root of file3 and the mount will succeed.
+ * end up mounting file3b at the root of file3 and the mount will succeed.
*/
if((mnt = H5Gopen2(file1, "/mnt1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
if(H5Fmount(mnt, ".", file3, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
H5E_BEGIN_TRY {
- status = H5Fmount(mnt, ".", file4, H5P_DEFAULT);
+ status = H5Fmount(mnt, ".", file3b, H5P_DEFAULT);
} H5E_END_TRY;
if(status >= 0) {
H5_FAILED();
@@ -233,13 +235,24 @@ test_illegal(hid_t fapl)
if(H5Funmount(mnt, ".") < 0) FAIL_STACK_ERROR
if(H5Gclose(mnt) < 0) FAIL_STACK_ERROR
-
+ /* Try to create a "weak" cycle */
+ if(H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+ H5E_BEGIN_TRY {
+ status = H5Fmount(file2, "/mnt1/file2", file1b, H5P_DEFAULT);
+ } H5E_END_TRY;
+ if(status >= 0) {
+ H5_FAILED();
+ puts(" Creating a cycle with mount points should have failed.");
+ TEST_ERROR
+ } /* end if */
+ if(H5Funmount(file1, "/mnt1") < 0) FAIL_STACK_ERROR
/* Close everything and return */
if(H5Fclose(file1) < 0) FAIL_STACK_ERROR
+ if(H5Fclose(file1b) < 0) FAIL_STACK_ERROR
if(H5Fclose(file2) < 0) FAIL_STACK_ERROR
if(H5Fclose(file3) < 0) FAIL_STACK_ERROR
- if(H5Fclose(file4) < 0) FAIL_STACK_ERROR
+ if(H5Fclose(file3b) < 0) FAIL_STACK_ERROR
PASSED();
return 0;
@@ -248,9 +261,10 @@ error:
H5E_BEGIN_TRY {
H5Gclose(mnt);
H5Fclose(file1);
+ H5Fclose(file1b);
H5Fclose(file2);
H5Fclose(file3);
- H5Fclose(file4);
+ H5Fclose(file3b);
} H5E_END_TRY;
return 1;
} /* end test_illegal() */
@@ -3919,6 +3933,275 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_sharedacc
+ *
+ * Purpose: Test shared access to a file's mount table.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Friday, August 1, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+ static int
+test_sharedacc(hid_t fapl)
+{
+ hid_t fid1[2] = {-1, -1}, fid2[2] = {-1, -1}; /* File IDs */
+ hid_t gid = -1;
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE],
+ filename3[NAME_BUF_SIZE]; /* Name of files to mount */
+ int i, j, k; /* Counters */
+
+ TESTING("shared mount access");
+
+ h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+ h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
+
+ /* Create file #1 & its group */
+ if((fid1[0] = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if((gid = H5Gcreate2(fid1[0], "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR
+
+ /* Create file #2 & its group */
+ if((fid2[0] = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if((gid = H5Gcreate2(fid2[0], "B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR
+
+ /* Test mount before reopen, then using reopened handle for access */
+ if(H5Fmount(fid1[0], "/A", fid2[0], H5P_DEFAULT) < 0)
+ TEST_ERROR
+ if((fid1[1] = H5Freopen(fid1[0])) < 0)
+ TEST_ERROR
+ if((fid2[1] = H5Freopen(fid2[0])) < 0)
+ TEST_ERROR
+ if((gid = H5Gopen2(fid1[1], "/A/B", H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR
+ if(H5Funmount(fid1[1], "/A") < 0)
+ TEST_ERROR
+
+ /* "Brute force" test of all possible ways of mounting, accessing, and
+ * unmounting files with multiple handles (mount after reopen) */
+ for(i=0; i<2; i++)
+ for(j=0; j<2; j++)
+ for(k=0; k<2; k++) {
+ if(H5Fmount(fid1[i], "/A", fid2[j], H5P_DEFAULT) < 0)
+ TEST_ERROR
+ if((gid = H5Gopen2(fid1[k], "/A/B", H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR
+ if(H5Funmount(fid1[k], "/A") < 0)
+ TEST_ERROR
+ }
+
+ /* Close file IDs */
+ for(i=0; i<2; i++) {
+ if(H5Fclose(fid1[i]) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid2[i]) < 0)
+ TEST_ERROR
+ }
+
+ /* Check that all file IDs have been closed */
+ if(H5I_nmembers(H5I_FILE) != 0)
+ TEST_ERROR
+ if(H5F_sfile_assert_num(0) != 0)
+ TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid);
+ for(i=0; i<2; i++) {
+ H5Fclose(fid1[i]);
+ H5Fclose(fid2[i]);
+ }
+ } H5E_END_TRY;
+ return 1;
+} /* end test_sharedacc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_sharedclose
+ *
+ * Purpose: Test that files within a shared mount structure are properly
+ * closed.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Friday, August 6, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+ static int
+test_sharedclose(hid_t fapl)
+{
+ hid_t fid1a = -1, fid1b = -1, fid2 = -1, fid3 = -2; /* File IDs */
+ hid_t gid1 = -1, gid2 = -1, gid3 = -1;
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE],
+ filename3[NAME_BUF_SIZE]; /* Name of files to mount */
+
+ TESTING("closing shared mounts");
+
+ h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+ h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
+
+ /* Create file #1a & its group */
+ if((fid1a = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if((gid1 = H5Gcreate2(fid1a, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Create file #1b & its groups */
+ if((fid1b = H5Freopen(fid1a)) < 0)
+ TEST_ERROR
+ if((gid2 = H5Gcreate2(fid1b, "B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if((gid3 = H5Gcreate2(fid1b, "B/C", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Create file #2 */
+ if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Create file #3 */
+ if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Mount file #2 to file #1a */
+ if(H5Fmount(gid1, ".", fid2, H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ /* Mount file #3 to file #1b */
+ if(H5Fmount(gid2, ".", fid3, H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ /* Close file #1b. It should be held open by the groups in it. */
+ if(H5Fclose(fid1b) < 0)
+ TEST_ERROR
+
+ /* Close file #3. It should be held open by the groups in its parent. */
+ if(H5Fclose(fid3) < 0)
+ TEST_ERROR
+
+ /* Close group B in file #1b. This should not close file #1b and #3. */
+ if(H5Gclose(gid2) < 0)
+ TEST_ERROR
+
+ /* Check that file #3 is still open */
+ if(H5F_sfile_assert_num(3) != 0)
+ TEST_ERROR
+
+ /* Close group B/C in file #1b. This should close file #1b and #3. */
+ if(H5Gclose(gid3) < 0)
+ TEST_ERROR
+
+ /* Check that file #3 has been closed */
+ if(H5F_sfile_assert_num(2) != 0)
+ TEST_ERROR
+
+ /* Unmount file 2 and close the rest of the handles */
+ if(H5Funmount(fid1a, "A") < 0)
+ TEST_ERROR
+ if(H5Gclose(gid1) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid2) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid1a) < 0)
+ TEST_ERROR
+
+ /* Check that all file IDs have been closed */
+ if(H5I_nmembers(H5I_FILE) != 0)
+ TEST_ERROR
+ if(H5F_sfile_assert_num(0) != 0)
+ TEST_ERROR
+
+ /* Create file #1 & its group */
+ if((fid1a = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if((gid1 = H5Gcreate2(fid1a, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Create file #1b & its group */
+ if((fid1b = H5Freopen(fid1a)) < 0)
+ TEST_ERROR
+ if((gid2 = H5Gcreate2(fid1b, "B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Create file #2 */
+ if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Mount file #2 to file #1 */
+ if(H5Fmount(fid1a, "A", fid2, H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ /* Close file #1b. It should be held open by the group in it. */
+ if(H5Fclose(fid1b) < 0)
+ TEST_ERROR
+
+ /* Close the group in file #1b. This should close file # 1b. */
+ if(H5Gclose(gid2) < 0)
+ TEST_ERROR
+
+ /* Unmount file 2 and close the rest of the handles */
+ if(H5Funmount(fid1a, "A") < 0)
+ TEST_ERROR
+ if(H5Gclose(gid1) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid2) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid1a) < 0)
+ TEST_ERROR
+
+ /* Check that all file IDs have been closed */
+ if(H5I_nmembers(H5I_FILE) != 0)
+ TEST_ERROR
+ if(H5F_sfile_assert_num(0) != 0)
+ TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid1);
+ H5Gclose(gid2);
+ H5Gclose(gid3);
+ H5Fclose(fid1a);
+ H5Fclose(fid1b);
+ H5Fclose(fid2);
+ H5Fclose(fid3);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_sharedclose() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test file mounting
@@ -3977,6 +4260,8 @@ main(void)
nerrors += test_close_parent(fapl);
nerrors += test_cut_graph(fapl);
nerrors += test_symlink(fapl);
+ nerrors += test_sharedacc(fapl);
+ nerrors += test_sharedclose(fapl);
if (nerrors) goto error;
puts("All mount tests passed.");