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


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed