ncdf4a13/nctest/dimtests.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *   Copyright 1993, UCAR/Unidata
00003  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
00004  *   $Header: /upc/share/CVS/netcdf-3/nctest/dimtests.c,v 1.13 2005/03/17 14:59:18 ed Exp $
00005  *********************************************************************/
00006 
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <stdlib.h>             /* for free() */
00010 #include "netcdf.h"
00011 #include "emalloc.h"
00012 #include "testcdf.h"            /* defines in-memory test cdf structure */
00013 #include "add.h"                /* functions to update in-memory netcdf */
00014 #include "error.h"
00015 #include "tests.h"
00016 
00017 /* 
00018  * Test ncdimdef
00019  *    try in data mode, check error
00020  *    check that returned id is one more than previous id
00021  *    try adding same dimension twice, check error
00022  *    try with illegal sizes, check error
00023  *    make sure unlimited size works, shows up in ncinquire(...,*xtendim)
00024  *    try to define a second unlimited dimension, check error
00025  */
00026 int
00027 test_ncdimdef(path)
00028      const char *path;          /* name of writable netcdf to open */
00029 {
00030     int nerrs = 0;
00031     static char pname[] = "test_ncdimdef";
00032     int cdfid;                  /* netcdf id */
00033     static struct cdfdim mm =   /* dimension */
00034       {"mm", 1};                /* 1 should be a valid dimension size */
00035     static struct cdfdim nn =   /* dimension */
00036       {"bogus", ___};           /* used for testing invalid dimension sizes */
00037     static struct cdfdim rec =  /* dimension */
00038       {"rec", NC_UNLIMITED};
00039     int ndims;                  /* number of dimensions */
00040     int nvars;                  /* number of variables */
00041     int natts;                  /* number of attributes */
00042     int xdimid;                 /* id of unlimited dimension, or -1 if none */
00043     int dimid;                  /* dimension id */
00044 
00045     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
00046 
00047     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
00048         error("%s: ncopen failed", pname);
00049         return ++nerrs;
00050     }
00051     /* opened, defining a dimension should fail in data mode */
00052     if (ncdimdef(cdfid, mm.name, mm.size) != -1) {
00053         error("%s: ncdimdef should have failed in data mode", pname);
00054         ncclose(cdfid); return ++nerrs;
00055     }
00056     /* enter define mode */
00057     if (ncredef(cdfid) == -1) {
00058         error("%s: cdredef failed", pname);
00059         ncclose(cdfid); return ++nerrs;
00060     }
00061     /* in define mode OK, add a dimension */
00062     if ((dimid = ncdimdef(cdfid, mm.name, mm.size)) == -1) {
00063         error("%s: ncdimdef failed", pname);
00064         ncclose(cdfid); return ++nerrs;
00065     }
00066     add_dim(&test, &mm);        /* keep in-memory netcdf in sync */
00067     /* check that dim id returned is one more than previous dim id */
00068     if (dimid != test.ndims - 1) {
00069         error("%s: ncdimdef returned %d for dim id, expected %d",
00070               pname, dimid, test.ndims-1);
00071         ncclose(cdfid); return ++nerrs;
00072     }
00073 
00074     /* try adding same dimension again, this should fail */
00075     if (ncdimdef(cdfid, mm.name, mm.size) != -1) {
00076         error("%s: ncdimdef should not have allowed redefinition", pname);
00077         ncclose(cdfid); return ++nerrs;
00078     }
00079     /* try adding dimension with negative size, this should fail */
00080     if (ncdimdef(cdfid, nn.name, (long) -10) != -1) {
00081         error("%s: ncdimdef should not allow negative size dimension", pname);
00082         ncclose(cdfid); return ++nerrs;
00083     }
00084     /* if there is not already an unlimited size dimension, try adding one */
00085     if (ncinquire(cdfid, &ndims, &nvars, &natts, &xdimid) == -1) {
00086         error("%s: ncinquire failed", pname);
00087         ncclose(cdfid); return ++nerrs;
00088     }
00089     if (xdimid == -1) {
00090         if (ncdimdef(cdfid, rec.name, rec.size) == -1) {
00091             error("%s: ncdimdef failed on NC_UNLIMITED dimension", pname);
00092             ncclose(cdfid); return ++nerrs;
00093         }
00094         add_dim(&test, &rec);
00095     }
00096     /* try adding another unlimited dimension, which should fail */
00097     if (ncdimdef(cdfid, "rec2", rec.size) != -1) {
00098         error("%s: ncdimdef should not allow second NC_UNLIMITED dimension",
00099               pname);
00100         ncclose(cdfid); return ++nerrs;
00101     }
00102     if (ncendef (cdfid) == -1) {
00103         error("%s: ncendef failed", pname);
00104         ncclose(cdfid); return ++nerrs;
00105     }
00106     if (ncclose (cdfid) == -1) {
00107         error("%s: ncclose failed", pname);
00108         return ++nerrs;
00109     }
00110     if (ncdimdef(cdfid, "rec2", rec.size) != -1) {
00111         error("%s: ncdimdef should fail on bad netCDF id", pname);
00112         nerrs++;
00113     }
00114     if (nerrs > 0)
00115       (void) fprintf(stderr,"FAILED! ***\n");
00116     else
00117       (void) fprintf(stderr,"ok ***\n");
00118 
00119     return nerrs;
00120 }
00121 
00122 
00123 /*
00124  * Test ncdimid
00125  *    check return with defined dimension in both modes
00126  *    try with undefined dimension, check error
00127  *    check return with unlimited size dimension
00128  *    try with bad handle, check error
00129  */
00130 int
00131 test_ncdimid(path)
00132      const char *path;          /* name of writable netcdf file to open */
00133 {
00134     int nerrs = 0;
00135     static char pname[] = "test_ncdimid";
00136     int cdfid;                  /* netcdf id */
00137     int nn_dim;                 /* dimension id */
00138     static struct cdfdim nn =   /* dimension */
00139       {"nn", 1};                /* 1 should be a valid dimension size */
00140 
00141     (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
00142 
00143     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
00144         error("%s: ncopen failed", pname);
00145         return ++nerrs;
00146     }
00147     /* opened, enter define mode */
00148     if (ncredef(cdfid) == -1) {
00149         error("%s: cdredef failed", pname);
00150         ncclose(cdfid); return ++nerrs;
00151     }
00152     /* in define mode OK, add a dimension */
00153     if ((nn_dim = ncdimdef(cdfid, nn.name, nn.size)) == -1) {
00154         error("%s: ncdimdef failed", pname);
00155         ncclose(cdfid); return ++nerrs;
00156     }
00157     add_dim(&test, &nn);        /* keep in-memory netcdf in sync */
00158     /* check id returned for name matches id returned from definition */
00159     if (ncdimid(cdfid, nn.name) != nn_dim) {
00160         error("%s: ncdimid returned wrong value in define mode", pname);
00161         ncclose(cdfid); return ++nerrs;
00162     }
00163     if (ncendef (cdfid) == -1) {
00164         error("%s: ncendef failed", pname);
00165         ncclose(cdfid); return ++nerrs;
00166     }
00167     /* in data mode, check returned id for dimension just added */
00168     if (ncdimid(cdfid, nn.name) != nn_dim) {
00169         error("%s: ncdimid returned wrong value in data mode", pname);
00170         ncclose(cdfid); return ++nerrs;
00171     }
00172     /* try with undefined dimension, should fail */
00173     if (ncdimid(cdfid, "easter-bunny") != -1) {
00174         error("%s: ncdimid with bogus name should have failed ", pname);
00175         ncclose(cdfid); return ++nerrs;
00176     }
00177     /* try with unlimited dimension, assumed to be "rec" from earlier calls */
00178     if (ncdimid(cdfid, "rec") != test.xdimid) {
00179         error("%s: ncdimid returned bad value for record dimension", pname);
00180         ncclose(cdfid); return ++nerrs;
00181     }
00182     if (ncclose (cdfid) == -1) {
00183         error("%s: ncclose failed", pname);
00184         return ++nerrs;
00185     }
00186     /* try on bad handle, should fail */
00187     if (ncdimid(cdfid, nn.name) != -1) {
00188         error("%s: ncdimid failed to report bad netcdf handle", pname);
00189         nerrs++;
00190     }
00191     if (nerrs > 0)
00192       (void) fprintf(stderr,"FAILED! ***\n");
00193     else
00194       (void) fprintf(stderr,"ok ***\n");
00195 
00196     return nerrs;
00197 }
00198 
00199 
00200 /*
00201  * Test ncdiminq
00202  *    try in both modes
00203  *    check returned name and size against defined name and size        
00204  *    try with bad dimension handle, check error
00205  *    try with bad netCDF handle, check error
00206  */
00207 int
00208 test_ncdiminq(path)
00209      const char *path;          /* name of writable netcdf file to open */
00210 {
00211     int nerrs = 0;
00212     static char pname[] = "test_ncdiminq";
00213     int cdfid;                  /* netcdf id */
00214     int dimid;                  /* dimension id */
00215     struct cdfdim dim;          /* dimension */
00216 
00217     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
00218 
00219     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
00220         error("%s: ncopen failed", pname);
00221         return ++nerrs;
00222     }
00223     /* opened, in data mode */
00224     dim.name = (char *) emalloc(MAX_NC_NAME);
00225     for (dimid = 0 ; dimid < test.ndims; dimid++) { /* loop on all dim ids */
00226         if (ncdiminq(cdfid, dimid, dim.name, &dim.size) == -1) {
00227             error("%s: ncdiminq in data mode failed on dim id %d",
00228                   pname, dimid);
00229             ncclose(cdfid); return ++nerrs;
00230         }
00231         /* compare returned with expected values */
00232         if (strcmp(dim.name, test.dims[dimid].name) != 0) {
00233             error("%s: ncdiminq (data mode), name %s, expected %s for id = %d",
00234                 pname, dim.name, test.dims[dimid].name, dimid);
00235             nerrs++;
00236         }
00237         if (dim.size != test.dims[dimid].size) {
00238             error("%s: ncdiminq (data mode), size %d, expected %d for id = %d",
00239                 pname, dim.size, test.dims[dimid].size, dimid);
00240             nerrs++;
00241         }
00242     }
00243     if (ncredef(cdfid) == -1) {
00244         error("%s: ncredef failed", pname);
00245         ncclose(cdfid); return ++nerrs;
00246     }
00247     /* in define mode, compare returned with expected values again */
00248     for (dimid = 0 ; dimid < test.ndims; dimid++) { /* loop on all dim ids */
00249         if (ncdiminq(cdfid, dimid, dim.name, &dim.size) == -1) {
00250             error("%s: ncdiminq in define mode failed on dim id %d",
00251                   pname, dimid);
00252             ncclose(cdfid); return ++nerrs;
00253         }
00254         /* compare returned with expected values */
00255         if (strcmp(dim.name, test.dims[dimid].name) != 0) {
00256             error("%s: ncdiminq (define), name %s, expected %s for id = %d",
00257                 pname, dim.name, test.dims[dimid].name, dimid);
00258             nerrs++;
00259         }
00260         if (dim.size != test.dims[dimid].size) {
00261             error("%s: ncdiminq (define), size %d, expected %d for id = %d",
00262                 pname, dim.size, test.dims[dimid].size, dimid);
00263             nerrs++;
00264         }
00265     }
00266     /* try with bad dimension handles, check for failure */
00267     if (ncdiminq(cdfid, -1, dim.name, &dim.size) != -1 ||
00268         ncdiminq(cdfid, test.ndims, dim.name, &dim.size) != -1) {
00269         error("%s: ncdiminq should have failed on bad dimension ids",
00270               pname, dimid);
00271         ncclose(cdfid); return ++nerrs;
00272     }
00273     if (ncendef (cdfid) == -1) {
00274         error("%s: ncendef failed", pname);
00275         ncclose(cdfid); return ++nerrs;
00276     }
00277     if (ncclose (cdfid) == -1) {
00278         error("%s: ncclose failed", pname);
00279         return ++nerrs;
00280     }
00281     /* should fail, since bad handle */
00282     if (test.ndims >= 1) {      /* if any dimensions have been defined */
00283         if (ncdiminq (cdfid, 0, dim.name, &dim.size) != -1) {
00284             error("%s: ncdiminq failed to report bad netcdf handle ", pname);
00285             nerrs++;
00286         }
00287     }
00288     free(dim.name);
00289     if (nerrs > 0)
00290       (void) fprintf(stderr,"FAILED! ***\n");
00291     else
00292       (void) fprintf(stderr,"ok ***\n");
00293 
00294     return nerrs;
00295 }    
00296     
00297 /*
00298  * Test ncdimrename
00299  *    check that proper rename worked with ncdiminq
00300  *    try renaming to existing dimension name, check error
00301  *    try with bad dimension handle, check error
00302  *    try with bad netCDF handle, check error
00303  */
00304 int
00305 test_ncdimrename(path)
00306      const char *path;          /* name of writable netcdf file to open */
00307 {
00308     int nerrs = 0;
00309     static char pname[] = "test_ncdimrename";
00310     int cdfid;                  /* netcdf id */
00311     int pp_dim;                 /* dimension id */
00312     static struct cdfdim pp =   /* dimension */
00313       {"pp", 7};
00314     static char newname[MAX_NC_NAME] = /* dimension name */
00315       "new_name";
00316     struct cdfdim dim;          /* dimension */
00317     static struct cdfdim qq =   /* dimension */
00318       {"qq", 10};
00319 
00320     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
00321 
00322     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
00323         error("%s: ncopen failed", pname);
00324         return ++nerrs;
00325     }
00326     /* opened */
00327     if (ncredef(cdfid) == -1) {
00328         error("%s: ncredef failed", pname);
00329         ncclose(cdfid); return ++nerrs;
00330     }
00331     /* in define mode, add two dimensions */
00332     if ((pp_dim = ncdimdef(cdfid, pp.name, pp.size)) == -1) {
00333         error("%s: ncdimdef failed", pname);
00334         ncclose(cdfid); return ++nerrs;
00335     }
00336     add_dim(&test, &pp);        /* keep in-memory netcdf in sync */
00337     if (ncdimdef(cdfid, qq.name, qq.size) == -1) {
00338         error("%s: ncdimdef failed", pname);
00339         ncclose(cdfid); return ++nerrs;
00340     }
00341     add_dim(&test, &qq);        /* keep in-memory netcdf in sync */
00342     /* rename first dimension */
00343     if (ncdimrename(cdfid, pp_dim, newname) == -1) {
00344         error("%s: ncdimrename failed", pname);
00345         ncclose(cdfid); return ++nerrs;
00346     }
00347     /* check new name with ncdiminq */
00348     dim.name = (char *) emalloc(MAX_NC_NAME);
00349     if (ncdiminq(cdfid, pp_dim, dim.name, &dim.size) == -1) {
00350         error("%s: ncdiminq failed", pname);
00351         ncclose(cdfid); return ++nerrs;
00352     }
00353     if (strcmp(dim.name,pp.name) == 0) {
00354         error("%s: ncdimrename failed to change name", pname);
00355         ncclose(cdfid); return ++nerrs;
00356     }
00357     if (strcmp(dim.name,newname) != 0) {
00358         error("%s: ncdimrename changed name to %s instead of %s",
00359               pname, dim.name, newname);
00360         ncclose(cdfid); return ++nerrs;
00361     }
00362     test.dims[pp_dim].name = (char *) erealloc((void *)test.dims[pp_dim].name,
00363                                               strlen(newname)+1);
00364     (void) strcpy(test.dims[pp_dim].name, newname); /* keep test consistent */
00365     /* try to rename second dimension same as first, should fail */
00366     if (ncdimrename(cdfid, pp_dim, qq.name) != -1) {
00367         error("%s: ncdimrename should have failed with used name", pname);
00368         ncclose(cdfid); return ++nerrs;
00369     }
00370     /* try with bad dimension handles, check for failure */
00371     if (ncdimrename(cdfid, -1, dim.name) != -1 ||
00372         ncdimrename(cdfid, test.ndims, dim.name) != -1) {
00373         error("%s: ncdimrename should have failed on bad dimension ids",
00374               pname);
00375         ncclose(cdfid); return ++nerrs;
00376     }
00377     if (ncendef (cdfid) == -1) {
00378         error("%s: ncendef failed", pname);
00379         ncclose(cdfid); return ++nerrs;
00380     }
00381 
00382     /* in data mode, rename to shorter name */
00383     if (ncdimrename(cdfid, pp_dim, "p") == -1) {
00384         error("%s: ncdimrename to shorter name failed in data mode", pname);
00385         ncclose(cdfid); return ++nerrs;
00386     }
00387     test.dims[pp_dim].name = (char *) erealloc((void *)test.dims[pp_dim].name,
00388                                               strlen("p")+1);
00389     (void) strcpy(test.dims[pp_dim].name, "p"); /* keep test consistent */
00390     /* Check with ncdimid */
00391     if (pp_dim != ncdimid(cdfid, "p")) {
00392         error("%s: lookup by name in data mode failed after ncdimrename",
00393               pname);   
00394     }
00395     /* in data mode, restore old name */
00396     if (ncdimrename(cdfid, pp_dim, pp.name) == -1) {
00397         error("%s: ncdimrename failed in data mode", pname);
00398         ncclose(cdfid); return ++nerrs;
00399     }
00400     test.dims[pp_dim].name = (char *) erealloc((void *)test.dims[pp_dim].name,
00401                                               strlen(pp.name)+1);
00402     (void) strcpy(test.dims[pp_dim].name, pp.name); /* keep test consistent */
00403     if (ncclose (cdfid) == -1) {
00404         error("%s: ncclose failed", pname);
00405         return ++nerrs;
00406     }
00407     /* should fail, since bad handle */
00408     if (ncdimrename (cdfid, 0, dim.name) != -1) {
00409         error("%s: ncdimrename failed to report bad netcdf handle ", pname);
00410         nerrs++;
00411     }
00412     free (dim.name);
00413     if (nerrs > 0)
00414       (void) fprintf(stderr,"FAILED! ***\n");
00415     else
00416       (void) fprintf(stderr,"ok ***\n");
00417 
00418     return nerrs;
00419 }

Generated on Thu Mar 16 18:10:14 2006 for nco by  doxygen 1.4.4