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 #include "h5test.h"
15 
16 #ifdef BROKEN
17 const char *FILENAME[] = {
18     "rsrv_heap",
19     "rsrv_ohdr",
20     "rsrv_vlen",
21     NULL
22 };
23 
24 /*-------------------------------------------------------------------------
25  * Function:	rsrv_heap
26  *
27  * Purpose:	Ensure that heaps reserve file address space.
28  *			This function does this by creating datasets up to and past
29  *			the limit of the file, then ensuring that an error (not an
30  *			assert) was generated and that the file is readable.
31  *
32  * Return:	Success:	0
33  *		Failure:	1
34  *
35  * Programmer:	James Laird
36  *              Nat Furrer
37  *              Friday, May 28, 2004
38  *
39  * Modifications:
40  *
41  *-------------------------------------------------------------------------
42  */
43 static herr_t
rsrv_heap(void)44 rsrv_heap(void)
45 {
46     hid_t       file_id=(-1), dataset_id=(-1), dataspace_id=(-1);
47     hid_t       fapl=(-1), fcpl=(-1);
48     hsize_t     dims[1] = {1};
49     char        filename[1024], dset_name[10];
50     int         i;
51 
52     TESTING("Reserving file space for heap");
53 
54     /* Create a new file. */
55     fapl = h5_fileaccess();
56 
57     h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
58     /* Set file address sizes to be very small. */
59     fcpl = H5Pcreate(H5P_FILE_CREATE);
60     if(fcpl < 0) TEST_ERROR;
61     if(H5Pset_sizes(fcpl, (size_t)2,(size_t)2) < 0) TEST_ERROR;
62 
63     file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
64     if(file_id < 0) TEST_ERROR;
65 
66     /* Write datasets until the file is full, at which point HDF5
67      * should throw an error.
68      */
69     for(i = 0; i < 200; i++) {
70         H5E_BEGIN_TRY {
71             dataspace_id = H5Screate_simple(1, dims, dims);
72         } H5E_END_TRY
73 
74         sprintf(dset_name, "Dset %d", i);
75 
76         H5E_BEGIN_TRY {
77             dataset_id = H5Dcreate2(file_id, dset_name, H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
78         } H5E_END_TRY
79 
80         if(dataset_id < 0)
81             break;
82 
83         H5E_BEGIN_TRY {
84             H5Dwrite(dataset_id, H5T_NATIVE_INT, dataspace_id, dataspace_id, H5P_DEFAULT, &i);
85         } H5E_END_TRY
86 
87         if(H5Dclose(dataset_id) < 0) TEST_ERROR;
88         if(H5Sclose(dataspace_id) < 0) TEST_ERROR;
89     } /* end for */
90 
91     /* The loop should have broken before completing--the file should not have had
92      * enough address space to hold 200 datasets (or this test needs to be updated!).
93      */
94     if(i == 200)
95         TEST_ERROR;
96 
97     /* Close the file, property lists, and library */
98     if(H5Fclose(file_id) < 0) TEST_ERROR;
99     if(H5Pclose(fapl) < 0) TEST_ERROR;
100     if(H5Pclose(fcpl) < 0) TEST_ERROR;
101     if(H5close() < 0) TEST_ERROR;
102 
103     /* Re-open the library and try to read a dataset from the file we created */
104     if(H5open() < 0) TEST_ERROR;
105 
106     sprintf(dset_name, "Dset %d", i - 2);
107 
108     file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
109     if(file_id < 0) TEST_ERROR;
110 
111     dataset_id = H5Dopen2(file_id, dset_name, H5P_DEFAULT);
112 
113     /* If we can read a dataset from the file, the file has been flushed to disk
114      * (if the heap or object headers weren't flushed, the file would be empty).
115      */
116     if(dataset_id == H5I_BADID)
117        TEST_ERROR;
118 
119     if(H5Dclose(dataset_id) < 0) TEST_ERROR;
120     if(H5Fclose(file_id) < 0) TEST_ERROR;
121 
122     PASSED();
123     return 0;
124 
125 error:
126     /* Close everything we can and exit */
127     H5E_BEGIN_TRY {
128       H5Dclose(dataset_id);
129       H5Sclose(dataspace_id);
130       H5Pclose(fcpl);
131       H5Pclose(fapl);
132       H5Fclose(file_id);
133     } H5E_END_TRY
134     return 1;
135 }
136 
137 /*-------------------------------------------------------------------------
138  * Function:	rsrv_ohdr
139  *
140  * Purpose:	Ensure that object headers reserve file address space.
141  *			This function does this by creating attributes of a dataset
142  *			past the limit of the file, then ensuring that an error (not
143  *			an assert) was generated and that the file is readable.
144  *
145  * Return:	Success:	0
146  *		Failure:	1
147  *
148  * Programmer:	James Laird
149  *              Nat Furrer
150  *              Friday, May 28, 2004
151  *
152  * Modifications:
153  *
154  *-------------------------------------------------------------------------
155  */
156 static herr_t
rsrv_ohdr(void)157 rsrv_ohdr(void)
158 {
159     hid_t       file_id=(-1), dataset_id=(-1), dataspace_id=(-1);
160     hid_t       fapl=(-1), fcpl=(-1), aid, attr_id;
161     hsize_t     dims[2];
162     herr_t      status;
163     int         attrval[4][6];
164     char        filename[1024], attrname[20];
165     int         i;
166 
167     TESTING("Reserving file space for object headers");
168 
169     /* Create a new file */
170     fapl = h5_fileaccess();
171     h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
172 
173     fcpl = H5Pcreate(H5P_FILE_CREATE);
174     if(fcpl < 0) TEST_ERROR;
175     if(H5Pset_sizes(fcpl, (size_t)2,(size_t)2) < 0) TEST_ERROR;
176 
177     file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
178     if(file_id < 0) TEST_ERROR;
179 
180     /* Create the data space for the dataset. */
181     dims[0] = 4;
182     dims[1] = 6;
183     dataspace_id = H5Screate_simple(2, dims, NULL);
184     if(dataspace_id < 0) TEST_ERROR;
185 
186     /* Create the dataset. */
187     dataset_id = H5Dcreate2(file_id, "/dset", H5T_STD_I32BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
188     if(dataset_id < 0) TEST_ERROR;
189 
190     for(i = 0; i < 6; i++) {
191         attrval[0][i] = 0;
192         attrval[1][i] = 1;
193         attrval[2][i] = 2;
194         attrval[3][i] = 3;
195     } /* end for */
196 
197     for(i = 0; i < 2000; i++) {
198         sprintf(attrname, "attr %d", i);
199         H5E_BEGIN_TRY{
200             aid =  H5Screate_simple(2, dims, NULL);
201             attr_id = H5Acreate2(dataset_id, attrname, H5T_STD_I32BE, aid, H5P_DEFAULT, H5P_DEFAULT);
202             H5Awrite(attr_id, H5T_NATIVE_INT, attrval);
203             status = H5Aclose(attr_id);
204         } H5E_END_TRY
205 
206         if(status < 0)
207             break;
208     } /* end for */
209 
210     /* The loop should have broken before completing--the file should not have had
211      * enough address space to hold 2000 attributes (or this test needs to be updated
212 !).
213      */
214     if(i == 2000)
215         TEST_ERROR;
216 
217     /* End access to the dataset and dataspace and release resources. */
218     if(H5Dclose(dataset_id) < 0) TEST_ERROR;
219     if(H5Pclose(fapl) < 0) TEST_ERROR;
220     if(H5Pclose(fcpl) < 0) TEST_ERROR;
221     if(H5Sclose(dataspace_id) < 0) TEST_ERROR;
222 
223     /* Close the file and the library. */
224     if(H5Fclose(file_id) < 0) TEST_ERROR;
225     if(H5close() < 0) TEST_ERROR;
226 
227     /* Re-open the library and try to read a dataset from the file we created */
228     if(H5open() < 0) TEST_ERROR;
229 
230     file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
231     if(file_id < 0) TEST_ERROR;
232 
233     dataset_id = H5Dopen2(file_id, "/dset", H5P_DEFAULT);
234 
235     /* If we can read the dataset from the file, the file has been flushed to disk
236      * (if the heap or object headers weren't flushed, the file would be empty).
237      */
238     if(dataset_id == H5I_BADID)
239         TEST_ERROR;
240 
241     if(H5Dclose(dataset_id) < 0) TEST_ERROR;
242     if(H5Fclose(file_id) < 0) TEST_ERROR;
243 
244     PASSED();
245     return 0;
246 
247 error:
248     /* Close everything we can and exit */
249     H5E_BEGIN_TRY {
250       H5Dclose(dataset_id);
251       H5Sclose(dataspace_id);
252       H5Pclose(fcpl);
253       H5Pclose(fapl);
254       H5Fclose(file_id);
255     } H5E_END_TRY
256     return 1;
257 }
258 
259 /*-------------------------------------------------------------------------
260  * Function:	rsrv_vlen
261  *
262  * Purpose:	Ensure that variable length datatypes properly ensure that
263  *              enough file address space exists before writing.
264  *		This function does this by creating a dataset containing
265  *              variable length data past the limit of the file, then
266  *              ensuring that an error (not an assert) was generated and
267  *              that the file is readable.
268  *
269  * Return:	Success:	0
270  *		Failure:	1
271  *
272  * Programmer:	James Laird
273  *		Nat Furrer
274  *              Thursday, July 1, 2004
275  *
276  * Modifications:
277  *
278  *-------------------------------------------------------------------------
279  */
280 static herr_t
rsrv_vlen(void)281 rsrv_vlen(void)
282 {
283     hid_t       file_id=(-1), dataset_id=(-1), dataspace_id=(-1), type_id=(-1);
284     hid_t       fapl=(-1), fcpl=(-1), mem_space_id=(-1);
285     hssize_t    offset[1];
286     hsize_t     start[1];
287     hsize_t     dims[1], count[1];
288     herr_t      status;
289     int         i;
290     int         write_buf[20];
291     char        filename[1024];
292     hvl_t       vlen_data;
293 
294     TESTING("Reserved space with variable length data");
295 
296     /* Create a new file */
297     fapl = h5_fileaccess();
298     h5_fixname(FILENAME[2], fapl, filename, sizeof filename);
299 
300     /* Make file address space very small */
301     fcpl = H5Pcreate(H5P_FILE_CREATE);
302     if(fcpl < 0) TEST_ERROR;
303     if(H5Pset_sizes(fcpl, (size_t)2,(size_t)2) < 0) TEST_ERROR;
304 
305     file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
306     if(file_id < 0) TEST_ERROR;
307 
308     /* Create the data space for the dataset. */
309     dims[0] = 2000;
310     dataspace_id = H5Screate_simple(1, dims, NULL);
311     if(dataspace_id < 0) TEST_ERROR;
312 
313     /* Create a variable length type */
314     type_id = H5Tvlen_create(H5T_NATIVE_INT);
315     if(type_id < 0) TEST_ERROR;
316 
317     /* Create the dataset. */
318     dataset_id = H5Dcreate2(file_id, "/dset", type_id, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
319     if(dataset_id < 0) TEST_ERROR;
320 
321     /* Create some data to write */
322     for(i = 0; i < 20; i++)
323         write_buf[i] = i + 1;
324     vlen_data.p = write_buf;
325 
326     /* Create a memory dataspace for writing */
327     dims[0] = 1;
328     mem_space_id = H5Screate_simple(1, dims, NULL);
329     if(mem_space_id < 0) TEST_ERROR;
330 
331     /* Create a selection to write to */
332     start[0] = 0;
333     count[0] = 1;
334     if(H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET, start, NULL, count, NULL)  < 0) TEST_ERROR;
335 
336     for(i = 0; i< 2000; i++) {
337         vlen_data.len = (i%20) + 1;
338 
339         offset[0] = i;
340         if( H5Soffset_simple(dataspace_id, offset) <0) TEST_ERROR;
341 
342         H5E_BEGIN_TRY
343             status = H5Dwrite(dataset_id, type_id, mem_space_id, dataspace_id, H5P_DEFAULT, &vlen_data);
344         H5E_END_TRY
345 
346         if(status < 0)
347             break;
348     } /* end for */
349 
350     /* The loop should have broken before completing--the file should not have had
351      * enough address space to hold 2000 attributes (or this test needs to be updated!).
352      */
353     if(i == 2000)
354         TEST_ERROR;
355 
356     /* End access to the dataset and dataspace and release resources. */
357     if(H5Dclose(dataset_id) < 0) TEST_ERROR;
358     if(H5Pclose(fcpl) < 0) TEST_ERROR;
359     if(H5Pclose(fapl) < 0) TEST_ERROR;
360     if(H5Sclose(dataspace_id) < 0) TEST_ERROR;
361     if(H5Tclose(type_id) < 0) TEST_ERROR;
362     if(H5Sclose(mem_space_id) < 0) TEST_ERROR;
363 
364     /* Close the file and the library. */
365     if(H5Fclose(file_id) < 0) TEST_ERROR;
366     if(H5close() < 0) TEST_ERROR;
367 
368     /* Re-open the library and try to read a dataset from the file we created */
369     if(H5open() < 0) TEST_ERROR;
370 
371     file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
372     if(file_id < 0) TEST_ERROR;
373 
374     dataset_id = H5Dopen2(file_id, "/dset", H5P_DEFAULT);
375 
376     /* If we can read the dataset from the file, the file has been flushed to disk
377      * (if the heap or object headers weren't flushed, the file would be empty).
378      */
379     if(dataset_id == H5I_BADID)
380         TEST_ERROR;
381 
382     if(H5Dclose(dataset_id) < 0) TEST_ERROR;
383     if(H5Fclose(file_id) < 0) TEST_ERROR;
384 
385     PASSED();
386     return 0;
387 
388 error:
389     /* Close everything we can and exit */
390     H5E_BEGIN_TRY {
391       H5Dclose(dataset_id);
392       H5Sclose(dataspace_id);
393       H5Sclose(mem_space_id);
394       H5Tclose(type_id);
395       H5Pclose(fcpl);
396       H5Pclose(fapl);
397       H5Fclose(file_id);
398     } H5E_END_TRY
399     return 1;
400 }
401 #endif /* BROKEN */
402 
403 /*-------------------------------------------------------------------------
404  * Function:	main
405  *
406  * Purpose:
407  *
408  * Return:	Success:
409  *
410  *		Failure:
411  *
412  * Programmer:	Nat Furrer and James Laird
413  *              Thursday, July 1, 2004
414  *
415  * Modifications:
416  *
417  *-------------------------------------------------------------------------
418  */
419 int
main(void)420 main(void)
421 {
422     /* This test is currently not working properly; it should be revisted
423      * when we have time.
424      *
425      * (Also, we should try to make this test work with all the VFDs)
426      */
427 #ifdef BROKEN
428     int num_errs=0;
429     hid_t fapl;
430     const char *envval = NULL;
431 
432     envval = HDgetenv("HDF5_DRIVER");
433     if (envval == NULL)
434         envval = "nomatch";
435 /* QAK: should be able to use the core driver? */
436     if (HDstrcmp(envval, "core") && HDstrcmp(envval, "split") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "family")) {
437 	num_errs+=rsrv_ohdr();
438 	num_errs+=rsrv_heap();
439 	num_errs+=rsrv_vlen();
440 
441 	if(num_errs > 0)
442 	    printf("**** %d FAILURE%s! ****\n", num_errs, num_errs==1?"":"S");
443 	else
444 	    puts("All address space reservation tests passed.");
445 
446 	fapl = h5_fileaccess();
447 	h5_cleanup(FILENAME, fapl);
448 	return num_errs;
449     }
450     else
451     {
452         puts("All address space reservation tests skippped - Incompatible with current Virtual File Driver");
453     }
454 #endif /* BROKEN */
455 
456     SKIPPED();
457     return 0;
458 
459 }
460 
461