1 /* This is part of the netCDF package. Copyright 2005-2019 University
2    Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
3    for conditions of use.
4 
5    Test list functions in nc4internal.c.
6 
7    Ed Hartnett, 8/21/19
8 */
9 
10 #include "config.h"
11 #include <nc_tests.h>
12 #include "nc.h"
13 #include "nc4internal.h"
14 #include "ncdispatch.h"
15 #include "err_macros.h"
16 
17 /* An integer value to use in testing. */
18 #define TEST_VAL_42 42
19 
20 #define FILE_NAME "tst_nc4internal.nc"
21 #define VAR_NAME "Hilary_Duff"
22 #define DIM_NAME "Foggy"
23 #define DIM_LEN 5
24 #define TYPE_NAME "Madonna"
25 #define TYPE_SIZE TEST_VAL_42
26 #define FIELD_NAME "Britany_Spears"
27 #define FIELD_OFFSET 9
28 
29 int
main(int argc,char ** argv)30 main(int argc, char **argv)
31 {
32     printf("\n*** Testing netcdf nc4internal functions.\n");
33     printf("Testing adding new file to nc4internal file lists with "
34            "nc4_file_list_add()...");
35     {
36         NC *ncp;
37         char *path;
38         /* The NC3_dispatch_table is defined in nc3dispatch.c and
39          * externed in ncdispatch.h. But it will be 0 because we have
40          * not yet called NC3_initialize(). */
41         const void *dispatcher = NC3_dispatch_table;
42         void *dispatchdata_in;
43         int mode = 0, mode_in;
44 
45         /* This won't work because there is no NC in the NC list which
46          * has an ncid of TEST_VAL_42. */
47         if (nc4_file_list_add(TEST_VAL_42, FILE_NAME, 0, NULL) != NC_EBADID) ERR;
48 
49         /* Create the NC* instance and insert its dispatcher */
50         if (new_NC(dispatcher, FILE_NAME, mode, &ncp)) ERR;
51 
52         /* Add to array of open files nc_filelist and define
53          * ext_ncid by left-shifting the index 16 bits. */
54         add_to_NCList(ncp);
55 
56         /* Create the NC_FILE_INFO_T instance associated empty lists
57          * to hold dims, types, groups, and the root group. */
58         if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, mode, NULL)) ERR;
59 
60         /* Find the file in the list. */
61         if (!(path = malloc(NC_MAX_NAME + 1))) ERR;
62         if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR;
63         if (strcmp(path, FILE_NAME)) ERR;
64         free(path);
65         if (mode_in != mode) ERR;
66 
67         /* This won't work. */
68         if (nc4_file_list_del(TEST_VAL_42) != NC_EBADID) ERR;
69 
70         /* Delete the NC_FILE_INFO_T and related storage. */
71         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
72 
73         /* Delete the ncp from the list. (In fact, just null out its
74          * entry in the array of file slots.) */
75         del_from_NCList(ncp); /* Will free empty list. */
76 
77         /* Now free the NC struct. */
78         free_NC(ncp);
79     }
80     SUMMARIZE_ERR;
81     printf("Testing adding new file to nc4internal file lists with "
82            "nc4_nc4f_list_add()...");
83     {
84         NC *ncp, *ncp_in, *ncp_in2;
85         char *path;
86         void *dispatchdata_in;
87         int mode = 0, mode_in;
88         NC_GRP_INFO_T *grp, *grp2;
89         NC_FILE_INFO_T *h5, *h52;
90 
91         /* Create the NC* instance and insert its dispatcher */
92         if (new_NC(NC3_dispatch_table, FILE_NAME, mode, &ncp)) ERR;
93 
94         /* Add to array of open files nc_filelist and define
95          * ext_ncid by left-shifting the index 16 bits. */
96         add_to_NCList(ncp);
97 
98         /* Create the NC_FILE_INFO_T instance associated empty lists
99          * to hold dims, types, groups, and the root group. */
100         if (nc4_nc4f_list_add(ncp, FILE_NAME, mode)) ERR;
101 
102         /* Find the file in the list. */
103         if (!(path = malloc(NC_MAX_NAME + 1))) ERR;
104         if (nc4_file_list_get(ncp->ext_ncid, &path, &mode_in, &dispatchdata_in)) ERR;
105         if (strcmp(path, FILE_NAME)) ERR;
106         free(path);
107         if (mode_in != mode) ERR;
108 
109         /* Find it again. */
110         if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR;
111         if (ncp_in->ext_ncid != ncp->ext_ncid) ERR;
112         if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
113         if (h5->controller->ext_ncid != ncp->ext_ncid) ERR;
114 
115         /* Any of the pointer parameters may be NULL. */
116         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, NULL)) ERR;
117         if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in2, NULL, NULL)) ERR;
118         if (ncp_in2->ext_ncid != ncp->ext_ncid) ERR;
119         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp2, NULL)) ERR;
120         if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
121         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, NULL, &h52)) ERR;
122         if (h52->controller->ext_ncid != ncp->ext_ncid) ERR;
123 
124         /* There are additional functions which use the NULL
125          * parameters of nc4_find_nc_grp_h5(). */
126         grp2 = NULL;
127         h52 = NULL;
128         if (nc4_find_grp_h5(ncp->ext_ncid, NULL, NULL)) ERR;
129         if (nc4_find_grp_h5(ncp->ext_ncid, &grp2, NULL)) ERR;
130         if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
131         if (nc4_find_grp_h5(ncp->ext_ncid, NULL, &h52)) ERR;
132         if (h52->controller->ext_ncid != ncp->ext_ncid) ERR;
133         grp2 = NULL;
134         if (nc4_find_nc4_grp(ncp->ext_ncid, NULL)) ERR;
135         if (nc4_find_nc4_grp(ncp->ext_ncid, &grp2)) ERR;
136         if (grp2->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
137 
138         /* Delete the NC_FILE_INFO_T and related storage. */
139         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
140 
141         /* Delete the ncp from the list. (In fact, just null out its
142          * entry in the array of file slots.) */
143         del_from_NCList(ncp); /* Will free empty list. */
144 
145         /* Now free the NC struct. */
146         free_NC(ncp);
147     }
148     SUMMARIZE_ERR;
149     printf("Testing adding new var to nc4internal file...");
150     {
151         NC *ncp, *ncp_in;
152         NC_GRP_INFO_T *grp;
153         NC_VAR_INFO_T *var, *var_in;
154         NC_FILE_INFO_T *h5;
155 
156         /* Create the NC* instance and insert its dispatcher */
157         if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &ncp)) ERR;
158 
159         /* Add to array of open files nc_filelist and define
160          * ext_ncid by left-shifting the index 16 bits. */
161         add_to_NCList(ncp);
162 
163         /* Create the NC_FILE_INFO_T instance associated empty lists
164          * to hold dims, types, groups, and the root group. */
165         if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
166 
167         /* Find the file in the list. */
168         if (nc4_find_nc_grp_h5(ncp->ext_ncid, &ncp_in, &grp, &h5)) ERR;
169         if (ncp_in->ext_ncid != ncp->ext_ncid) ERR;
170 
171         /* Add a var to the varlist. */
172         if (nc4_var_list_add(grp, VAR_NAME, 0, &var)) ERR;
173 
174         /* Find the var. */
175         if (nc4_find_var(grp, VAR_NAME, &var_in)) ERR;
176         if (strcmp(var_in->hdr.name, var->hdr.name)) ERR;
177 
178         /* Find it again. */
179         h5 = NULL;
180         grp = NULL;
181         var_in = NULL;
182         if (nc4_find_grp_h5_var(ncp->ext_ncid, 0, &h5, &grp, &var_in)) ERR;
183         if (h5->controller->ext_ncid != ncp->ext_ncid) ERR;
184         if (grp->nc4_info->controller->ext_ncid != ncp->ext_ncid) ERR;
185         if (strcmp(var_in->hdr.name, var->hdr.name)) ERR;
186 
187         /* Delete the NC_FILE_INFO_T and related storage, including
188          * all vars, dims, types, etc. */
189         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
190 
191         /* Delete the ncp from the list. (In fact, just null out its
192          * entry in the array of file slots.) */
193         del_from_NCList(ncp); /* Will free empty list. */
194 
195         /* Now free the NC struct. */
196         free_NC(ncp);
197     }
198     SUMMARIZE_ERR;
199     printf("Testing adding new dim to nc4internal file...");
200     {
201         NC *ncp;
202         NC_GRP_INFO_T *grp, *dim_grp;
203         NC_DIM_INFO_T *dim, *dim_in;
204 
205         /* Create the NC, add it to nc_filelist array, add and init
206          * NC_FILE_INFO_T. */
207         if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &ncp)) ERR;
208         add_to_NCList(ncp);
209         if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
210         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, NULL)) ERR;
211 
212         /* Add a dim. */
213         if (nc4_dim_list_add(grp, DIM_NAME, DIM_LEN, 0, &dim)) ERR;
214 
215         /* Find the dim. */
216         if (nc4_find_dim(grp, 0, &dim_in, &dim_grp)) ERR;
217         if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR;
218         if (strcmp(dim_grp->hdr.name, grp->hdr.name)) ERR;
219         dim_in = NULL;
220         if (nc4_find_dim(grp, 0, &dim_in, NULL)) ERR;
221         if (strcmp(dim_in->hdr.name, dim->hdr.name)) ERR;
222 
223         /* Release resources. */
224         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
225         del_from_NCList(ncp);
226         free_NC(ncp);
227     }
228     SUMMARIZE_ERR;
229     printf("Testing adding new type to nc4internal file...");
230     {
231         NC *ncp;
232         NC_GRP_INFO_T *grp;
233         NC_TYPE_INFO_T *type, *type_in;
234         NC_FILE_INFO_T *h5;
235 
236         /* Create the NC, add it to nc_filelist array, add and init
237          * NC_FILE_INFO_T. */
238         if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &ncp)) ERR;
239         add_to_NCList(ncp);
240         if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
241         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR;
242 
243         /* Add a type. */
244         if (nc4_type_list_add(grp, TYPE_SIZE, TYPE_NAME, &type)) ERR;
245 
246         /* Add a field to the type. */
247         /* if (nc4_field_list_add(type, FIELD_NAME, FIELD_OFFSET, NC_INT, 0, */
248         /*                        NULL)) ERR; */
249 
250         /* Find it. */
251         if (nc4_find_type(h5, type->hdr.id, &type_in)) ERR;
252         if (strcmp(type_in->hdr.name, type->hdr.name)) ERR;
253 
254         /* Release resources. */
255         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
256         del_from_NCList(ncp);
257         free_NC(ncp);
258     }
259     SUMMARIZE_ERR;
260     printf("Testing changing ncid...");
261     {
262         NC *ncp;
263         NC_GRP_INFO_T *grp;
264         NC_FILE_INFO_T *h5;
265         int old_ncid;
266 
267         /* Create the NC, add it to nc_filelist array, add and init
268          * NC_FILE_INFO_T. */
269         if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &ncp)) ERR;
270         add_to_NCList(ncp);
271         if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR;
272         if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR;
273 
274         /* Change the ncid. */
275         old_ncid = ncp->ext_ncid;
276         if (nc4_file_change_ncid(ncp->ext_ncid, TEST_VAL_42)) ERR;
277 
278         /* Can't find old ncid. */
279         if (nc4_find_nc_grp_h5(old_ncid, NULL, NULL, NULL) != NC_EBADID) ERR;
280 
281         /* Delete it. */
282         if (nc4_file_list_del(ncp->ext_ncid)) ERR;
283         del_from_NCList(ncp); /* Will free empty list. */
284         free_NC(ncp);
285 
286         /* Ensure it is no longer in list. */
287         /* if (find_in_NCList(ncp->ext_ncid)) ERR; */
288 
289     }
290     SUMMARIZE_ERR;
291     FINAL_RESULTS;
292 }
293