summaryrefslogtreecommitdiffstats
path: root/test/ohdr.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-05-24 18:36:53 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-05-24 18:36:53 (GMT)
commitfa133cfb95c052f3b96b0a5089b98491b77628ef (patch)
treefb9226aa6db5511279a07f2486144ae3f2e88436 /test/ohdr.c
parent415889bef3df70552a389214ca2ed241aa12e379 (diff)
downloadhdf5-fa133cfb95c052f3b96b0a5089b98491b77628ef.zip
hdf5-fa133cfb95c052f3b96b0a5089b98491b77628ef.tar.gz
hdf5-fa133cfb95c052f3b96b0a5089b98491b77628ef.tar.bz2
[svn-r13808] Description:
Fix possible file corruption when using "new" format object headers and the size of chunk #0 for an object header transitions between needing 1->2->4->8- byte encoding for the size and there are "clean" messages in the object header already. (Usually triggered by flushing the file while adding attributes to an object) Tested on: Mac OS X/32 10.4.9 (amazon) Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2)
Diffstat (limited to 'test/ohdr.c')
-rw-r--r--test/ohdr.c424
1 files changed, 234 insertions, 190 deletions
diff --git a/test/ohdr.c b/test/ohdr.c
index 73ede43..d4b6ea4 100644
--- a/test/ohdr.c
+++ b/test/ohdr.c
@@ -67,240 +67,284 @@ main(void)
hid_t dset=-1;
H5F_t *f=NULL;
char filename[1024];
+ H5O_info_t oinfo; /* Object info */
H5O_loc_t oh_loc;
time_t time_new, ro;
int i;
+ hbool_t b; /* Index for "new format" loop */
const char *envval = NULL;
/* Reset library */
h5_reset();
fapl = h5_fileaccess();
h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
- if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
- if(NULL == (f = H5I_object(file))) FAIL_STACK_ERROR
-
-
- /*
- * Test object header creation
- * (using default group creation property list only because it's convenient)
- */
- TESTING("object header creation");
- HDmemset(&oh_loc, 0, sizeof(oh_loc));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
- FAIL_STACK_ERROR
- PASSED();
-
-
- /* create a new message */
- TESTING("message creation");
- time_new = 11111111;
- if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
- FAIL_STACK_ERROR
- if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
- FAIL_STACK_ERROR
- if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
- FAIL_STACK_ERROR
- if(ro != time_new)
- TEST_ERROR
- PASSED();
-
-
- /*
- * Test modification of an existing message.
- */
- TESTING("message modification");
- time_new = 33333333;
- if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
- FAIL_STACK_ERROR
- if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
- FAIL_STACK_ERROR
- if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
- FAIL_STACK_ERROR
- if(ro != time_new)
- TEST_ERROR
- PASSED();
-
-
- /*
- * Test creation of a bunch of messages one after another to see
- * what happens when the object header overflows in core.
- * (Use 'old' MTIME message here, because it is large enough to be
- * replaced with a continuation message (the new one is too small)
- * and the library doesn't understand how to migrate more than one
- * message from an object header currently - QAK - 10/8/03)
- */
- TESTING("object header overflow in memory");
- for(i = 0; i < 40; i++) {
- time_new = (i + 1) * 1000 + 1;
- if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
+
+ /* Loop over old & new formats */
+ for(b = FALSE; b <= TRUE; b++) {
+ /* Display info about testing */
+ if(b)
+ HDputs("Using new file format");
+ else
+ HDputs("Using default file format");
+
+ /* Set the format to use for the file */
+ if (H5Pset_latest_format(fapl, b) < 0) FAIL_STACK_ERROR
+
+ /* Create the file to operate on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+ if(NULL == (f = H5I_object(file))) FAIL_STACK_ERROR
+
+
+ /*
+ * Test object header creation
+ * (using default group creation property list only because it's convenient)
+ */
+ TESTING("object header creation");
+ HDmemset(&oh_loc, 0, sizeof(oh_loc));
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
FAIL_STACK_ERROR
- } /* end for */
- if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
- FAIL_STACK_ERROR
- PASSED();
-
-
- /*
- * Test creation of a bunch of messages one after another to see
- * what happens when the object header overflows on disk.
- */
- TESTING("object header overflow on disk");
- for(i = 0; i < 10; i++) {
- time_new = (i + 1) * 1000 + 10;
+ PASSED();
+
+
+ /* create a new message */
+ TESTING("message creation");
+ time_new = 11111111;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
FAIL_STACK_ERROR
- } /* end for */
- PASSED();
-
-
- /*
- * Delete all time messages.
- */
- TESTING("message deletion");
- if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
- FAIL_STACK_ERROR
- if(H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
- FAIL_STACK_ERROR
- if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
- FAIL_STACK_ERROR
- if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT))
- FAIL_STACK_ERROR
- PASSED();
-
-
- /* release resources */
- TESTING("object header closing");
- if(H5O_close(&oh_loc) < 0)
- FAIL_STACK_ERROR
- PASSED();
-
-
- /* Test reading datasets with undefined object header messages */
- puts("Reading objects with unknown header messages");
- envval = HDgetenv("HDF5_DRIVER");
- if(envval == NULL)
- envval = "nomatch";
- if(HDstrcmp(envval, "core") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "split") && HDstrcmp(envval, "family")) {
- hid_t file2; /* File ID for 'bogus' object file */
- char testpath[512] = "";
- char testfile[512] = "";
- char *srcdir = HDgetenv("srcdir");
-
- /* Build path to all test files */
- if(srcdir && ((HDstrlen(srcdir) + 2) < sizeof(testpath))) {
- HDstrcpy(testpath, srcdir);
- HDstrcat(testpath, "/");
- } /* end if */
-
- /* Build path to test file */
- if(srcdir && ((HDstrlen(testpath) + HDstrlen(FILE_BOGUS) + 1) < sizeof(testfile)))
- HDstrcpy(testfile, testpath);
- HDstrcat(testfile, FILE_BOGUS);
+ if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
+ if(ro != time_new)
+ TEST_ERROR
+ PASSED();
- TESTING("object with unknown header message and no flags set");
- /* Open the file with objects that have unknown header messages (generated with gen_bogus.c) */
- if((file2 = H5Fopen(testfile, H5F_ACC_RDONLY, fapl)) < 0)
+ /*
+ * Test modification of an existing message.
+ */
+ TESTING("message modification");
+ time_new = 33333333;
+ if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
+ FAIL_STACK_ERROR
+ if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
+ if(ro != time_new)
TEST_ERROR
- /* Open the dataset with the unknown header message, but no extra flags */
- if((dset = H5Dopen(file2, "/Dataset1")) < 0)
- TEST_ERROR
- if(H5Dclose(dset) < 0)
+ /* Make certain that chunk #0 in the object header can be encoded with a 1-byte size */
+ if(H5O_get_info(&oh_loc, &oinfo, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(oinfo.hdr.space.total >=256)
TEST_ERROR
PASSED();
- TESTING("object with unknown header message & 'fail if unknown' flag set");
+ /*
+ * Test creation of a bunch of messages one after another to see
+ * what happens when the object header overflows in core.
+ * (Use 'old' MTIME message here, because it is large enough to be
+ * replaced with a continuation message (the new one is too small)
+ * and the library doesn't understand how to migrate more than one
+ * message from an object header currently - QAK - 10/8/03)
+ */
+ TESTING("object header overflow in memory");
+ for(i = 0; i < 40; i++) {
+ time_new = (i + 1) * 1000 + 1;
+ if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ } /* end for */
+ if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
+ FAIL_STACK_ERROR
- /* Attempt to open the dataset with the unknown header message, and "fail if unknown" flag */
- H5E_BEGIN_TRY {
- dset = H5Dopen(file2, "/Dataset2");
- } H5E_END_TRY;
- if(dset >= 0) {
- H5Dclose(dset);
+ /* Make certain that chunk #0 in the object header will be encoded with a 2-byte size */
+ if(H5O_get_info(&oh_loc, &oinfo, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(oinfo.hdr.space.total < 256)
TEST_ERROR
- } /* end if */
PASSED();
- TESTING("object with unknown header message & 'mark if unknown' flag set");
-
- /* Copy object with "mark if unknown" flag on message into file that can be modified */
- if(H5Ocopy(file2, "/Dataset3", file, "/Dataset3", H5P_DEFAULT, H5P_DEFAULT) < 0)
- TEST_ERROR
-
- /* Close the file we created (to flush changes to file) */
+ /* Close & re-open file & object header */
+ /* (makes certain that an object header in the new format that transitions
+ * between 1-byte chunk #0 size encoding and 2-byte chunk #0 size encoding
+ * works correctly - QAK)
+ */
+ if(H5O_close(&oh_loc) < 0)
+ FAIL_STACK_ERROR
if(H5Fclose(file) < 0)
- TEST_ERROR
+ FAIL_STACK_ERROR
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+ oh_loc.file = f;
+ if(H5O_open(&oh_loc) < 0)
+ FAIL_STACK_ERROR
- /* Re-open the file created, with read-only permissions */
- if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
- TEST_ERROR
+ /*
+ * Test creation of a bunch of messages one after another to see
+ * what happens when the object header overflows on disk.
+ */
+ TESTING("object header overflow on disk");
+ for(i = 0; i < 10; i++) {
+ time_new = (i + 1) * 1000 + 10;
+ if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
+ FAIL_STACK_ERROR
+ } /* end for */
+ PASSED();
- /* Open the dataset with the "mark if unknown" message */
- if((dset = H5Dopen(file, "/Dataset3")) < 0)
- TEST_ERROR
+ /*
+ * Delete all time messages.
+ */
+ TESTING("message deletion");
+ if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
+ if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
+ PASSED();
- /* Check that the "unknown" message was _NOT_ marked */
- if(H5O_check_msg_marked_test(dset, FALSE) < 0)
+
+ /* release resources */
+ TESTING("object header closing");
+ if(H5O_close(&oh_loc) < 0)
FAIL_STACK_ERROR
+ PASSED();
- /* Close the dataset */
- if(H5Dclose(dset) < 0)
- TEST_ERROR
- /* Close the file we created (to flush change to object header) */
- if(H5Fclose(file) < 0)
- TEST_ERROR
+ /* Test reading datasets with undefined object header messages */
+ puts("Reading objects with unknown header messages");
+ envval = HDgetenv("HDF5_DRIVER");
+ if(envval == NULL)
+ envval = "nomatch";
+ if(HDstrcmp(envval, "core") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "split") && HDstrcmp(envval, "family")) {
+ hid_t file2; /* File ID for 'bogus' object file */
+ char testpath[512] = "";
+ char testfile[512] = "";
+ char *srcdir = HDgetenv("srcdir");
- /* Re-open the file created */
- if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
- TEST_ERROR
+ /* Build path to all test files */
+ if(srcdir && ((HDstrlen(srcdir) + 2) < sizeof(testpath))) {
+ HDstrcpy(testpath, srcdir);
+ HDstrcat(testpath, "/");
+ } /* end if */
- /* Open the dataset with the "mark if unknown" message */
- if((dset = H5Dopen(file, "/Dataset3")) < 0)
- TEST_ERROR
- if(H5Dclose(dset) < 0)
- TEST_ERROR
+ /* Build path to test file */
+ if(srcdir && ((HDstrlen(testpath) + HDstrlen(FILE_BOGUS) + 1) < sizeof(testfile)))
+ HDstrcpy(testfile, testpath);
+ HDstrcat(testfile, FILE_BOGUS);
- /* Close the file we created (to flush change to object header) */
- if(H5Fclose(file) < 0)
- TEST_ERROR
+ TESTING("object with unknown header message and no flags set");
- /* Re-open the file created */
- if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
- TEST_ERROR
+ /* Open the file with objects that have unknown header messages (generated with gen_bogus.c) */
+ if((file2 = H5Fopen(testfile, H5F_ACC_RDONLY, fapl)) < 0)
+ TEST_ERROR
- /* Re-open the dataset with the "mark if unknown" message */
- if((dset = H5Dopen(file, "/Dataset3")) < 0)
- TEST_ERROR
+ /* Open the dataset with the unknown header message, but no extra flags */
+ if((dset = H5Dopen(file2, "/Dataset1")) < 0)
+ TEST_ERROR
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR
- /* Check that the "unknown" message was marked */
- if(H5O_check_msg_marked_test(dset, TRUE) < 0)
- FAIL_STACK_ERROR
+ PASSED();
- /* Close the dataset */
- if(H5Dclose(dset) < 0)
- TEST_ERROR
+ TESTING("object with unknown header message & 'fail if unknown' flag set");
+ /* Attempt to open the dataset with the unknown header message, and "fail if unknown" flag */
+ H5E_BEGIN_TRY {
+ dset = H5Dopen(file2, "/Dataset2");
+ } H5E_END_TRY;
+ if(dset >= 0) {
+ H5Dclose(dset);
+ TEST_ERROR
+ } /* end if */
- /* Close the file with the bogus objects */
- if(H5Fclose(file2) < 0)
- TEST_ERROR
+ PASSED();
- PASSED();
- } /* end if */
- else {
- SKIPPED();
- puts(" Test not compatible with current Virtual File Driver");
- } /* end else */
-
- /* Close the file we created */
- if(H5Fclose(file) < 0)
- TEST_ERROR
+ TESTING("object with unknown header message & 'mark if unknown' flag set");
+
+ /* Copy object with "mark if unknown" flag on message into file that can be modified */
+ if(H5Ocopy(file2, "/Dataset3", file, "/Dataset3", H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ /* Close the file we created (to flush changes to file) */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* Re-open the file created, with read-only permissions */
+ if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
+ TEST_ERROR
+
+ /* Open the dataset with the "mark if unknown" message */
+ if((dset = H5Dopen(file, "/Dataset3")) < 0)
+ TEST_ERROR
+
+ /* Check that the "unknown" message was _NOT_ marked */
+ if(H5O_check_msg_marked_test(dset, FALSE) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the dataset */
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR
+
+ /* Close the file we created (to flush change to object header) */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* Re-open the file created */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ TEST_ERROR
+
+ /* Open the dataset with the "mark if unknown" message */
+ if((dset = H5Dopen(file, "/Dataset3")) < 0)
+ TEST_ERROR
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR
+
+ /* Close the file we created (to flush change to object header) */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* Re-open the file created */
+ if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
+ TEST_ERROR
+
+ /* Re-open the dataset with the "mark if unknown" message */
+ if((dset = H5Dopen(file, "/Dataset3")) < 0)
+ TEST_ERROR
+
+ /* Check that the "unknown" message was marked */
+ if(H5O_check_msg_marked_test(dset, TRUE) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the dataset */
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR
+
+
+ /* Close the file with the bogus objects */
+ if(H5Fclose(file2) < 0)
+ TEST_ERROR
+
+ PASSED();
+ } /* end if */
+ else {
+ SKIPPED();
+ puts(" Test not compatible with current Virtual File Driver");
+ } /* end else */
+
+ /* Close the file we created */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+ } /* end for */
puts("All object header tests passed.");
h5_cleanup(FILENAME, fapl);