1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * All rights reserved. *
4 * *
5 * This file is part of HDF5. The full HDF5 copyright notice, including *
6 * terms governing use, modification, and redistribution, is contained in *
7 * the COPYING file, which can be found at the root of the source code *
8 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
9 * If you do not have access to either file, you may request a copy from *
10 * help@hdfgroup.org. *
11 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 /*
13 * Programmer: Raymond Lu
14 * 24 April 2013
15 *
16 * Purpose: Tests H5Zunregister function
17 */
18 #include "h5test.h"
19
20 #include "H5CXprivate.h" /* API Contexts */
21
22 const char *FILENAME[] = {
23 "unregister_filter_1",
24 "unregister_filter_2",
25 NULL
26 };
27
28 #define GROUP_NAME "test_group"
29 #define DSET_NAME "test_dataset"
30 #define FILENAME_BUF_SIZE 1024
31 #define DSET_DIM1 100
32 #define DSET_DIM2 200
33 #define FILTER_CHUNK_DIM1 2
34 #define FILTER_CHUNK_DIM2 25
35 #define GROUP_ITERATION 1000
36
37 #define H5Z_FILTER_DUMMY 312
38
39 static size_t do_nothing(unsigned int flags, size_t cd_nelmts,
40 const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
41
42 /* Dummy filter for test_unregister_filters only */
43 const H5Z_class2_t H5Z_DUMMY[1] = {{
44 H5Z_CLASS_T_VERS, /* H5Z_class_t version */
45 H5Z_FILTER_DUMMY, /* Filter ID number */
46 1, 1, /* Encoding and decoding enabled */
47 "dummy", /* Filter name for debugging */
48 NULL, /* The "can apply" callback */
49 NULL, /* The "set local" callback */
50 do_nothing, /* The actual filter function */
51 }};
52
53
54 /*-------------------------------------------------------------------------
55 * Function: do_nothing
56 *
57 * Purpose: A dummy compression method that doesn't do anything. This
58 * filter is only for test_unregister_filters. Please don't
59 * use it for other tests because it may mess up this test.
60 *
61 * Return: Data chunk size
62 *
63 *-------------------------------------------------------------------------
64 */
65 static size_t
do_nothing(unsigned int H5_ATTR_UNUSED flags,size_t H5_ATTR_UNUSED cd_nelmts,const unsigned int H5_ATTR_UNUSED * cd_values,size_t nbytes,size_t H5_ATTR_UNUSED * buf_size,void H5_ATTR_UNUSED ** buf)66 do_nothing(unsigned int H5_ATTR_UNUSED flags, size_t H5_ATTR_UNUSED cd_nelmts,
67 const unsigned int H5_ATTR_UNUSED *cd_values, size_t nbytes,
68 size_t H5_ATTR_UNUSED *buf_size, void H5_ATTR_UNUSED **buf)
69 {
70 return nbytes;
71 }
72
73 /*-------------------------------------------------------------------------
74 * Function: test_unregister_filters
75 *
76 * Purpose: Tests unregistering filter before closing the file
77 *
78 * Return: SUCCEED/FAIL
79 *
80 *-------------------------------------------------------------------------
81 */
82 static herr_t
test_unregister_filters(hid_t fapl_id)83 test_unregister_filters(hid_t fapl_id)
84 {
85 hid_t fid1 = H5I_INVALID_HID;
86 hid_t fid2 = H5I_INVALID_HID;
87 hid_t dcpl_id = H5I_INVALID_HID;
88 hid_t gcpl_id = H5I_INVALID_HID;
89 hid_t gid = H5I_INVALID_HID;
90 hid_t gid_loop = H5I_INVALID_HID;
91 hid_t did = H5I_INVALID_HID;
92 hid_t sid = H5I_INVALID_HID;
93 int i, j, n;
94 char group_name[32];
95 char filename[FILENAME_BUF_SIZE];
96 const hsize_t chunk_dims[2] = {FILTER_CHUNK_DIM1, FILTER_CHUNK_DIM2}; /* Chunk dimensions */
97 hsize_t dims[2];
98 int data[DSET_DIM1][DSET_DIM2];
99 herr_t ret;
100
101 TESTING("Unregistering filter");
102
103 /* Create first file */
104 h5_fixname(FILENAME[0], fapl_id, filename, sizeof(filename));
105 if((fid1 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
106 goto error;
107
108 /* Create second file */
109 h5_fixname(FILENAME[1], fapl_id, filename, sizeof(filename));
110 if((fid2 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
111 goto error;
112
113 /* Register DUMMY filter */
114 if (H5Zregister(H5Z_DUMMY) < 0)
115 goto error;
116 if (H5Zfilter_avail(H5Z_FILTER_DUMMY) != TRUE)
117 goto error;
118
119 /*******************
120 * PART 1 - GROUPS *
121 *******************/
122
123 /* Use DUMMY filter for creating groups */
124 if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0)
125 goto error;
126 if(H5Pset_filter(gcpl_id, H5Z_FILTER_DUMMY, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0)
127 goto error;
128
129 /* Create a group using this filter */
130 if((gid = H5Gcreate2(fid1, GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0)
131 goto error;
132
133 /* Create multiple groups under the main group */
134 for(i = 0; i < GROUP_ITERATION; i++) {
135 HDsprintf(group_name, "group_%d", i);
136 if((gid_loop = H5Gcreate2(gid, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
137 goto error;
138 if(H5Gclose(gid_loop) < 0)
139 goto error;
140 }
141
142 /* Flush the file containing the groups */
143 if(H5Fflush(fid1, H5F_SCOPE_GLOBAL) < 0)
144 goto error;
145
146 /* Unregister the filter before closing the group. It should fail */
147 H5E_BEGIN_TRY {
148 ret = H5Zunregister(H5Z_FILTER_DUMMY);
149 } H5E_END_TRY;
150 if(ret >= 0) {
151 H5_FAILED();
152 HDprintf(" Line %d: Should not be able to unregister filter\n", __LINE__);
153 goto error;
154 }
155
156 /* Close the group */
157 if(H5Gclose(gid) < 0)
158 goto error;
159
160 /* Clean up objects used for this test */
161 if(H5Pclose (gcpl_id) < 0)
162 goto error;
163
164 /*********************
165 * PART 2 - DATASETS *
166 *********************/
167
168 /* Use DUMMY filter for creating datasets */
169 if((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
170 goto error;
171 if(H5Pset_chunk(dcpl_id, 2, chunk_dims) < 0)
172 goto error;
173 if(H5Pset_filter(dcpl_id, H5Z_FILTER_DUMMY, 0, (size_t)0, NULL) < 0)
174 goto error;
175
176 /* Initialize the data for writing */
177 for(i = n = 0; i < DSET_DIM1; i++)
178 for(j = 0; j < DSET_DIM2; j++)
179 data[i][j] = n++;
180
181 /* Create the dataspace */
182 dims[0] = DSET_DIM1;
183 dims[1] = DSET_DIM2;
184 if((sid = H5Screate_simple(2, dims, NULL)) < 0)
185 goto error;
186
187 /* Create a dataset in the first file */
188 if((did = H5Dcreate2(fid1, DSET_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
189 goto error;
190
191 /* Write the data to the dataset */
192 if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
193 goto error;
194
195 /* Unregister the filter before closing the dataset. It should fail */
196 H5E_BEGIN_TRY {
197 ret = H5Zunregister(H5Z_FILTER_DUMMY);
198 } H5E_END_TRY;
199 if(ret >= 0) {
200 H5_FAILED();
201 HDprintf(" Line %d: Should not be able to unregister filter\n", __LINE__);
202 goto error;
203 }
204
205 /* Close the dataset */
206 if(H5Dclose(did) < 0)
207 goto error;
208
209 /* Create a dataset in the second file */
210 if((did = H5Dcreate2(fid2, DSET_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
211 goto error;
212
213 /* Write the data to the dataset */
214 if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
215 goto error;
216
217 /* Close the dataset in the second file */
218 if(H5Dclose(did) < 0)
219 goto error;
220
221 /* Unregister the filter after closing all objects but before closing files.
222 * It should flush all files.
223 */
224 if(H5Zunregister(H5Z_FILTER_DUMMY) < 0)
225 goto error;
226
227 /* Clean up objects used for this test */
228 if(H5Pclose(dcpl_id) < 0)
229 goto error;
230 if(H5Fclose(fid1) < 0)
231 goto error;
232 if(H5Fclose(fid2) < 0)
233 goto error;
234
235 PASSED();
236 return SUCCEED;
237
238 error:
239 H5E_BEGIN_TRY {
240 H5Fclose(fid1);
241 H5Fclose(fid2);
242 H5Pclose(dcpl_id);
243 H5Pclose(gcpl_id);
244 H5Gclose(gid);
245 H5Gclose(gid_loop);
246 H5Dclose(did);
247 H5Sclose(sid);
248 } H5E_END_TRY;
249
250 return FAIL;
251 }
252
253
254 /*-------------------------------------------------------------------------
255 * Function: main
256 *
257 * Purpose: Tests unregistering filter with H5Zunregister
258 *
259 * Return: EXIT_SUCCESS/EXIT_FAILURE
260 *
261 *-------------------------------------------------------------------------
262 */
263 int
main(void)264 main(void)
265 {
266 hid_t fapl_id = H5I_INVALID_HID;
267 int nerrors = 0;
268 hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
269
270 /* Testing setup */
271 h5_reset();
272 fapl_id = h5_fileaccess();
273
274 /* Push API context */
275 if(H5CX_push() < 0) FAIL_STACK_ERROR
276 api_ctx_pushed = TRUE;
277
278 /* Test unregistering filter in its own file */
279 nerrors += (test_unregister_filters(fapl_id) < 0 ? 1 : 0);
280
281 h5_cleanup(FILENAME, fapl_id);
282
283 if (nerrors)
284 goto error;
285 HDprintf("All filter unregistration tests passed.\n");
286
287 /* Pop API context */
288 if(api_ctx_pushed && H5CX_pop() < 0) FAIL_STACK_ERROR
289 api_ctx_pushed = FALSE;
290
291
292 HDexit(EXIT_SUCCESS);
293
294 error:
295 nerrors = MAX(1, nerrors);
296 HDprintf("***** %d FILTER UNREGISTRATION TEST%s FAILED! *****\n",
297 nerrors, 1 == nerrors ? "" : "S");
298
299 if(api_ctx_pushed) H5CX_pop();
300
301 HDexit(EXIT_FAILURE);
302 } /* end main() */
303
304