summaryrefslogtreecommitdiffstats
path: root/test/stab.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
commita1708eb023f2c8f8ac6c2c17bf1e598c8dff956e (patch)
tree34c87a3753b36c4c8d689d58bf456eaf261cd235 /test/stab.c
parentbea1e576c5ef5500678f7ce913d835341b625e8f (diff)
downloadhdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.zip
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.gz
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.bz2
[svn-r11712] Purpose:
New feature Description: Check in baseline for compact group revisions, which radically revises the source code for managing groups and object headers. WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! This initiates the "unstable" phase of the 1.7.x branch, leading up to the 1.8.0 release. Please test this code, but do _NOT_ keep files created with it - the format will change again before the release and you will not be able to read your old files!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! Solution: There's too many changes to really describe them all, but some of them include: - Stop abusing the H5G_entry_t structure and split it into two separate structures for non-symbol table node use within the library: H5O_loc_t for object locations in a file and H5G_name_t to store the path to an opened object. H5G_entry_t is now only used for storing symbol table entries on disk. - Retire H5G_namei() in favor of a more general mechanism for traversing group paths and issuing callbacks on objects located. This gets us out of the business of hacking H5G_namei() for new features, generally. - Revised H5O* routines to take a H5O_loc_t instead of H5G_entry_t - Lots more... Platforms tested: h5committested and maybe another dozen configurations.... :-)
Diffstat (limited to 'test/stab.c')
-rw-r--r--test/stab.c732
1 files changed, 724 insertions, 8 deletions
diff --git a/test/stab.c b/test/stab.c
index 947825c..33c0fce 100644
--- a/test/stab.c
+++ b/test/stab.c
@@ -16,13 +16,14 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Tuesday, November 24, 1998
*/
-#include "h5test.h"
-/*
- * This file needs to access private datatypes from the H5G package.
- */
-#define H5G_PACKAGE
-#include "H5Gpkg.h"
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+/* Define this macro to indicate that the testing APIs should be available */
+#define H5G_TESTING
+
+#include "h5test.h"
+#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"stab1",
@@ -30,6 +31,40 @@ const char *FILENAME[] = {
NULL
};
+#define NAME_BUF_SIZE 1024
+
+/* Definitions for 'lifecycle' test */
+#define LIFECYCLE_TOP_GROUP "top"
+#define LIFECYCLE_BOTTOM_GROUP "bottom %u"
+#define LIFECYCLE_MAX_COMPACT 4
+#define LIFECYCLE_MIN_DENSE 3
+#define LIFECYCLE_EST_NUM_ENTRIES 3
+#define LIFECYCLE_EST_NAME_LEN 10
+
+/* Definitions for 'long_compact' test */
+#define LONG_COMPACT_LENGTH ((64 * 1024) + 1024)
+
+/* Definitions for 'read_old' test */
+#define READ_OLD_NGROUPS 100
+#define READ_OLD_BUFSIZE 1024
+
+/* The group_old.h5 is generated from gen_old_fill.c in HDF5 'test' directory
+ * for version 1.6. To get this data file, simply compile gen_old_group.c with
+ * the HDF5 library in that branch and run it. */
+#define FILE_OLD_GROUPS "group_old.h5"
+
+/* Definitions for 'no_compact' test */
+#define NO_COMPACT_TOP_GROUP "top"
+#define NO_COMPACT_BOTTOM_GROUP "bottom %u"
+#define NO_COMPACT_MAX_COMPACT 0
+#define NO_COMPACT_MIN_DENSE 0
+
+/* Definitions for 'no_compact' test */
+#define GCPL_ON_ROOT_MIDDLE_GROUP "/middle"
+#define GCPL_ON_ROOT_BOTTOM_GROUP "/middle/bottom"
+#define GCPL_ON_ROOT_MAX_COMPACT 4
+#define GCPL_ON_ROOT_MIN_DENSE 2
+
/*-------------------------------------------------------------------------
* Function: test_misc
@@ -127,11 +162,11 @@ test_long(hid_t file)
TESTING("long names");
/* Group names */
- name1 = malloc(namesize);
+ name1 = HDmalloc(namesize);
for (i=0; i<namesize; i++)
name1[i] = (char)('A' + i%26);
name1[namesize-1] = '\0';
- name2 = malloc(2*namesize + 2);
+ name2 = HDmalloc(2*namesize + 2);
sprintf(name2, "%s/%s", name1, name1);
/* Create groups */
@@ -146,6 +181,10 @@ test_long(hid_t file)
H5Gclose(g1);
H5Gclose(g2);
+ /* Release name buffers */
+ HDfree(name2);
+ HDfree(name1);
+
PASSED();
return 0;
@@ -153,6 +192,10 @@ test_long(hid_t file)
H5E_BEGIN_TRY {
H5Gclose(g1);
H5Gclose(g2);
+ if(name2)
+ free(name2);
+ if(name1)
+ free(name1);
} H5E_END_TRY;
return 1;
}
@@ -214,6 +257,674 @@ test_large(hid_t file)
/*-------------------------------------------------------------------------
+ * Function: lifecycle
+ *
+ * Purpose: Test that adding links to a group follow proper "lifecycle"
+ * of empty->compact->symbol table->compact->empty. (As group
+ * is created, links are added, then links removed)
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 17, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+lifecycle(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t gid2 = (-1); /* Datatype ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ size_t lheap_size_hint; /* Local heap size hint */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ unsigned est_num_entries; /* Estimated # of entries in group */
+ unsigned est_name_len; /* Estimated length of entry name */
+ unsigned nmsgs; /* Number of messages in group's header */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ char filename[NAME_BUF_SIZE];
+ off_t empty_size; /* Size of an empty file */
+ unsigned u; /* Local index variable */
+ off_t file_size; /* Size of each file created */
+
+ TESTING("group lifecycle");
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ /* Get size of file as empty */
+ if((empty_size = h5_get_file_size(filename)) == 0) TEST_ERROR;
+
+ /* Re-open file */
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR;
+
+ /* Set up group creation property list */
+ if((gcpl = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR;
+
+ /* Query default group creation property settings */
+ if(H5Pget_local_heap_size_hint(gcpl, &lheap_size_hint) < 0) TEST_ERROR;
+ if(lheap_size_hint != H5G_CRT_GINFO_LHEAP_SIZE_HINT) TEST_ERROR;
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != H5G_CRT_GINFO_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != H5G_CRT_GINFO_MIN_DENSE) TEST_ERROR;
+ if(H5Pget_est_link_info(gcpl, &est_num_entries, &est_name_len) < 0) TEST_ERROR;
+ if(est_num_entries != H5G_CRT_GINFO_EST_NUM_ENTRIES) TEST_ERROR;
+ if(est_name_len != H5G_CRT_GINFO_EST_NAME_LEN) TEST_ERROR;
+
+ /* Set GCPL parameters */
+ if(H5Pset_link_phase_change(gcpl, LIFECYCLE_MAX_COMPACT, LIFECYCLE_MIN_DENSE) < 0) TEST_ERROR;
+ if(H5Pset_est_link_info(gcpl, LIFECYCLE_EST_NUM_ENTRIES, LIFECYCLE_EST_NAME_LEN) < 0) TEST_ERROR;
+
+ /* Create group for testing lifecycle */
+ if((gid = H5Gcreate_expand(fid, LIFECYCLE_TOP_GROUP, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Query default group creation property settings */
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != LIFECYCLE_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != LIFECYCLE_MIN_DENSE) TEST_ERROR;
+ if(H5Pget_est_link_info(gcpl, &est_num_entries, &est_name_len) < 0) TEST_ERROR;
+ if(est_num_entries != LIFECYCLE_EST_NUM_ENTRIES) TEST_ERROR;
+ if(est_name_len != LIFECYCLE_EST_NAME_LEN) TEST_ERROR;
+
+ /* Use internal testing routine to check that the group has no links or symbol table */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR;
+
+ /* Create first "bottom" group */
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, (unsigned)0);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != 1) TEST_ERROR;
+
+ /* Create several more bottom groups, to push the top group almost to a symbol table */
+ /* (Start counting at '1', since we've already created one bottom group */
+ for(u = 1; u < LIFECYCLE_MAX_COMPACT; u++) {
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != LIFECYCLE_MAX_COMPACT) TEST_ERROR;
+
+ /* Create one more "bottom" group, which should push top group into using a symbol table */
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Unlink objects from top group */
+ while(u >= LIFECYCLE_MIN_DENSE) {
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+
+ u--;
+ } /* end while */
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Unlink one more object from the group, which should transform back to using links */
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ u--;
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != (LIFECYCLE_MIN_DENSE - 1)) TEST_ERROR;
+
+ /* Unlink last two objects from top group */
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ u--;
+ sprintf(objname, LIFECYCLE_BOTTOM_GROUP, u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close top group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Unlink top group */
+ if(H5Gunlink(fid, LIFECYCLE_TOP_GROUP) < 0) TEST_ERROR
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ /* Get size of file as empty */
+ if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR;
+
+ /* Verify that file is correct size */
+ if(file_size != empty_size) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gcpl);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return 1;
+} /* end lifecycle() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: long_compact
+ *
+ * Purpose: Test that long links are correctly _not_ put into compact
+ * form.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 18, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+long_compact(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t gid2 = (-1); /* Group ID */
+ char *objname; /* Object name */
+ char filename[NAME_BUF_SIZE];
+ off_t empty_size; /* Size of an empty file */
+ off_t file_size; /* Size of each file created */
+
+ TESTING("long link names in compact groups");
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Get size of file as empty */
+ if((empty_size = h5_get_file_size(filename)) == 0) TEST_ERROR
+
+ /* Construct very long object name template */
+ if((objname = HDmalloc(LONG_COMPACT_LENGTH+1)) == NULL) TEST_ERROR
+ HDmemset(objname, 'a', LONG_COMPACT_LENGTH);
+ objname[LONG_COMPACT_LENGTH] = '\0';
+
+ /* Re-open file */
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Create top group */
+ if((gid = H5Gcreate(fid, "top", (size_t)0)) < 0) TEST_ERROR
+
+ /* Use internal testing routine to check that the group has no links or symbol table */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR
+
+ /* Create first group with "long" name */
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ /* (Should have symbol table to hold links, since name is too long for object header message) */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Create second group with "long" name */
+ objname[0] = 'b';
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ /* (Should have symbol table to hold links, since name is too long for object header message) */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Unlink second object from top group */
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ /* (Should still be symbol table to hold links, since name is too long for object header message) */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Unlink first object from top group */
+ objname[0] = 'a';
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ /* (Should have deleted the symbol table now) */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR;
+
+ /* Free object name */
+ HDfree(objname);
+
+ /* Close top group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Unlink top group */
+ if(H5Gunlink(fid, "top") < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Get size of file as empty */
+ if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR;
+
+ /* Verify that file is correct size */
+ if(file_size != empty_size) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return 1;
+} /* end long_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: read_old
+ *
+ * Purpose: Test reading a file with "old style" (symbol table) groups
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 24, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+read_old(hid_t fapl)
+{
+ int fd_old = (-1), fd_new = (-1); /* File descriptors for copying data */
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t gid2 = (-1); /* Group ID */
+ char buf[READ_OLD_BUFSIZE]; /* Buffer for copying data */
+ ssize_t nread; /* Number of bytes read in */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ unsigned u; /* Local index variable */
+ char *srcdir = HDgetenv("srcdir"); /* where the src code is located */
+ char filename[512]=""; /* old test file name */
+ char filename2[NAME_BUF_SIZE]; /* copy of old test file */
+
+ TESTING("reading old groups");
+
+ /* Generate correct name for test file by prepending the source path */
+ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(FILE_OLD_GROUPS) + 1) < sizeof(filename))) {
+ HDstrcpy(filename, srcdir);
+ HDstrcat(filename, "/");
+ }
+ HDstrcat(filename, FILE_OLD_GROUPS);
+
+ /* Create filename */
+ h5_fixname(FILENAME[1], fapl, filename2, sizeof(filename2));
+
+ /* Copy old file into temporary file */
+ if((fd_old = HDopen(filename, O_RDONLY, 0666)) < 0) TEST_ERROR
+ if((fd_new = HDopen(filename2, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) TEST_ERROR
+
+ /* Copy data */
+ while((nread = HDread(fd_old, buf, (size_t)READ_OLD_BUFSIZE)) > 0)
+ HDwrite(fd_new, buf, (size_t)nread);
+
+ /* Close files */
+ if(HDclose(fd_old) < 0) TEST_ERROR
+ if(HDclose(fd_new) < 0) TEST_ERROR
+
+
+ /* Open copied file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Attempt to open "old" group */
+ if((gid = H5Gopen(fid, "old")) < 0) TEST_ERROR
+
+ /* Check on old group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Create a bunch of objects in the group */
+ for(u = 0; u < READ_OLD_NGROUPS; u++) {
+ sprintf(objname, "Group %u", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on old group's status */
+ /* (Should stay in old "symbol table" form) */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Delete new objects from old group */
+ for(u = 0; u < READ_OLD_NGROUPS; u++) {
+ sprintf(objname, "Group %u", u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on old group's status */
+ /* (Should stay in old "symbol table" form) */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR
+
+ /* Close old group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return 1;
+} /* end read_old() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: no_compact
+ *
+ * Purpose: Test that its possible to create groups that don't use the
+ * compact form directly (and don't use link messages).
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 25, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+no_compact(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t gid2 = (-1); /* Datatype ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ char filename[NAME_BUF_SIZE];
+ off_t empty_size; /* Size of an empty file */
+ off_t file_size; /* Size of each file created */
+
+ TESTING("group without compact form");
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ /* Get size of file as empty */
+ if((empty_size = h5_get_file_size(filename)) == 0) TEST_ERROR;
+
+ /* Re-open file */
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR;
+
+ /* Set up group creation property list */
+ if((gcpl = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR;
+
+ /* Set GCPL parameters */
+ if(H5Pset_link_phase_change(gcpl, NO_COMPACT_MAX_COMPACT, NO_COMPACT_MIN_DENSE) < 0) TEST_ERROR;
+
+ /* Create group for testing lifecycle */
+ if((gid = H5Gcreate_expand(fid, NO_COMPACT_TOP_GROUP, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Use internal testing routine to check that the group has no links or symbol table */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR;
+
+ /* Create first "bottom" group */
+ sprintf(objname, NO_COMPACT_BOTTOM_GROUP, (unsigned)0);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+
+ /* Check on bottom group's status */
+ if(H5G_is_empty_test(gid2) != TRUE) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Unlink object from top group */
+ sprintf(objname, NO_COMPACT_BOTTOM_GROUP, (unsigned)0);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+
+ /* Check on top group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close top group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Unlink top group */
+ if(H5Gunlink(fid, NO_COMPACT_TOP_GROUP) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ /* Get size of file as empty */
+ if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR;
+
+ /* Verify that file is correct size */
+ if(file_size != empty_size) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gcpl);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return 1;
+} /* end no_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: gcpl_on_root
+ *
+ * Purpose: Test setting group creation properties for root group.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 25, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+gcpl_on_root(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t gid2 = (-1); /* Datatype ID */
+ hid_t fcpl = (-1); /* File creation property list ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("setting root group creation properties");
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
+
+ /* Set up file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR;
+
+ /* Set GCPL parameters */
+ if(H5Pset_link_phase_change(fcpl, GCPL_ON_ROOT_MAX_COMPACT, GCPL_ON_ROOT_MIN_DENSE) < 0) TEST_ERROR;
+
+ /* Query the group creation properties from the FCPL */
+ if(H5Pget_link_phase_change(fcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != GCPL_ON_ROOT_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != GCPL_ON_ROOT_MIN_DENSE) TEST_ERROR;
+
+ /* Create file with modified root group creation properties */
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR;
+
+ /* Close FCPL */
+ if(H5Pclose(fcpl) < 0) TEST_ERROR;
+
+ /* Open the root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR;
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR;
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != GCPL_ON_ROOT_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != GCPL_ON_ROOT_MIN_DENSE) TEST_ERROR;
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Create a group creation property list, with intermediate group creation set */
+ if((gcpl = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR;
+ if(H5Pset_create_intermediate_group(gcpl, TRUE) < 0) TEST_ERROR
+
+ /* Create a group and intermediate groups, to check if root group settings are inherited */
+ if((gid2 = H5Gcreate_expand(gid, GCPL_ON_ROOT_BOTTOM_GROUP, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid2)) < 0) TEST_ERROR;
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != H5G_CRT_GINFO_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != H5G_CRT_GINFO_MIN_DENSE) TEST_ERROR;
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Open the middle group */
+ if((gid2 = H5Gopen(fid, GCPL_ON_ROOT_MIDDLE_GROUP)) < 0) TEST_ERROR;
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid2)) < 0) TEST_ERROR;
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR;
+ if(max_compact != GCPL_ON_ROOT_MAX_COMPACT) TEST_ERROR;
+ if(min_dense != GCPL_ON_ROOT_MIN_DENSE) TEST_ERROR;
+
+ /* Close GCPL */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR;
+
+ /* Close bottom group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gcpl);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Gclose(fcpl);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return 1;
+} /* end gcpl_on_root() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test groups
@@ -258,6 +969,11 @@ main(void)
nerrors += test_misc(file);
nerrors += test_long(file);
nerrors += test_large(file);
+ nerrors += lifecycle(fapl);
+ nerrors += long_compact(fapl);
+ nerrors += read_old(fapl);
+ nerrors += no_compact(fapl);
+ nerrors += gcpl_on_root(fapl);
if (nerrors) goto error;
/* Cleanup */