1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /* Programmer: Robb Matzke <matzke@llnl.gov>
15 * Tuesday, November 24, 1998
16 */
17 #include "h5test.h"
18 #include "H5srcdir.h"
19 #include "H5Iprivate.h"
20
21 /*
22 * This file needs to access private datatypes from the H5O package.
23 * This file also needs to access the object header testing code.
24 */
25 #define H5O_PACKAGE
26 #define H5O_TESTING
27 #include "H5Opkg.h"
28
29 /*
30 * This file needs to access private datatypes from the H5G package.
31 */
32 #define H5G_PACKAGE
33 #include "H5Gpkg.h"
34
35 const char *FILENAME[] = {
36 "ohdr",
37 NULL
38 };
39
40 /* The tbogus.h5 is generated from gen_bogus.c in HDF5 'test' directory.
41 * To get this data file, define H5O_ENABLE_BOGUS in src/H5Oprivate, rebuild
42 * the library and simply compile gen_bogus.c with that HDF5 library and run it.
43 */
44 #define FILE_BOGUS "tbogus.h5"
45
46 /*
47 * Verify that messages are moved forward into a "continuation message":
48 * Create an object header with several continuation chunks
49 * Remove a message in the last chunk
50 * The remaining message(s) in the last chunk should be moved forward into the continuation message
51 * The process will repeat when the continuation message is big enough to hold all the
52 * messages in the last chunk.
53 * Result: the number of chunks should be reduced
54 */
55 static herr_t
test_cont(char * filename,hid_t fapl)56 test_cont(char *filename, hid_t fapl)
57 {
58 hid_t file=-1;
59 H5F_t *f = NULL;
60 H5O_hdr_info_t hdr_info;
61 H5O_loc_t oh_locA, oh_locB;
62 time_t time_new;
63 const char *short_name = "T";
64 const char *long_name = "This is the message";
65 size_t nchunks;
66
67 TESTING("object header continuation block");
68
69 HDmemset(&oh_locA, 0, sizeof(oh_locA));
70 HDmemset(&oh_locB, 0, sizeof(oh_locB));
71
72 /* Create the file to operate on */
73 if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
74 if(NULL == (f = (H5F_t *)H5I_object(file))) FAIL_STACK_ERROR
75
76 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locA/*out*/) < 0)
77 FAIL_STACK_ERROR
78
79 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locB/*out*/) < 0)
80 FAIL_STACK_ERROR
81
82 time_new = 11111111;
83
84 if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &long_name, H5P_DATASET_XFER_DEFAULT) < 0)
85 FAIL_STACK_ERROR
86
87 if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
88 FAIL_STACK_ERROR
89 if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
90 FAIL_STACK_ERROR
91 if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
92 FAIL_STACK_ERROR
93
94 if(H5O_msg_create(&oh_locA, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
95 FAIL_STACK_ERROR
96
97 if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
98 FAIL_STACK_ERROR
99
100 if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &short_name, H5P_DATASET_XFER_DEFAULT) < 0)
101 FAIL_STACK_ERROR
102
103 if(1 != H5O_link(&oh_locA, 1, H5P_DATASET_XFER_DEFAULT))
104 FAIL_STACK_ERROR
105 if(1 != H5O_link(&oh_locB, 1, H5P_DATASET_XFER_DEFAULT))
106 FAIL_STACK_ERROR
107 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
108 FAIL_STACK_ERROR
109 if(H5O_expunge_chunks_test(&oh_locA, H5P_DATASET_XFER_DEFAULT) < 0)
110 FAIL_STACK_ERROR
111
112 if(H5O_get_hdr_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
113 FAIL_STACK_ERROR
114 nchunks = hdr_info.nchunks;
115
116 /* remove the 1st H5O_NAME_ID message */
117 if(H5O_msg_remove(&oh_locA, H5O_NAME_ID, 0, FALSE, H5P_DATASET_XFER_DEFAULT) < 0)
118 FAIL_STACK_ERROR
119
120 if(H5O_get_hdr_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
121 FAIL_STACK_ERROR
122
123 if(hdr_info.nchunks >= nchunks)
124 TEST_ERROR
125
126 if(H5O_close(&oh_locA) < 0)
127 FAIL_STACK_ERROR
128 if(H5O_close(&oh_locB) < 0)
129 FAIL_STACK_ERROR
130 if(H5Fclose(file) < 0)
131 FAIL_STACK_ERROR
132
133 PASSED();
134
135
136 return 0;
137
138 error:
139 H5E_BEGIN_TRY {
140 H5O_close(&oh_locA);
141 H5O_close(&oh_locB);
142 H5Fclose(file);
143 } H5E_END_TRY;
144
145 return -1;
146 } /* test_cont() */
147
148 /*
149 * Verify that object headers are held in the cache until they are linked
150 * to a location in the graph, or assigned an ID. This is done by
151 * creating an object header, then forcing it out of the cache by creating
152 * local heaps until the object header is evicted from the cache, then
153 * modifying the object header. The refcount on the object header is
154 * checked as verifying that the object header has remained in the cache.
155 */
156 static herr_t
test_ohdr_cache(char * filename,hid_t fapl)157 test_ohdr_cache(char *filename, hid_t fapl)
158 {
159 hid_t file = -1; /* File ID */
160 hid_t my_fapl; /* FAPL ID */
161 hid_t my_dxpl; /* DXPL ID */
162 H5AC_cache_config_t mdc_config; /* Metadata cache configuration info */
163 H5F_t *f = NULL; /* File handle */
164 H5HL_t *lheap, *lheap2, *lheap3; /* Pointer to local heaps */
165 haddr_t lheap_addr, lheap_addr2, lheap_addr3; /* Local heap addresses */
166 H5O_loc_t oh_loc; /* Object header location */
167 time_t time_new; /* Time value for modification time message */
168 unsigned rc; /* Refcount for object */
169
170 TESTING("object header creation in cache");
171
172 /* Make a copy of the FAPL */
173 if((my_fapl = H5Pcopy(fapl)) < 0)
174 FAIL_STACK_ERROR
175
176 /* Tweak down the size of the metadata cache to only 64K */
177 mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
178 if(H5Pget_mdc_config(my_fapl, &mdc_config) < 0)
179 FAIL_STACK_ERROR
180 mdc_config.set_initial_size = TRUE;
181 mdc_config.initial_size = 32 * 1024;
182 mdc_config.max_size = 64 * 1024;
183 mdc_config.min_size = 8 * 1024;
184 if(H5Pset_mdc_config(my_fapl, &mdc_config) < 0)
185 FAIL_STACK_ERROR
186
187 /* Make a copy of the default DXPL */
188 if((my_dxpl = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0)
189 FAIL_STACK_ERROR
190
191 /* Create the file to operate on */
192 if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
193 FAIL_STACK_ERROR
194 if(H5Pclose(my_fapl) < 0)
195 FAIL_STACK_ERROR
196 if(NULL == (f = (H5F_t *)H5I_object(file)))
197 FAIL_STACK_ERROR
198
199 /* Create object (local heap) that occupies most of cache */
200 if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr) < 0)
201 FAIL_STACK_ERROR
202
203 /* Protect local heap (which actually pins it in the cache) */
204 if(NULL == (lheap = H5HL_protect(f, my_dxpl, lheap_addr, H5AC_READ)))
205 FAIL_STACK_ERROR
206
207 /* Create an object header */
208 HDmemset(&oh_loc, 0, sizeof(oh_loc));
209 if(H5O_create(f, my_dxpl, (size_t)2048, (size_t)1, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
210 FAIL_STACK_ERROR
211
212 /* Query object header information */
213 rc = 0;
214 if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
215 FAIL_STACK_ERROR
216 if(0 != rc)
217 TEST_ERROR
218
219 /* Create object (local heap) that occupies most of cache */
220 if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr2) < 0)
221 FAIL_STACK_ERROR
222
223 /* Protect local heap (which actually pins it in the cache) */
224 if(NULL == (lheap2 = H5HL_protect(f, my_dxpl, lheap_addr2, H5AC_READ)))
225 FAIL_STACK_ERROR
226
227 /* Unprotect local heap (which actually unpins it from the cache) */
228 if(H5HL_unprotect(lheap2) < 0)
229 FAIL_STACK_ERROR
230
231 /* Create object header message in new object header */
232 time_new = 11111111;
233 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, my_dxpl) < 0)
234 FAIL_STACK_ERROR
235
236 /* Create object (local heap) that occupies most of cache */
237 if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr3) < 0)
238 FAIL_STACK_ERROR
239
240 /* Protect local heap (which actually pins it in the cache) */
241 if(NULL == (lheap3 = H5HL_protect(f, my_dxpl, lheap_addr3, H5AC_READ)))
242 FAIL_STACK_ERROR
243
244 /* Unprotect local heap (which actually unpins it from the cache) */
245 if(H5HL_unprotect(lheap3) < 0)
246 FAIL_STACK_ERROR
247
248 /* Query object header information */
249 /* (Note that this is somewhat of a weak test, since it doesn't actually
250 * verify that the object header was evicted from the cache, but it's
251 * very difficult to verify when an entry is evicted from the cache in
252 * a non-invasive way -QAK)
253 */
254 rc = 0;
255 if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
256 FAIL_STACK_ERROR
257 if(0 != rc)
258 TEST_ERROR
259
260 /* Decrement reference count o object header */
261 if(H5O_dec_rc_by_loc(&oh_loc, my_dxpl) < 0)
262 FAIL_STACK_ERROR
263
264 /* Close object header created */
265 if(H5O_close(&oh_loc) < 0)
266 FAIL_STACK_ERROR
267
268 /* Unprotect local heap (which actually unpins it from the cache) */
269 if(H5HL_unprotect(lheap) < 0)
270 FAIL_STACK_ERROR
271
272 if(H5Pclose(my_dxpl) < 0)
273 FAIL_STACK_ERROR
274 if(H5Fclose(file) < 0)
275 FAIL_STACK_ERROR
276
277 PASSED();
278
279 return 0;
280
281 error:
282 H5E_BEGIN_TRY {
283 H5Fclose(file);
284 } H5E_END_TRY;
285
286 return -1;
287 } /* test_ohdr_cache() */
288
289 /*
290 * To test objects with unknown messages in a file with:
291 * a) H5O_BOGUS_VALID_ID:
292 * --the bogus_id is within the range of H5O_msg_class_g[]
293 * b) H5O_BOGUS_INVALID_ID:
294 * --the bogus_id is outside the range of H5O_msg_class_g[]
295 *
296 * The test file is FILE_BOGUS: "tbogus.h5" generated with gen_bogus.c
297 * --objects that have unknown header messages with H5O_BOGUS_VALID_ID in "/"
298 * --objects that have unknown header messages with H5O_BOGUS_INVALID_ID in "/group"
299 *
300 * The test also uses the test file FILENAME[0] (ohdr.h5): the parameter "filename"
301 */
302 static herr_t
test_unknown(unsigned bogus_id,char * filename,hid_t fapl)303 test_unknown(unsigned bogus_id, char *filename, hid_t fapl)
304 {
305 hid_t fid = -1; /* file ID */
306 hid_t gid = -1; /* group ID */
307 hid_t did = -1; /* Dataset ID */
308 hid_t sid = -1; /* Dataspace ID */
309 hid_t aid = -1; /* Attribute ID */
310 hid_t loc = -1; /* location: file or group ID */
311 hid_t fid_bogus = -1; /* bogus file ID */
312 hid_t gid_bogus = -1; /* bogus group ID */
313 hid_t loc_bogus = -1; /* location: bogus file or group ID */
314 char testfile[256];
315
316 /* create a different name for a local copy of the data file to be
317 opened with rd/wr file permissions in case build and test are
318 done in the source directory. */
319 HDstrncpy(testfile, FILE_BOGUS, strlen(FILE_BOGUS));
320 testfile[strlen(FILE_BOGUS)]='\0';
321 HDstrncat(testfile, ".copy", 5);
322
323 /* Make a copy of the data file from svn. */
324 if(h5_make_local_copy(FILE_BOGUS, testfile) < 0)
325 FAIL_STACK_ERROR
326
327 TESTING("object with unknown header message and no flags set");
328
329 /* Open filename */
330 if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
331 FAIL_STACK_ERROR
332
333 /* Open FILE_BOGUS */
334 if((fid_bogus = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
335 FAIL_STACK_ERROR
336
337 /* Set up location ID depending on bogus_id */
338 if(bogus_id == H5O_BOGUS_INVALID_ID) {
339 /* Open "group" in FILE_BOGUS */
340 if((gid_bogus = H5Gopen2(fid_bogus, "group", H5P_DEFAULT)) < 0)
341 FAIL_STACK_ERROR
342 loc_bogus = gid_bogus;
343
344 /* Create "group" in filename */
345 if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
346 FAIL_STACK_ERROR
347 loc = gid;
348
349 } else { /* H5O_BOGUS_VALID_ID */
350 loc_bogus = fid_bogus;
351 loc = fid;
352 } /* end else */
353
354 /* Open the dataset with the unknown header message, but no extra flags */
355 if((did = H5Dopen2(loc_bogus, "Dataset1", H5P_DEFAULT)) < 0)
356 FAIL_STACK_ERROR
357 if(H5Dclose(did) < 0)
358 FAIL_STACK_ERROR
359
360 PASSED();
361
362 TESTING("object in r/o file with unknown header message & 'fail if unknown and open for write' flag set");
363
364 /* Open the dataset with the unknown header message, and "fail if unknown and open for write" flag */
365 if((did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT)) < 0)
366 FAIL_STACK_ERROR
367 if(H5Dclose(did) < 0)
368 FAIL_STACK_ERROR
369
370 PASSED();
371
372 /* TESTING("object in r/o file with unknown header message & 'fail if unknown always' flag set"); */
373 /* There is no H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS */
374
375 TESTING("object with unknown header message & 'mark if unknown' flag set");
376
377 /* Copy object with "mark if unknown" flag on message into file (FILENAME[0]) that can be modified */
378 if(H5Ocopy(loc_bogus, "Dataset4", loc, "Dataset4", H5P_DEFAULT, H5P_DEFAULT) < 0)
379 FAIL_STACK_ERROR
380
381 /* Closing: filename */
382 if(bogus_id == H5O_BOGUS_INVALID_ID)
383 if(H5Gclose(gid) < 0)
384 FAIL_STACK_ERROR
385 if(H5Fclose(fid) < 0)
386 FAIL_STACK_ERROR
387
388 /* Re-open filename, with read-only permissions */
389 if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
390 FAIL_STACK_ERROR
391
392 /* Set up location ID depending on bogus_id */
393 if(bogus_id == H5O_BOGUS_INVALID_ID) {
394 /* Open "group" in filename */
395 if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
396 FAIL_STACK_ERROR
397 loc = gid;
398 } else
399 loc = fid;
400
401 /* Open the dataset with the "mark if unknown" message */
402 if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
403 FAIL_STACK_ERROR
404
405 /* Check that the "unknown" message was _NOT_ marked */
406 if(H5O_check_msg_marked_test(did, FALSE) < 0)
407 FAIL_STACK_ERROR
408
409 /* Close the dataset */
410 if(H5Dclose(did) < 0)
411 FAIL_STACK_ERROR
412
413 /* Close "group" in filename depending on bogus_id */
414 if(bogus_id == H5O_BOGUS_INVALID_ID)
415 if(H5Gclose(gid) < 0)
416 FAIL_STACK_ERROR
417
418 /* Close filename (to flush change to object header) */
419 if(H5Fclose(fid) < 0)
420 FAIL_STACK_ERROR
421
422 /* Re-open filename */
423 if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
424 FAIL_STACK_ERROR
425
426 /* Set up location ID depending on bogus_id */
427 if(bogus_id == H5O_BOGUS_INVALID_ID) {
428 /* Open "group" in filename */
429 if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
430 FAIL_STACK_ERROR
431 loc = gid;
432 } else
433 loc = fid;
434
435 /* Open the dataset with the "mark if unknown" message */
436 if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
437 FAIL_STACK_ERROR
438
439 /* Create data space */
440 if((sid = H5Screate(H5S_SCALAR)) < 0)
441 FAIL_STACK_ERROR
442
443 /* Create an attribute, to get the object header into write access */
444 if((aid = H5Acreate2(did, "Attr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
445 FAIL_STACK_ERROR
446
447 /* Close dataspace */
448 if(H5Sclose(sid) < 0)
449 FAIL_STACK_ERROR
450
451 /* Close attribute */
452 if(H5Aclose(aid) < 0)
453 FAIL_STACK_ERROR
454
455 /* Close the dataset */
456 if(H5Dclose(did) < 0)
457 FAIL_STACK_ERROR
458
459 /* Close "group" in filename depending on bogus_id */
460 if(bogus_id == H5O_BOGUS_INVALID_ID)
461 if(H5Gclose(gid) < 0)
462 FAIL_STACK_ERROR
463
464 /* Close filename (to flush change to object header) */
465 if(H5Fclose(fid) < 0)
466 FAIL_STACK_ERROR
467
468 /* Re-open filename */
469 if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
470 FAIL_STACK_ERROR
471
472 /* Set up location ID depending on bogus_id */
473 if(bogus_id == H5O_BOGUS_INVALID_ID) {
474 /* Open "group" in filename */
475 if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
476 FAIL_STACK_ERROR
477 loc = gid;
478 } else
479 loc = fid;
480
481 /* Re-open the dataset with the "mark if unknown" message */
482 if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
483 FAIL_STACK_ERROR
484
485 /* Check that the "unknown" message was marked */
486 if(H5O_check_msg_marked_test(did, TRUE) < 0)
487 FAIL_STACK_ERROR
488
489 /* Close the dataset */
490 if(H5Dclose(did) < 0)
491 FAIL_STACK_ERROR
492
493 /* Closing: filename */
494 if(bogus_id == H5O_BOGUS_INVALID_ID)
495 if(H5Gclose(gid) < 0)
496 FAIL_STACK_ERROR
497 if(H5Fclose(fid) < 0)
498 FAIL_STACK_ERROR
499
500 PASSED();
501
502 /* Closing: FILE_BOGUS */
503 if(bogus_id == H5O_BOGUS_INVALID_ID)
504 if(H5Gclose(gid_bogus) < 0)
505 FAIL_STACK_ERROR
506 if(H5Fclose(fid_bogus) < 0)
507 FAIL_STACK_ERROR
508
509 TESTING("object in r/w file with unknown header message & 'fail if unknown and open for write' flag set");
510
511 /* Open FILE_BOGUS with RW intent this time */
512 if((fid_bogus = H5Fopen(testfile, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
513 FAIL_STACK_ERROR
514
515 /* Set up location ID */
516 if(bogus_id == H5O_BOGUS_INVALID_ID) {
517 /* Open "group" in FILE_BOGUS */
518 if((gid_bogus = H5Gopen2(fid_bogus, "group", H5P_DEFAULT)) < 0)
519 FAIL_STACK_ERROR
520 loc_bogus = gid_bogus;
521 } else
522 loc_bogus = fid_bogus;
523
524 /* Attempt to open the dataset with the unknown header message, and "fail if unknown and open for write" flag */
525 H5E_BEGIN_TRY {
526 did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT);
527 } H5E_END_TRY;
528 if(did >= 0) {
529 H5Dclose(did);
530 TEST_ERROR
531 } /* end if */
532
533 PASSED();
534
535 /* TESTING("object in r/w file with unknown header message & 'fail if unknown always' flag set"); */
536 /* There is no H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS */
537
538 /* Closing: FILE_BOGUS */
539 if(bogus_id == H5O_BOGUS_INVALID_ID)
540 if(H5Gclose(gid_bogus) < 0)
541 FAIL_STACK_ERROR
542 if(H5Fclose(fid_bogus) < 0)
543 FAIL_STACK_ERROR
544
545 PASSED();
546
547 return SUCCEED;
548
549 error:
550 H5E_BEGIN_TRY {
551 H5Fclose(fid);
552 H5Gclose(gid);
553 H5Fclose(fid_bogus);
554 H5Gclose(gid_bogus);
555 H5Dclose(did);
556 H5Sclose(sid);
557 H5Aclose(aid);
558 } H5E_END_TRY;
559
560 return FAIL;
561 } /* test_unknown() */
562
563
564 /*-------------------------------------------------------------------------
565 * Function: main
566 *
567 * Purpose: Exercise private object header behavior and routines
568 *
569 * Return: Success: 0
570 * Failure: 1
571 *
572 * Programmer: Robb Matzke
573 * Tuesday, November 24, 1998
574 *
575 *-------------------------------------------------------------------------
576 */
577 int
main(void)578 main(void)
579 {
580 hid_t fapl = -1, file = -1;
581 hid_t dset = -1;
582 H5F_t *f = NULL;
583 char filename[1024];
584 H5O_hdr_info_t hdr_info; /* Object info */
585 H5O_loc_t oh_loc, oh_loc2; /* Object header locations */
586 time_t time_new, ro;
587 int chunkno; /* Chunk index for message */
588 int i; /* Local index variable */
589 hbool_t b; /* Index for "new format" loop */
590 herr_t ret; /* Generic return value */
591
592 /* Reset library */
593 h5_reset();
594 fapl = h5_fileaccess();
595 h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
596
597 /* Loop over old & new formats */
598 for(b = FALSE; b <= TRUE; b++) {
599 /* Display info about testing */
600 if(b)
601 HDputs("Using new file format:");
602 else
603 HDputs("Using default file format:");
604
605 /* Set the format to use for the file */
606 if(H5Pset_libver_bounds(fapl, (b ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST) < 0)
607 FAIL_STACK_ERROR
608
609 /* test on object continuation block */
610 if(test_cont(filename, fapl) < 0)
611 FAIL_STACK_ERROR
612
613 /* Create the file to operate on */
614 if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
615 TEST_ERROR
616 if(NULL == (f = (H5F_t *)H5I_object(file)))
617 FAIL_STACK_ERROR
618
619
620 /*
621 * Test object header creation
622 * (using default group creation property list only because it's convenient)
623 */
624 TESTING("object header creation");
625 HDmemset(&oh_loc, 0, sizeof(oh_loc));
626 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
627 FAIL_STACK_ERROR
628 PASSED();
629
630
631 /* create a new message */
632 TESTING("message creation");
633 time_new = 11111111;
634 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
635 FAIL_STACK_ERROR
636 if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
637 FAIL_STACK_ERROR
638 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
639 FAIL_STACK_ERROR
640 if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
641 FAIL_STACK_ERROR
642 if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
643 FAIL_STACK_ERROR
644 if(ro != time_new)
645 TEST_ERROR
646 PASSED();
647
648
649 /*
650 * Test modification of an existing message.
651 */
652 TESTING("message modification");
653 time_new = 33333333;
654 if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
655 FAIL_STACK_ERROR
656 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
657 FAIL_STACK_ERROR
658 if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
659 FAIL_STACK_ERROR
660 if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
661 FAIL_STACK_ERROR
662 if(ro != time_new)
663 TEST_ERROR
664
665 /* Make certain that chunk #0 in the object header can be encoded with a 1-byte size */
666 if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
667 FAIL_STACK_ERROR
668 if(hdr_info.space.total >=256)
669 TEST_ERROR
670
671 PASSED();
672
673 /*
674 * Test creation of a bunch of messages one after another to see
675 * what happens when the object header overflows in core.
676 * (Use 'old' MTIME message here, because it is large enough to be
677 * replaced with a continuation message (the new one is too small)
678 * and the library doesn't understand how to migrate more than one
679 * message from an object header currently - QAK - 10/8/03)
680 */
681 TESTING("object header overflow in memory");
682 for(i = 0; i < 40; i++) {
683 time_new = (i + 1) * 1000 + 1000000;
684 if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
685 FAIL_STACK_ERROR
686 } /* end for */
687 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
688 FAIL_STACK_ERROR
689 if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
690 FAIL_STACK_ERROR
691
692 /* Make certain that chunk #0 in the object header will be encoded with a 2-byte size */
693 if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
694 FAIL_STACK_ERROR
695 if(hdr_info.space.total < 256)
696 TEST_ERROR
697
698 PASSED();
699
700 /* Close & re-open file & object header */
701 /* (makes certain that an object header in the new format that transitions
702 * between 1-byte chunk #0 size encoding and 2-byte chunk #0 size encoding
703 * works correctly - QAK)
704 */
705 TESTING("close & re-open object header");
706 if(H5O_close(&oh_loc) < 0)
707 FAIL_STACK_ERROR
708 if(H5Fclose(file) < 0)
709 FAIL_STACK_ERROR
710 if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
711 FAIL_STACK_ERROR
712 if(NULL == (f = (H5F_t *)H5I_object(file)))
713 FAIL_STACK_ERROR
714 oh_loc.file = f;
715 if(H5O_open(&oh_loc) < 0)
716 FAIL_STACK_ERROR
717 PASSED();
718
719 /*
720 * Test creation of a bunch of messages one after another to see
721 * what happens when the object header overflows on disk.
722 */
723 TESTING("object header overflow on disk");
724 for(i = 0; i < 10; i++) {
725 time_new = (i + 1) * 1000 + 10;
726 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
727 FAIL_STACK_ERROR
728 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
729 FAIL_STACK_ERROR
730 if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
731 FAIL_STACK_ERROR
732 } /* end for */
733 PASSED();
734
735 /*
736 * Delete all time messages.
737 */
738 TESTING("message deletion");
739 if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
740 FAIL_STACK_ERROR
741 if(H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
742 FAIL_STACK_ERROR
743 if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
744 FAIL_STACK_ERROR
745 if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT))
746 FAIL_STACK_ERROR
747 PASSED();
748
749
750 /*
751 * Constant message handling.
752 * (can't write to them, but should be able to remove them)
753 */
754 TESTING("constant message handling");
755 time_new = 22222222;
756 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
757 FAIL_STACK_ERROR
758 if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
759 FAIL_STACK_ERROR
760 if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
761 FAIL_STACK_ERROR
762 if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
763 FAIL_STACK_ERROR
764 if(ro != time_new)
765 TEST_ERROR
766 time_new = 33333333;
767 H5E_BEGIN_TRY {
768 ret = H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT);
769 } H5E_END_TRY;
770 if(ret >= 0)
771 TEST_ERROR
772 if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
773 FAIL_STACK_ERROR
774 PASSED();
775
776
777 /* release resources */
778 TESTING("object header closing");
779 if(H5O_close(&oh_loc) < 0)
780 FAIL_STACK_ERROR
781 PASSED();
782
783 /*
784 * Test moving message to first chunk
785 */
786 TESTING("locking messages");
787 HDmemset(&oh_loc, 0, sizeof(oh_loc));
788 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
789 FAIL_STACK_ERROR
790 if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
791 FAIL_STACK_ERROR
792
793 /* Create second object header, to guarantee that first object header uses multiple chunks */
794 HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
795 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
796 FAIL_STACK_ERROR
797 if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
798 FAIL_STACK_ERROR
799
800 /* Fill object header with messages, creating multiple chunks */
801 for(i = 0; i < 10; i++) {
802 time_new = (i + 1) * 1000 + 10;
803 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
804 FAIL_STACK_ERROR
805 } /* end for */
806
807 /* Get # of object header chunks */
808 if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
809 FAIL_STACK_ERROR
810 if(hdr_info.nchunks != 2)
811 TEST_ERROR
812
813 /* Add message to lock to object header */
814 time_new = 11111111;
815 if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
816 FAIL_STACK_ERROR
817
818 /* Verify chunk index for message */
819 if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
820 FAIL_STACK_ERROR
821 if(chunkno != 1)
822 TEST_ERROR
823
824 /* Lock the message into the chunk */
825 if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
826 FAIL_STACK_ERROR
827
828 /* Attempt to lock the message twice */
829 H5E_BEGIN_TRY {
830 ret = H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
831 } H5E_END_TRY;
832 if(ret >= 0)
833 TEST_ERROR
834
835 /* Delete all the other messages, which would move the message into
836 * chunk #0, if it wasn't locked
837 */
838 if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
839 FAIL_STACK_ERROR
840
841 /* Verify chunk index for message */
842 if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
843 FAIL_STACK_ERROR
844 if(chunkno != 1)
845 TEST_ERROR
846
847 /* Unlock the message */
848 if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
849 FAIL_STACK_ERROR
850
851 /* Attempt to unlock the message twice */
852 H5E_BEGIN_TRY {
853 ret = H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
854 } H5E_END_TRY;
855 if(ret >= 0)
856 TEST_ERROR
857
858 /* Close object headers */
859 if(H5O_close(&oh_loc2) < 0)
860 FAIL_STACK_ERROR
861 if(H5O_close(&oh_loc) < 0)
862 FAIL_STACK_ERROR
863
864 /* Open first object header */
865 HDmemset(&oh_loc, 0, sizeof(oh_loc));
866 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
867 FAIL_STACK_ERROR
868 if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
869 FAIL_STACK_ERROR
870
871 /* Create second object header, to guarantee that first object header uses multiple chunks */
872 HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
873 if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
874 FAIL_STACK_ERROR
875 if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
876 FAIL_STACK_ERROR
877
878 /* Add message to move to object header */
879 time_new = 11111111;
880 if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
881 FAIL_STACK_ERROR
882
883 /* Verify chunk index for message */
884 if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
885 FAIL_STACK_ERROR
886 if(chunkno != 0)
887 TEST_ERROR
888
889 /* Lock the message into the chunk */
890 if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
891 FAIL_STACK_ERROR
892
893 /* Fill object header with messages, creating multiple chunks */
894 /* (would normally move locked message to new chunk) */
895 for(i = 0; i < 10; i++) {
896 time_new = (i + 1) * 1000 + 10;
897 if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
898 FAIL_STACK_ERROR
899 } /* end for */
900
901 /* Get # of object header chunks */
902 if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
903 FAIL_STACK_ERROR
904 if(hdr_info.nchunks != 2)
905 TEST_ERROR
906
907 /* Verify chunk index for message */
908 if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
909 FAIL_STACK_ERROR
910 if(chunkno != 0)
911 TEST_ERROR
912
913 /* Unlock the message */
914 if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
915 FAIL_STACK_ERROR
916
917 /* Close object headers */
918 if(H5O_close(&oh_loc2) < 0)
919 FAIL_STACK_ERROR
920 if(H5O_close(&oh_loc) < 0)
921 FAIL_STACK_ERROR
922
923 PASSED();
924
925 /* Close the file we created */
926 if(H5Fclose(file) < 0)
927 TEST_ERROR
928
929 /* Test reading datasets with undefined object header messages
930 * and the various "fail/mark if unknown" object header message flags
931 */
932 HDputs("Accessing objects with unknown header messages: H5O_BOGUS_VALID_ID");
933 if(test_unknown(H5O_BOGUS_VALID_ID, filename, fapl) < 0)
934 TEST_ERROR
935 HDputs("Accessing objects with unknown header messages: H5O_BOGUS_INVALID_ID");
936 if(test_unknown(H5O_BOGUS_INVALID_ID, filename, fapl) < 0)
937 TEST_ERROR
938
939 /* Test object header creation metadata cache issues */
940 if(test_ohdr_cache(filename, fapl) < 0)
941 TEST_ERROR
942 } /* end for */
943
944 /* Verify symbol table messages are cached */
945 if(h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR
946
947 puts("All object header tests passed.");
948 h5_cleanup(FILENAME, fapl);
949 return(0);
950
951 error:
952 puts("*** TESTS FAILED ***");
953 H5E_BEGIN_TRY {
954 H5Fclose(file);
955 } H5E_END_TRY;
956
957 return(1);
958 } /* end main() */
959
960