1 /*********************************************************************
2 * Copyright 1993, UCAR/Unidata
3 * See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 * $Id$
5 *********************************************************************/
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "h4config.h"
12 #ifdef H4_HAVE_NETCDF
13 #include "netcdf.h"
14 #else
15 #include "hdf4_netcdf.h"
16 #endif
17 #include "testcdf.h" /* defines in-memory test netcdf structure */
18 #include "add.h" /* functions to update in-memory netcdf */
19 #include "error.h"
20 #include "tests.h"
21 #include "alloc.h"
22 #include "emalloc.h"
23 #ifdef HDF
24 #include "hdf.h"
25 #endif
26
27 #define LEN_OF(array) ((sizeof array) / (sizeof array[0]))
28
29
30 /*
31 * Test nccreate
32 * create a netcdf with no data, close it, test that it can be opened
33 * try again with NC_CLOBBER mode, check that no errors occurred
34 * try again with NC_NOCLOBBER mode, check error return
35 * On exit, netcdf files are closed.
36 * Uses: nccreate, ncendef, ncclose, ncopen.
37 */
38 void
test_nccreate(path)39 test_nccreate(path)
40 char *path; /* name of cdf file to create */
41 {
42 int nerrs = 0;
43 static char pname[] = "test_nccreate";
44 int cdfid;
45
46 (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
47
48 if ((cdfid = nccreate(path, NC_CLOBBER)) == -1) {
49 error("%s: nccreate failed to NC_CLOBBER", pname);
50 return;
51 }
52 /* created OK */
53 if (ncendef (cdfid) == -1) {
54 error("%s: ncendef failed", pname);
55 nerrs++;
56 }
57 if (ncclose (cdfid) == -1) {
58 error("%s: ncclose failed", pname);
59 nerrs++;
60 }
61 if ((cdfid = ncopen(path, NC_NOWRITE)) == -1) {
62 error("%s: ncopen of newly created netcdf failed", pname);
63 return;
64 }
65 /* opened OK */
66 if (ncclose (cdfid) == -1) {
67 error("%s: second ncclose failed", pname);
68 nerrs++;
69 }
70 /* this call should fail, since we're using NC_NOCLOBBER mode */
71 if ((cdfid = nccreate(path, NC_NOCLOBBER)) != -1) {
72 error("%s: nccreate failed to honor NC_NOCLOBBER mode", pname);
73 nerrs++;
74 }
75
76 /* Initialize in-memory netcdf to empty */
77 add_reset(&test);
78 if (nerrs > 0)
79 (void) fprintf(stderr,"FAILED! ***\n");
80 else
81 (void) fprintf(stderr,"ok ***\n");
82 }
83
84
85 /*
86 * Test ncopen
87 * try to open a non-existent netCDF, check error return
88 * open a netCDF with NC_WRITE mode, write something, close it
89 * open a netCDF with NC_NOWRITE mode, write something and check error
90 * try to open a netcdf twice, check whether returned cdf ids different
91 * On exit, netcdf files are closed.
92 * Uses: ncopen, ncredef, ncattput, ncendef, ncclose.
93 */
94 void
test_ncopen(path)95 test_ncopen(path)
96 char *path; /* name of writable netcdf file to open */
97 {
98 int nerrs = 0;
99 static char pname[] = "test_ncopen";
100 int cdfid0, cdfid1;
101 static char title_val[] = "test netcdf";
102 static char xpath[] = "tooth-fairy.cdf"; /* must not exist */
103 static struct cdfatt title = /* attribute */
104 {NC_GLOBAL, "title", NC_CHAR, LEN_OF (title_val), (void *) title_val};
105
106 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
107
108 if((cdfid0 = ncopen(xpath, NC_NOWRITE)) != -1) {
109 error("%s: ncopen should fail opening nonexistent file",
110 pname);
111 return;
112 }
113 if((cdfid0 = ncopen(xpath, NC_WRITE)) != -1) {
114 error("%s: ncopen should fail writing nonexistent file",
115 pname);
116 return;
117 }
118 if ((cdfid0 = ncopen(path, NC_WRITE)) == -1) {
119 error("%s: ncopen failed with NC_WRITE mode", pname);
120 return;
121 }
122 /* opened */
123 if (ncredef(cdfid0) == -1) {
124 error("%s: cdredef failed", pname);
125 ncclose(cdfid0); return;
126 }
127 /* in define mode */
128 if (ncattput(cdfid0, NC_GLOBAL, "title", NC_CHAR, title.len, title.val)
129 == -1) {
130 error("%s: ncattput failed", pname);
131 ncclose(cdfid0); return;
132 }
133 add_att(&test, NC_GLOBAL, &title); /* keep in-memory netcdf updated */
134 if (ncendef (cdfid0) == -1) {
135 error("%s: ncendef failed after ncattput", pname);
136 ncclose(cdfid0); return;
137 }
138 if (ncclose (cdfid0) == -1) {
139 error("%s: ncclose failed in NC_WRITE mode", pname);
140 return;
141 }
142
143 if ((cdfid0 = ncopen(path, NC_NOWRITE)) == -1) {
144 error("%s: ncopen failed with NC_NOWRITE mode", pname);
145 return;
146 }
147 /* opened */
148 /* this should fail, since in NC_NOWRITE mode */
149 if (ncredef(cdfid0) != -1) {
150 error("%s: cdredef should fail after NC_NOWRITE open", pname);
151 ncclose(cdfid0); return;
152 }
153
154 if ((cdfid1 = ncopen(path, NC_WRITE)) == -1) {
155 error("%s: second ncopen failed", pname);
156 nerrs++;
157 }
158 else
159 {
160 /* second open OK */
161 if (cdfid0 == cdfid1) {
162 error("%s: ncopen should return new cdfid on second open",
163 pname);
164 nerrs++;
165 }
166 if (ncclose (cdfid1) == -1) {
167 error("%s: ncclose failed to close after second open", pname);
168 nerrs++;
169 }
170 }
171
172 if (ncclose (cdfid0) == -1) {
173 error("%s: ncclose failed in NC_NOWRITE mode", pname);
174 nerrs++;
175 }
176 if (nerrs > 0)
177 (void) fprintf(stderr,"FAILED! ***\n");
178 else
179 (void) fprintf(stderr,"ok ***\n");
180 }
181
182
183 /*
184 * Test ncredef
185 * open a netCDF, enter define mode, add dimension, variable, attribute
186 * try ncredef from within define mode, check error
187 * leave define mode and close, releasing netcdf handle
188 * try ncredef with old handle, check error
189 * On exit netcdf files are closed.
190 * Uses: ncopen, ncredef, ncdimdef, ncvardef, ncattput, ncclose
191 */
192 void
test_ncredef(path)193 test_ncredef(path)
194 char *path; /* name of writable netcdf file to open */
195 {
196 int nerrs = 0;
197 static char pname[] = "test_ncredef";
198 int cdfid; /* netcdf id */
199 int ii_dim; /* dimension id */
200 static struct cdfdim ii = /* dimension */
201 {"ii", 4};
202 int aa_id; /* variable id */
203 static struct cdfvar aa = /* variable */
204 {"aa", NC_LONG, 1, ___, 0};
205 static char units_val[] = "furlongs";
206 static struct cdfatt aa_units = /* attribute */
207 {___, "units", NC_CHAR, LEN_OF(units_val), (void *)units_val};
208
209 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
210
211 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
212 error("%s: ncopen failed", pname);
213 return;
214 }
215 /* opened OK, enter define mode */
216 if (ncredef(cdfid) == -1) {
217 error("%s: cdredef failed", pname);
218 ncclose(cdfid); return;
219 }
220 /* in define mode OK, add a dimension */
221 if ((ii_dim = ncdimdef(cdfid, ii.name, ii.size)) == -1) {
222 error("%s: ncdimdef failed", pname);
223 ncclose(cdfid); return;
224 }
225 add_dim(&test, &ii); /* keep in-memory netcdf in sync */
226
227 /* dimension added OK, add a variable */
228 aa.dims = (int *)emalloc(sizeof(int) * aa.ndims);
229 aa.dims[0] = ii_dim;
230 if ((aa_id = ncvardef(cdfid, aa.name, aa.type,
231 aa.ndims, aa.dims)) == -1) {
232 error("%s: ncvardef failed", pname);
233 ncclose(cdfid); return;
234 }
235 add_var(&test, &aa); /* keep in-memory netcdf in sync */
236
237 /* variable added OK, add a variable attribute */
238 aa_units.var = aa_id;
239 if (ncattput(cdfid, aa_units.var, aa_units.name,
240 aa_units.type, aa_units.len, (void *) aa_units.val) == -1) {
241 error("%s: ncattput failed", pname);
242 ncclose(cdfid); return;
243 }
244 add_att(&test, aa_id, &aa_units); /* keep in-memory netcdf in sync */
245
246 if (ncredef(cdfid) != -1) {
247 error("%s: cdredef in define mode should have failed", pname);
248 ncclose(cdfid); return;
249 }
250 if (ncendef (cdfid) == -1) {
251 error("%s: ncendef failed", pname);
252 ncclose(cdfid); return;
253 }
254 if (ncclose (cdfid) == -1) {
255 error("%s: ncclose failed", pname);
256 return;
257 }
258 if (ncredef(cdfid) != -1) {
259 error("%s: ncredef failed to report bad cdf handle", pname);
260 nerrs++;
261 }
262 Free ((char *)aa.dims);
263 if (nerrs > 0)
264 (void) fprintf(stderr,"FAILED! ***\n");
265 else
266 (void) fprintf(stderr,"ok ***\n");
267 }
268
269
270 /*
271 * Test ncendef
272 * check return from proper cdfendif after define mode
273 * try ncendef when in data mode, check error
274 * try ncendef with bad handle, check error
275 * On exit netcdf files are closed.
276 * Uses: ncopen, ncredef, ncdimdef, ncvardef, ncattput, ncendef, ncclose
277 */
278 void
test_ncendef(path)279 test_ncendef(path)
280 char *path; /* name of writable netcdf file to open */
281 {
282 int nerrs = 0;
283 static char pname[] = "test_ncendef";
284 int cdfid; /* netcdf id */
285 int jj_dim, kk_dim; /* dimension ids */
286 int bb_id; /* variable id */
287 static struct cdfdim kk = /* dimension */
288 {"kk", 3};
289 static struct cdfdim jj = /* dimension */
290 {"jj", 3};
291 static struct cdfvar bb = /* variable */
292 {"bb", NC_LONG, 2, ___, 0};
293 static float bb_rangev[2] = {0., 100.}; /* attribute vector */
294 static struct cdfatt bb_range = /* attribute */
295 {___, "valid_range", NC_FLOAT, LEN_OF(bb_rangev), (void *)bb_rangev};
296
297 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
298
299 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
300 error("%s: ncopen failed", pname);
301 return;
302 }
303 /* opened */
304 if (ncredef(cdfid) == -1) {
305 error("%s: ncredef failed", pname);
306 ncclose(cdfid); return;
307 }
308 /* in define mode, add dimensions */
309 if ((jj_dim = ncdimdef(cdfid, jj.name, jj.size)) == -1 ||
310 (kk_dim = ncdimdef(cdfid, kk.name, kk.size)) == -1) {
311 error("%s: ncdimdef failed", pname);
312 ncclose(cdfid); return;
313 }
314 add_dim(&test, &jj); /* keep in-memory netcdf in sync */
315 add_dim(&test, &kk); /* keep in-memory netcdf in sync */
316
317 /* dimensions added OK, add a variable */
318 bb.dims = (int *) emalloc(sizeof(int) * bb.ndims);
319 bb.dims[0] = kk_dim;
320 bb.dims[1] = jj_dim;
321 if ((bb_id = ncvardef(cdfid, bb.name, bb.type,
322 bb.ndims, bb.dims)) == -1) {
323 error("%s: ncvardef failed", pname);
324 ncclose(cdfid); return;
325 }
326 add_var(&test, &bb); /* keep in-memory netcdf in sync */
327
328 /* variable added OK, add a variable attribute */
329 if (ncattput(cdfid, bb_id, bb_range.name, bb_range.type, bb_range.len,
330 (void *) bb_range.val) == -1) {
331 error("%s: ncattput failed", pname);
332 ncclose(cdfid); return;
333 }
334 add_att(&test, bb_id, &bb_range); /* keep in-memory netcdf in sync */
335
336 if (ncendef (cdfid) == -1) {
337 error("%s: ncendef failed", pname);
338 ncclose(cdfid); return;
339 }
340 /* in data mode */
341 if (ncendef (cdfid) != -1) { /* should fail in data mode */
342 error("%s: ncendef in data mode should have failed", pname);
343 ncclose(cdfid); return;
344 }
345 if (ncclose (cdfid) == -1) {
346 error("%s: ncclose failed", pname);
347 return;
348 }
349 /* should fail on a bad handle */
350 if (ncendef (cdfid) != -1) {
351 error("ncendef failed to report bad netcdf handle");
352 nerrs++;
353 }
354 if (nerrs > 0)
355 (void) fprintf(stderr,"FAILED! ***\n");
356 else
357 (void) fprintf(stderr,"ok ***\n");
358 }
359
360
361 /*
362 * Test ncclose
363 * try on open netCDF
364 * try in define mode and data mode
365 * try with bad handle, check error
366 * On exit netcdf files are closed.
367 */
368 void
test_ncclose(path)369 test_ncclose(path)
370 char *path; /* name of writable netcdf file to open */
371 {
372 int nerrs = 0;
373 static char pname[] = "test_ncclose";
374 int cdfid; /* netcdf id */
375
376 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
377
378 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
379 error("%s: ncopen failed", pname);
380 return;
381 }
382 /* opened */
383 if (ncredef(cdfid) == -1) {
384 error("%s: ncredef failed", pname);
385 ncclose(cdfid); return;
386 }
387 /* in define mode */
388 if (ncclose (cdfid) == -1) {
389 error("%s: ncclose in define mode failed", pname);
390 nerrs++;
391 }
392
393 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
394 error("%s: ncopen failed", pname);
395 return;
396 }
397 /* in data mode */
398 if (ncclose (cdfid) == -1) {
399 error("%s: ncclose failed", pname);
400 nerrs++;
401 }
402 if (ncclose (cdfid) != -1) { /* should fail, since cdfid is a bad handle */
403 error("%s: ncclose failed to report bad cdf handle ", pname);
404 nerrs++;
405 }
406 if (nerrs > 0)
407 (void) fprintf(stderr,"FAILED! ***\n");
408 else
409 (void) fprintf(stderr,"ok ***\n");
410 }
411
412
413 /*
414 * Test ncinquire
415 * try in data mode, check returned values
416 * try in define mode, after adding an unlimited dimension, variable
417 * try with bad handle, check error
418 * On exit netcdf files are closed.
419 */
420 void
test_ncinquire(path)421 test_ncinquire(path)
422 char *path; /* name of writable netcdf file to open */
423 {
424 int nerrs = 0;
425 static char pname[] = "test_ncinquire";
426 int cdfid; /* netcdf id */
427 int ndims; /* number of dimensions */
428 int nvars; /* number of variables */
429 int ngatts; /* number of global attributes */
430 int xdimid; /* id of unlimited dimension */
431 int rec_dim; /* dimension id */
432 static struct cdfdim rec = /* dimension */
433 {"rec", NC_UNLIMITED};
434 static struct cdfdim dims[] = { /* dimensions */
435 {"i1", 5},{"i2", 3},{"i3", 7}
436 };
437 int id, nd = LEN_OF(dims); /* number of dimensions */
438 int dimids[LEN_OF(dims)];
439 int cc_id; /* variable id */
440 static struct cdfvar cc[] = { /* record variables of various sizes */
441 {"cc", NC_LONG, 1, ___, 0},
442 {"cd", NC_SHORT, 2, ___, 0},
443 {"ce", NC_FLOAT, 3, ___, 0}
444 };
445 int iv;
446 int nv = LEN_OF(cc); /* number of record variables */
447 static char units_val[] = "moles";
448 static struct cdfatt cc_units = /* attribute */
449 {___, "units", NC_CHAR, LEN_OF(units_val), (void *)units_val};
450
451 (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
452
453 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
454 error("%s: ncopen failed", pname);
455 return;
456 }
457 /* opened, in data mode */
458 if (ncinquire(cdfid, &ndims, &nvars, &ngatts, &xdimid) == -1) {
459 error("%s: ncinquire in data mode failed", pname);
460 ncclose(cdfid); return;
461 }
462 /* compare returned with expected values */
463 if (ndims != test.ndims) {
464 error("%s: ndims returned as %d, expected %d",
465 pname, ndims, test.ndims);
466 nerrs++;
467 }
468 if (nvars != test.nvars) {
469 error("%s: nvars returned as %d, expected %d",
470 pname, nvars, test.nvars);
471 nerrs++;
472 }
473 if (ngatts != test.ngatts) {
474 error("%s: ngatts returned as %d, expected %d",
475 pname, ngatts, test.ngatts);
476 nerrs++;
477 }
478 if (xdimid != test.xdimid) {
479 error("%s: xdimid returned as %d, expected %d",
480 pname, xdimid, test.xdimid);
481 nerrs++;
482 }
483
484 if (ncredef(cdfid) == -1) {
485 error("%s: ncredef failed", pname);
486 ncclose(cdfid); return;
487 }
488 /* add dimensions */
489 for (id = 0; id < nd; id++) {
490 if ((dimids[id] = ncdimdef(cdfid, dims[id].name, dims[id].size))
491 == -1) {
492 error("%s: ncdimdef failed on normal dimension", pname);
493 ncclose(cdfid); return;
494 }
495 add_dim(&test, &dims[id]);
496 }
497
498 /* add an unlimited dimension */
499 if ((rec_dim = ncdimdef(cdfid, rec.name, rec.size)) == -1) {
500 error("%s: ncdimdef failed on NC_UNLIMITED dimension", pname);
501 ncclose(cdfid); return;
502 }
503 add_dim(&test, &rec);
504
505 /* add some record variables */
506 for (iv = 0; iv < nv; iv++) {
507 cc[iv].dims = (int *) emalloc(sizeof(int) * cc[iv].ndims);
508 cc[iv].dims[0] = rec_dim; /* first dimension unlimited */
509 for (id = 1; id < cc[iv].ndims; id++)
510 cc[iv].dims[id] = dimids[id];
511 if ((cc_id = ncvardef(cdfid, cc[iv].name, cc[iv].type,
512 cc[iv].ndims, cc[iv].dims)) == -1) {
513 error("%s: ncvardef failed", pname);
514 ncclose(cdfid); return;
515 }
516 add_var(&test, &cc[iv]);
517
518 /* add a variable attribute */
519 if (ncattput(cdfid, cc_id, cc_units.name, cc_units.type,
520 cc_units.len, (void *) cc_units.val) == -1) {
521 error("%s: ncattput failed", pname);
522 ncclose(cdfid); return;
523 }
524 add_att(&test, cc_id, &cc_units);
525 }
526 /* try calling from define mode, compare returned values to expected */
527 if (ncinquire(cdfid, &ndims, &nvars, &ngatts, &xdimid) == -1) {
528 error("%s: ncinquire in define mode failed", pname);
529 ncclose(cdfid); return;
530 }
531 /* compare returned with expected values */
532 if (ndims != test.ndims) {
533 error("%s: ndims returned as %d, expected %d",
534 pname, ndims, test.ndims);
535 nerrs++;
536 }
537 if (nvars != test.nvars) {
538 error("%s: nvars returned as %d, expected %d",
539 pname, nvars, test.nvars);
540 nerrs++;
541 }
542 if (ngatts != test.ngatts) {
543 error("%s: ngatts returned as %d, expected %d",
544 pname, ngatts, test.ngatts);
545 nerrs++;
546 }
547 if (xdimid != test.xdimid) {
548 error("%s: xdimid returned as %d, expected %d",
549 pname, xdimid, test.xdimid);
550 nerrs++;
551 }
552
553 if (ncendef (cdfid) == -1) {
554 error("%s: ncendef failed", pname);
555 ncclose(cdfid); return;
556 }
557
558 if (ncclose (cdfid) == -1) {
559 error("%s: ncclose failed", pname);
560 return;
561 }
562 /* should fail, since bad handle */
563 if (ncinquire (cdfid, &ndims, &nvars, &ngatts, &xdimid) != -1) {
564 error("%s: ncinquire failed to report bad netcdf handle ", pname);
565 nerrs++;
566 }
567 if (nerrs > 0)
568 (void) fprintf(stderr,"FAILED! ***\n");
569 else
570 (void) fprintf(stderr,"ok ***\n");
571 }
572
573
574 /*
575 * Test ncsync
576 * try in define mode, check error
577 * try writing with one handle, reading with another on same netCDF
578 * try with bad handle, check error
579 * On exit netcdf files are closed.
580 */
581 void
test_ncsync(path)582 test_ncsync(path)
583 char *path; /* name of writable netcdf file to open */
584 {
585 int nerrs = 0;
586 static char pname[] = "test_ncsync";
587 int cdfid0, cdfid1; /* netcdf ids */
588 int ll_dim; /* dimension id */
589 static struct cdfdim ll = /* dimension */
590 {"ll", 3};
591 int dd_id; /* variable id */
592 static struct cdfvar dd = /* variable */
593 {"dd", NC_SHORT, 1, ___, 0};
594 static short dd_fill_valv[] = {-999};
595 static struct cdfatt dd_fill_val = /* attribute */
596 {___, "fill_value", NC_SHORT, LEN_OF(dd_fill_valv), (void *) dd_fill_valv};
597
598 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
599
600 if ((cdfid0 = ncopen(path, NC_WRITE)) == -1) {
601 error("%s: ncopen in NC_WRITE mode failed", pname);
602 return;
603 }
604
605 /* opened */
606 if (ncredef(cdfid0) == -1) {
607 error("%s: ncredef failed", pname);
608 ncclose(cdfid0); return;
609 }
610 /* in define mode, add a dimension, variable, and attribute */
611 if ((ll_dim = ncdimdef(cdfid0, ll.name, ll.size)) == -1) {
612 error("%s: ncdimdef failed", pname);
613 ncclose(cdfid0);
614 return;
615 }
616 add_dim(&test, &ll);
617
618 dd.dims = (int *) emalloc(sizeof(int) * dd.ndims);
619 dd.dims[0] = ll_dim;
620 if ((dd_id=ncvardef(cdfid0, dd.name, dd.type, dd.ndims, dd.dims)) == -1) {
621 error("%s: ncvardef failed", pname);
622 ncclose(cdfid0);
623 return;
624 }
625 add_var(&test, &dd);
626
627 if (ncattput(cdfid0, dd_id, dd_fill_val.name, dd_fill_val.type,
628 dd_fill_val.len, (void *) dd_fill_val.val) == -1) {
629 error("%s: ncattput failed", pname);
630 ncclose(cdfid0);
631 return;
632 }
633 add_att(&test, dd_id, &dd_fill_val);
634
635 if (ncsync (cdfid0) != -1) {
636 error("%s: ncsync in define mode should fail", pname);
637 nerrs++;
638 }
639
640 if (ncendef (cdfid0) == -1) {
641 error("%s: ncendef failed", pname);
642 ncclose(cdfid0); return;
643 }
644 /* in data mode */
645 if (ncsync (cdfid0) == -1) {
646 error("%s: ncsync in data mode failed", pname);
647 nerrs++;
648 }
649
650 /* put some data into a variable */
651 {
652 static long dd_start[] = {0};
653 static long dd_edges[] = {2};
654 static short dd_vals[] = {1, 2};
655 short got_vals[2];
656
657 if (ncvarput(cdfid0,dd_id,dd_start,dd_edges,(void *)dd_vals) == -1) {
658 error("%s: ncvarput failed", pname);
659 ncclose(cdfid0);
660 return;
661 }
662 add_data(&test,dd_id,dd_start,dd_edges); /* keep test in sync */
663 if (ncsync (cdfid0) == -1) {
664 error("%s: ncsync after putting data failed", pname);
665 nerrs++;
666 }
667
668 if ((cdfid1 = ncopen(path, NC_NOWRITE)) == -1) {
669 error("%s: second ncopen failed", pname);
670 nerrs++;
671 } else {
672 if (cdfid0 == cdfid1) {
673 error("%s: second ncopen should return distinct handle",
674 pname);
675 nerrs++;
676 } /* read data just put after a sync, should succeed */
677 if (ncvarget(cdfid1,dd_id,dd_start,dd_edges,(void *)got_vals)
678 == -1) {
679 error("%s: ncvarget failed", pname);
680 nerrs++;
681 }
682 if (dd_vals[0] != got_vals[0] || dd_vals[1] != got_vals[1]) {
683 error("%s: ncvarget succeeded but data values wrong",
684 pname);
685 }
686 if (ncclose (cdfid1) == -1) {
687 error("%s: ncclose failed", pname);
688 nerrs++;
689 }
690 }
691 }
692 if (ncclose (cdfid0) == -1) {
693 error("%s: ncclose failed", pname);
694 nerrs++;
695 }
696 if (ncsync (cdfid0) != -1) { /* should fail, since cdfid0 is bad handle */
697 error("%s: ncsync failed to report bad cdf handle ", pname);
698 nerrs++;
699 }
700 if (nerrs > 0)
701 (void) fprintf(stderr,"FAILED! ***\n");
702 else
703 (void) fprintf(stderr,"ok ***\n");
704 }
705
706
707 /*
708 * Test ncabort
709 * try in define mode, check that file was deleted
710 * try after writing variable
711 * try with bad handle, check error
712 * On exit netcdf files are closed.
713 */
714 void
test_ncabort(path)715 test_ncabort(path)
716 char *path; /* name of writable netcdf file to open */
717 {
718 int nerrs = 0;
719 static char pname[] = "test_ncabort";
720 static char fpath[] = "ufo.cdf";
721 static short attv[] = {3};
722 static struct cdfatt att = /* attribute */
723 {___, "temp", NC_SHORT, LEN_OF(attv), (void *) attv};
724 int cdfid; /* netcdf id */
725
726 (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
727
728 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
729 error("%s: ncopen failed", pname);
730 return;
731 }
732 /* opened */
733 if (ncredef(cdfid) == -1) {
734 error("%s: ncredef failed", pname);
735 ncclose(cdfid); return;
736 }
737 /* in define mode, add a new global attribute */
738 if (ncattput(cdfid, NC_GLOBAL, att.name, att.type, att.len, att.val) == -1) {
739 error("%s: ncattput failed", pname);
740 ncclose(cdfid); return;
741 }
742
743 /* abort in define mode, should restore to state before define mode */
744 if (ncabort(cdfid) == -1) {
745 error("%s: ncabort in define mode failed", pname);
746 ncclose(cdfid); return;
747 }
748 if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
749 error("%s: ncopen after ncabort failed", pname);
750 return;
751 }
752 /* check that new global attribute was not added */
753 if (ncattinq(cdfid, NC_GLOBAL, att.name, &att.type, &att.len) != -1) {
754 error("%s: ncabort should have restored state before ncredef", pname);
755 ncclose(cdfid); return;
756 }
757 /* in data mode not being created, should just close */
758 if (ncabort(cdfid) == -1) {
759 error("%s: ncabort in define mode failed", pname);
760 return;
761 }
762 if ((cdfid = nccreate(fpath, NC_CLOBBER)) == -1) {
763 error("%s: nccreate failed to NC_CLOBBER", pname);
764 return;
765 }
766 /* in define mode being created, should delete */
767 if (ncabort(cdfid) == -1) {
768 error("%s: ncabort after nccreate failed", pname);
769 return;
770 }
771 /* check with ncopen that file doesn't exist */
772 if (ncopen(fpath, NC_NOWRITE) != -1) {
773 error("%s: ncabort deleted file, but ncopen found it", pname);
774 return;
775 }
776 if (ncabort(cdfid) != -1) { /* should fail, cdfid is bad handle */
777 error("%s: ncclose failed to report bad cdf handle ", pname);
778 nerrs++;
779 }
780 if (nerrs > 0)
781 (void) fprintf(stderr,"FAILED! ***\n");
782 else
783 (void) fprintf(stderr,"ok ***\n");
784 }
785