hdf5/test/external.c

551 lines
13 KiB
C
Raw Normal View History

[svn-r303] Changes since 19980228 ---------------------- ./html/Dataspaces.html ./html/Errors.html ./html/Files.html ./html/H5.api.html ./html/review1.html ./src/H5private.h ./src/H5public.h ./test/dsets.c ./test/dtypes.c Removed all the types like `int32' and `intn' into private headers since they violate the naming scheme and pollute application name space. Besides, our test files only use them in a handful of places and it's probably useless to export them to the app. The app is always written in terms of standard numeric types or its own numeric types and probably never in terms of HDF5 numeric types. If it were, then the user would have to copy from their type to hdf5 type for almost every hdf5 API function call! Same goes for return values. I also removed SUCCEED/FAIL from the API since apps should be checking against zero anyway. if (FAIL==(space=H5Screate_simple(...))) /*wrong*/ if ((space=H5Fcreate_simple(...)<0)) /*right*/ ./src/H5.c Changed arguments of H5version() from `uintn' to `unsigned'. ./src/H5Tpublic.h ./src/H5T.c Changed return type of H5Tget_nmembers() from `intn' to `int' ./src/H5A.c ./src/H5Aprivate.h ./src/H5Apublic.h Changed `H5Asearch_func_t' to `H5A_search_func_t' and moved its definition from the public to the private header file. ./html/H5.format.html Documented changes made to the external file list (H5O_EFL) message. ./src/H5D.c ./src/H5Dprivate.h ./src/H5E.c ./src/H5Epublic.h ./src/H5O.c ./src/H5Oefl.c ./src/H5Oprivate.h ./src/H5P.c ./src/H5Ppublic.h Added partial support for external raw data files. HDF5 can now describe external raw data files by listing the file names, offsets, and size for a dataset. However, we will restrict a dataset to be stored "contiguously" when the external file list is viewed as a single address space. The current implementation is unable to read/write to external files--that will come later this week as will documentation. For now, take a look at ./test/external.c, particularly the calls to H5Pset_external(). ./test/Makefile.in ./test/external.c [NEW] ./MANIFEST Added tests for external storage. Note: the read test is supposed to fail at this point since reading external datasets is not implemented yet. There is no write test. ./src/H5S.c ./src/H5Sprivate.h ./src/H5Ssimp.c Added H5S_get_npoints_max() to return the maximum possible number of data points in a data space. Added an extra argument to H5S_get_dims() which returns the maximum dims. ./src/H5F.c ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5M.c [DEPRICATED] ./src/H5Mpublic.h [DEPRICATED] Changed `template' to `property list' in lots of places. ./src/H5Osdspace.c Removed an extra `\n' from a print statement. ./src/H5S_public.h Changed H5S_UNLIMITED to the maximum size_t value. ./test/extend.c "Extendable" is spelled "extendible". ./src/H5Farray.c ./src/H5V.c ./src/H5Vprivate.h ./test/hyperslab.c Strides are now type ssize_t instead of int. These have nothing to do with the sample granularity arguments for hyperslabs, which are also called "strides" in the code. ./test/tstab.c Changed assumptions about default address and length sizes.
1998-03-05 00:20:23 +08:00
/*
* Copyright (C) 1998 NCSA
* All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
* Tuesday, March 3, 1998
*
* Purpose: Tests datasets stored in external raw files.
*/
#include <assert.h>
#include <fcntl.h>
#include <hdf5.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*-------------------------------------------------------------------------
* Function: display_error_cb
*
* Purpose: Displays the error stack after printing "*FAILED*".
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Wednesday, March 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
display_error_cb (void *client_data)
{
puts ("*FAILED*");
H5Eprint (stdout);
return 0;
}
/*-------------------------------------------------------------------------
* Function: test_1
*
* Purpose: Describes various external datasets in an HDF5 file without
* actually creating the external raw files.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Tuesday, March 3, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
test_1 (void)
{
hid_t file, plist, space, dset, grp;
herr_t status;
size_t size[2], max_size[2];
herr_t (*func)(void*) = NULL;
void *client_data = NULL;
int n;
/*
* Create the file and an initial group. This causes messages about
* debugging to be emitted before we start playing games with what the
* output looks like.
*/
file = H5Fcreate ("extern_1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
assert (file>=0);
grp = H5Gcreate (file, "emit-diagnostics", 8);
H5Gclose (grp);
printf ("Testing external storage descriptions...\n");
/*
* A single external file for a non-extendible dataset.
*/
do {
printf ("%-70s", "...fixed-size data space, exact storage");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, 400);
assert (status>=0);
size[0] = max_size[0] = 100;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
/* Create the dataset, the `dset1' name is used later too */
dset = H5Dcreate (file, "dset1", H5T_NATIVE_INT32, space, plist);
if (dset<0) break;
H5Dclose (dset);
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* A single external file which is too small to represent all the data.
*/
do {
printf ("%-70s", "...external storage is too small");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, 399);
assert (status>=0);
size[0] = max_size[0] = 100;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
H5Eget_auto (&func, &client_data);
H5Eset_auto (NULL, NULL);
dset = H5Dcreate (file, "dset2", H5T_NATIVE_INT32, space, plist);
H5Eset_auto (func, client_data);
if (dset>=0) {
puts ("*FAILED*");
printf (" Small external file succeeded instead of failing\n");
H5Dclose (dset);
break;
}
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* A single external file which is large enough to represent the current
* data and large enough to represent the eventual size of the data.
*/
do {
printf ("%-70s", "...extendible dataspace, exact external size");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, 800);
assert (status>=0);
size[0] = 100;
max_size[0] = 200;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
dset = H5Dcreate (file, "dset3", H5T_NATIVE_INT32, space, plist);
if (dset<0) break;
H5Dclose (dset);
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* A single external file which is large enough for the current data size
* but not large enough for the eventual size.
*/
do {
printf ("%-70s", "...extendible dataspace, "
"external storage is too small");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, 799);
assert (status>=0);
size[0] = 100;
max_size[0] = 200;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
H5Eget_auto (&func, &client_data);
H5Eset_auto (NULL, NULL);
dset = H5Dcreate (file, "dset4", H5T_NATIVE_INT32, space, plist);
H5Eset_auto (func, client_data);
if (dset>=0) {
puts ("*FAILED*");
printf (" Small external file succeeded instead of failing\n");
H5Dclose (dset);
break;
}
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* A single external file of unlimited size and an unlimited data space.
*/
do {
printf ("%-70s", "...unlimited dataspace, unlimited external storage");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, H5F_UNLIMITED);
assert (status>=0);
size[0] = 100;
max_size[0] = H5S_UNLIMITED;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
/* Create the dataset, the `dset5' name is used later too */
dset = H5Dcreate (file, "dset5", H5T_NATIVE_INT32, space, plist);
if (dset<0) break;
H5Dclose (dset);
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* Open one of the previous datasets and make sure it looks the same as
* when we wrote it.
*/
do {
char name[256];
size_t file_offset;
size_t file_size;
printf ("%-70s", "...opening a dataset and reading the storage info");
fflush (stdout);
dset = H5Dopen (file, "dset1");
assert (dset>=0);
plist = H5Dget_create_parms (dset);
assert (plist>=0);
n = H5Pget_external_count (plist);
if (n<0) break;
if (1!=n) {
puts ("*FAILED*");
printf (" Returned external count is wrong.\n");
break;
}
strcpy (name+sizeof(name)-4, "...");
status = H5Pget_external (plist, 0, sizeof(name)-4, name,
&file_offset, &file_size);
if (status<0) {
printf (" Unable to read first extern file info.\n");
break;
} else if (file_offset!=0) {
puts ("*FAILED*");
printf (" Wrong file offset.\n");
break;
} else if (file_size!=400) {
puts ("*FAILED*");
printf (" Wrong file size.\n");
break;
}
puts (" PASSED");
} while (0);
H5Pclose (plist);
H5Dclose (dset);
/*
* Open one of the previous unlimited datasets and make sure it looks the
* same as when we wrote it.
*/
do {
char name[256];
size_t file_offset;
size_t file_size;
printf ("%-70s", "...opening an unlimited dataset and reading the "
"storage info");
fflush (stdout);
dset = H5Dopen (file, "dset5");
assert (dset>=0);
plist = H5Dget_create_parms (dset);
assert (plist>=0);
n = H5Pget_external_count (plist);
if (n<0) break;
if (1!=n) {
puts ("*FAILED*");
printf (" Returned external count is wrong.\n");
break;
}
strcpy (name+sizeof(name)-4, "...");
status = H5Pget_external (plist, 0, sizeof(name)-4, name,
&file_offset, &file_size);
if (status<0) {
printf (" Unable to read first extern file info.\n");
break;
} else if (file_offset!=0) {
puts ("*FAILED*");
printf (" Wrong file offset.\n");
break;
} else if (H5F_UNLIMITED!=file_size) {
puts ("*FAILED*");
printf (" Wrong file size.\n");
break;
}
puts (" PASSED");
} while (0);
H5Pclose (plist);
H5Dclose (dset);
/*
* Multiple external files for a dataset.
*/
do {
printf ("%-70s", "...multiple external files");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, 100);
assert (status>=0);
status = H5Pset_external (plist, "ext2.data", 0, 100);
assert (status>=0);
status = H5Pset_external (plist, "ext3.data", 0, 100);
assert (status>=0);
status = H5Pset_external (plist, "ext4.data", 0, 100);
assert (status>=0);
size[0] = max_size[0] = 100;
space = H5Screate_simple (1, size, max_size);
assert (space>=0);
dset = H5Dcreate (file, "dset6", H5T_NATIVE_INT32, space, plist);
if (dset<0) break;
H5Dclose (dset);
puts (" PASSED");
} while (0);
H5Sclose (space);
H5Pclose (plist);
/*
* It should be impossible to define an unlimited external file and then
* follow it with another external file.
*/
do {
printf ("%-70s", "...external file following unlimited file");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, H5F_UNLIMITED);
assert (status>=0);
/* Next function should fail */
H5Eget_auto (&func, &client_data);
H5Eset_auto (NULL, NULL);
status = H5Pset_external (plist, "ext2.data", 0, 100);
H5Eset_auto (func, client_data);
if (status>=0) {
puts ("*FAILED*");
puts (" H5Pset_external() succeeded when it should have failed");
break;
}
/* Check the number of files */
n = H5Pget_external_count (plist);
if (n<0) break;
if (1!=n) {
puts ("*FAILED*");
puts (" Wrong external file count returned.");
}
puts (" PASSED");
} while (0);
H5Pclose (plist);
/*
* It should be impossible to create a set of external files whose total
* size overflows a size_t integer.
*/
do {
printf ("%-70s", "...address overflow in external files");
fflush (stdout);
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "ext1.data", 0, H5F_UNLIMITED-1);
assert (status>=0);
/* Next function should fail */
H5Eget_auto (&func, &client_data);
H5Eset_auto (NULL, NULL);
status = H5Pset_external (plist, "ext2.data", 0, 100);
H5Eset_auto (func, client_data);
if (status>=0) {
puts ("*FAILED*");
puts (" H5Pset_external() succeeded when it should have failed");
break;
}
puts (" PASSED");
} while (0);
H5Pclose (plist);
/* END OF TESTS */
H5Fclose (file);
return 0;
}
/*-------------------------------------------------------------------------
* Function: test_2
*
* Purpose: Tests reading from an external file set.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Wednesday, March 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
test_2 (void)
{
hid_t file, plist, space, dset, grp;
herr_t status;
int fd,i, j;
ssize_t n;
char fname[64];
int part[25], whole[100];
size_t size;
/* Write the data to external files */
printf ("Writing external data...\n");
for (i=0; i<4; i++) {
for (j=0; j<25; j++) {
part[j] = i*25+j;
}
sprintf (fname, "extern_%d.raw", i+1);
fd = open (fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
assert (fd>=0);
n = write (fd, part, sizeof(part));
assert (n==sizeof(part));
close (fd);
}
/*
* Create the file and an initial group. This causes messages about
* debugging to be emitted before we start playing games with what the
* output looks like.
*/
file = H5Fcreate ("extern_2.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
assert (file>=0);
grp = H5Gcreate (file, "emit-diagnostics", 8);
H5Gclose (grp);
printf ("Testing external data reading...\n");
/* Create the external file list */
plist = H5Pcreate (H5P_DATASET_CREATE);
assert (plist>=0);
status = H5Pset_external (plist, "extern_1.raw", 0, sizeof(part));
assert (status>=0);
status = H5Pset_external (plist, "extern_2.raw", 0, sizeof(part));
assert (status>=0);
status = H5Pset_external (plist, "extern_3.raw", 0, sizeof(part));
assert (status>=0);
status = H5Pset_external (plist, "extern_4.raw", 0, sizeof(part));
assert (status>=0);
/* Create the data space */
size = 100;
space = H5Screate_simple (1, &size, NULL);
assert (space>=0);
/* Create the dataset */
dset = H5Dcreate (file, "dset1", H5T_NATIVE_INT, space, plist);
assert (dset>=0);
/*
* Read the entire dataset and compare with the original
*/
do {
/* Read from the dataset */
printf ("%-70s", "...reading entire dataset");
fflush (stdout);
status = H5Dread (dset, H5T_NATIVE_INT, space, space,
H5P_DEFAULT, whole);
if (status<0) {
puts (" Failed to read dataset");
break;
}
for (i=0; i<100; i++) {
if (whole[i]!=i) {
puts ("*FAILED*");
puts (" Incorrect value(s) read.");
break;
}
}
puts (" PASSED");
} while (0);
H5Dclose (dset);
H5Pclose (plist);
H5Sclose (space);
H5Fclose (file);
return 0;
}
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Runs external dataset tests.
*
* Return: Success: exit(0)
*
* Failure: exit(non-zero)
*
* Programmer: Robb Matzke
* Tuesday, March 3, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int
main (void)
{
herr_t status;
int nerrors=0;
H5Eset_auto (display_error_cb, NULL);
status = test_1 ();
nerrors += (status<0 ? 1 : 0);
status = test_2 ();
nerrors += (status<0 ? 1 : 0);
if (0==nerrors) {
printf ("All external storage tests passed.\n");
}
exit (nerrors?1:0);
}