diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/stream_test.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/test/stream_test.c b/test/stream_test.c new file mode 100644 index 0000000..a29a0c1 --- /dev/null +++ b/test/stream_test.c @@ -0,0 +1,379 @@ +/* + * Copyright © 2000 The author. + * The author prefers this code not be used for military purposes. + * + * + * Author: Thomas Radke <tradke@aei-potsdam.mpg.de> + * Tuesday, September 12, 2000 + * + * Modifications: + * + */ + +/* + * This program tests the functionality of the Stream Virtual File Driver. + * 1. It spawns two new processes, a sender and a receiver. + * 2. The sender opens an HDF5 file for writing and writes + * a sample dataset to it. + * On closing the file the Stream VFD would send the file + * contents to any connected client. + * 3. The receiver serves as a client attempting to open an + * HDF5 file for reading. On opening the file the Stream VFD + * would establish a socket connection to the sender process, + * identified by its hostname (which is localhost in this example) + * and a port number, and read the file contents via this socket. + * Aftwerwards the dataset is read from the file into memory + * and verified. + * 4. The main program waits for termination of its two child + * processes and returns their exit code. + */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <stdio.h> +#include <stdlib.h> + +#include <h5test.h> + +#ifndef H5_HAVE_STREAM + +int main (void) +{ + printf ("Test skipped because Stream Virtual File Driver not available\n"); + return (0); +} + +#else + +#define DELAY 10 /* sleeping time in seconds */ +#define RANK 2 /* sample dataset rank */ +#define DIMS 50 /* sample dataset dimensions */ +#define DATASETNAME "IntArray" /* sample dataset name */ +#define FILENAME "localhost:5678" /* filename argument */ + + +static int sender (void) +{ + int i; + hsize_t dims[RANK]; + int *data; + herr_t status; + hid_t fapl, file; + hid_t dataspace, dataset; + + + /* + * Create access property list and set it to use the Stream driver. + */ + fapl = H5Pcreate (H5P_FILE_ACCESS); + if (fapl < 0) + { + fprintf (stderr, "sender: couldn't create file access property list\n"); + return (-1); + } + + status = H5Pset_fapl_stream (fapl, NULL); + if (status < 0) + { + fprintf (stderr, "sender: couldn't set file access property list " + "for Stream VFD\n"); + H5Pclose (fapl); + return (-2); + } + + /* + * Create the data space for fixed size dataset. + */ + for (i = 0; i < RANK; i++) + { + dims[i] = DIMS; + } + dataspace = H5Screate_simple (RANK, dims, NULL); + if (dataspace < 0) + { + fprintf (stderr, "sender: couldn't create dataspace\n"); + H5Pclose (fapl); + return (-3); + } + + /* + * Data buffer initialization. + */ + i = (int) H5Sget_simple_extent_npoints (dataspace); + data = (int *) malloc (i * sizeof (int)); + if (data == NULL) + { + fprintf (stderr, "sender: cannot allocate buffer for dataset with " + "%d integers\n", i); + H5Sclose (dataspace); + H5Pclose (fapl); + return (-4); + } + while (--i >= 0) + { + data[i] = i; + } + + /* + * Create a new file using H5F_ACC_TRUNC access, + * default file creation properties, and STREAM file + * access properties. + */ + printf (" sender: opening file '%s' for writing...\n", FILENAME); + file = H5Fcreate (FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + if (file < 0) + { + fprintf (stderr, "sender: couldn't create file for '%s'\n", FILENAME); + free (data); + H5Sclose (dataspace); + H5Pclose (fapl); + return (-5); + } + + /* + * Create a new dataset within the file using defined dataspace and + * default dataset creation properties. + */ + dataset = H5Dcreate (file, DATASETNAME, H5T_NATIVE_INT, dataspace, + H5P_DEFAULT); + if (dataset < 0) + { + fprintf (stderr, "sender: couldn't create dataset '%s'\n", DATASETNAME); + free (data); + H5Fclose (file); + H5Sclose (dataspace); + H5Pclose (fapl); + return (-6); + } + + /* + * Write the data to the dataset using default transfer properties. + */ + printf (" sender: writing dataset '%s' of type INTEGER to file '%s'...\n", + DATASETNAME, FILENAME); + status = H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + data); + if (status < 0) + { + free (data); + H5Fclose (file); + H5Dclose (dataset); + H5Sclose (dataspace); + H5Pclose (fapl); + fprintf (stderr, "sender: couldn't write dataset\n"); + return (-7); + } + + /* + * Now give the receiver some time to connect before closing the file + * and releasing resources. + */ + printf (" sender: sleeping for %d seconds...\n", DELAY); + sleep (DELAY); + printf (" sender: closing file '%s'\n", FILENAME); + H5Sclose (dataspace); + H5Dclose (dataset); + H5Fclose (file); + H5Pclose (fapl); + free (data); + + return (0); +} + + +static int receiver (void) +{ + int i; /* looper */ + hid_t fapl; /* file access property list */ + hid_t file; /* file handle */ + hid_t dataset; /* dataset handle */ + hid_t datatype; /* datatype handle */ + hid_t dataspace; /* dataspace handle */ + hsize_t nelems; /* total number of elements in the dataset */ + hsize_t *dims; /* dataset dimensions */ + int rank; /* dataset rank */ + int *data; /* read buffer */ + int nerrors; /* total number of errors during verify */ + int status; /* return code of HDF5 routines */ + + + /* + * Create access property list and set it to use the Stream driver. + */ + fapl = H5Pcreate (H5P_FILE_ACCESS); + if (fapl < 0) + { + fprintf (stderr, "receiver: couldn't create file access property list\n"); + return (-1); + } + + status = H5Pset_fapl_stream (fapl, NULL); + if (status < 0) + { + fprintf (stderr, "receiver: couldn't set file access property list " + "for Stream VFD\n"); + return (-2); + } + + /* + * Now give the sender some time to open the file and accepting connections. + */ + printf (" receiver: sleeping for %d seconds...\n", DELAY / 2); + sleep (DELAY / 2); + printf (" receiver: opening file '%s' for reading...\n", FILENAME); + file = H5Fopen (FILENAME, H5F_ACC_RDONLY, fapl); + H5Pclose (fapl); + if (file < 0) + { + fprintf (stderr, "receiver: couldn't open file from '%s'\n", FILENAME); + return (-3); + } + + /* + * Open the file and the dataset. + */ + printf (" receiver: reading dataset '%s'...\n", DATASETNAME); + dataset = H5Dopen (file, DATASETNAME); + if (dataset < 0) + { + fprintf (stderr, "receiver: couldn't open dataset '%s'\n", DATASETNAME); + return (-4); + } + + /* + * Get dataset class, order, and size information + */ + datatype = H5Dget_type (dataset); + if (H5Tget_class (datatype) == H5T_INTEGER) + { + printf (" receiver: dataset is of type INTEGER\n"); + } + printf (" receiver: datatype size is %d bytes\n", + (int) H5Tget_size (datatype)); + printf (" receiver: byte ordering is %s endian\n", + H5Tget_order (datatype) == H5T_ORDER_LE ? "little" : "big"); + H5Tclose(datatype); + + /* + * Get dataset dimensions + */ + dataspace = H5Dget_space (dataset); + rank = H5Sget_simple_extent_ndims (dataspace); + dims = (hsize_t *) malloc (rank * sizeof (hsize_t)); + H5Sget_simple_extent_dims (dataspace, dims, NULL); + H5Sclose (dataspace); + + printf (" receiver: rank %d, dimensions %u", rank, (unsigned int) dims[0]); + nelems = dims[0]; + for (i = 1; i < rank; i++) + { + printf (" x %u", (unsigned int) dims[i]); + nelems *= dims[i]; + } + printf ("\n receiver: total number of elements: %d\n", (int) nelems); + free (dims); + + /* + * Read dataset from file into memory. + */ + data = (int *) malloc (nelems * sizeof (int)); + status = H5Dread (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + data); + H5Dclose (dataset); + + /* + * Close the file. + */ + printf (" receiver: closing file '%s'...\n", FILENAME); + H5Fclose (file); + + /* + * Verify the dataset contents + */ + printf (" receiver: verifying contents of dataset '%s'...\n", DATASETNAME); + for (i = nerrors = 0; i < (int) nelems; i++) + { + if (data[i] != i) + { + fprintf (stderr, "receiver: data error at offset %d: " + "expected %d got %d\n", i, i, data[i]); + nerrors++; + } + } + printf (" receiver: dataset verified, %d errors found\n", nerrors); + + free (data); + + return (-nerrors); +} + + +int main (void) +{ + int main_status, sender_status, receiver_status; + pid_t sender_pid, receiver_pid; + + + sender_pid = receiver_pid = 0; + + /* main's return code for success */ + main_status = 0; + + /* spawn off the sender and the receiver process */ + printf ("main: starting sender process...\n"); + sender_pid = fork (); + if (sender_pid == 0) + { + return (sender ()); + } + else if (sender_pid < 0) + { + perror ("Failed to spawn sender"); + main_status = -1; + } + else + { + printf ("main: starting receiver process...\n"); + receiver_pid = fork (); + if (receiver_pid == 0) + { + return (receiver ()); + } + else if (sender_pid < 0) + { + perror ("Failed to spawn receiver"); + main_status = -1; + } + } + + /* wait for the termination of sender and receiver and check their status */ + printf ("main: waiting for termination of sender and receiver process...\n"); + if (sender_pid > 0 && + waitpid (sender_pid, &sender_status, 0) != sender_pid) + { + perror ("Failed to wait for termination of sender"); + main_status = -1; + } + else + { + main_status |= sender_status; + } + if (receiver_pid > 0 && + waitpid (receiver_pid, &receiver_status, 0) != receiver_pid) + { + perror ("Failed to wait for termination of receiver"); + main_status = -1; + } + else + { + main_status |= receiver_status; + } + + printf (main_status == 0 ? + "Stream Virtual File Driver test passed.\n" : + "*** Stream Virtual File Driver TEST FAILED ***\n"); + + return (main_status); +} + +#endif /* H5_HAVE_STREAM */ |