netcdf-c/nc_test/test_write.m4
2024-03-18 15:51:04 -05:00

2555 lines
87 KiB
Plaintext

dnl This is m4 source.
dnl Process using m4 to produce 'C' language file.
dnl
dnl This file is supposed to be the same as PnetCDF's test_write.m4
dnl
dnl If you see this line, you can ignore the next one.
/* Do not edit this file. It is produced from the corresponding .m4 source */
dnl
/*
* Copyright (C) 2003, Northwestern University and Argonne National Laboratory
* See COPYRIGHT notice in top-level directory.
*/
/* $Id: test_write.m4 2687 2016-12-08 18:32:13Z wkliao $ */
dnl
dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF
dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types
dnl (MPI_Offset vs. size_t), and function name substrings for external data
dnl types.
dnl
#if defined (_WIN32) || defined (_WIN64)
#include <io.h>
#endif
#include <sys/types.h> /* open() */
#include <sys/stat.h> /* open() */
#include <fcntl.h> /* open() */
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h> /* read() */
#endif
#include "tests.h"
#include "config.h"
#include "math.h"
define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl
define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl
define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl
define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_$1',`test_nc_$1')')dnl
define(`APIFunc', `ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl
define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, $3)', `file_open($1, $2, $3)')')dnl
define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, $3)', `file_create($1, $2, $3)')')dnl
define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl
define(`Def_Vars', `ifdef(`PNETCDF',`def_vars($1,$2)',`def_vars($1)')')dnl
define(`Put_Atts', `ifdef(`PNETCDF',`put_atts($1,$2,$3)',`put_atts($1)')')dnl
define(`Put_Vars', `ifdef(`PNETCDF',`put_vars($1,$2)',`put_vars($1)')')dnl
define(`Check_File',`ifdef(`PNETCDF',`check_file($1,$2,$3)',`check_file($1)')')dnl
define(`Check_Atts',`ifdef(`PNETCDF',`check_atts($1,$2,$3)',`check_atts($1)')')dnl
define(`Check_Vars',`ifdef(`PNETCDF',`check_vars($1,$2)',`check_vars($1)')')dnl
define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl
define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts, int numVars',`void')')dnl
define(`GetVar1TYPE',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl
define(`PutVar1TYPE',`ifdef(`PNETCDF',`ncmpi_put_var1_$1_all',`nc_put_var1_$1')')dnl
define(`PutVar1', `ifdef(`PNETCDF',`ncmpi_put_var1_all($1,$2,$3,$4,$5,$6)', `nc_put_var1($1,$2,$3,$4)')')dnl
define(`PutVar', `ifdef(`PNETCDF',`ncmpi_put_var_all( $1,$2,$3,$4,$5)', `nc_put_var( $1,$2,$3)')')dnl
define(`PutVara', `ifdef(`PNETCDF',`ncmpi_put_vara_all($1,$2,$3,$4,$5,$6,$7)', `nc_put_vara($1,$2,$3,$4,$5)')')dnl
define(`PutVars', `ifdef(`PNETCDF',`ncmpi_put_vars_all($1,$2,$3,$4,$5,$6,$7,$8)', `nc_put_vars($1,$2,$3,$4,$5,$6)')')dnl
define(`PutVarm', `ifdef(`PNETCDF',`ncmpi_put_varm_all($1,$2,$3,$4,$5,$6,$7,$8,$9)', `nc_put_varm($1,$2,$3,$4,$5,$6,$7)')')dnl
/*
* Test APIFunc(create)
* For mode in NC_NOCLOBBER, NC_CLOBBER do:
* create netcdf file 'scratch.nc' with no data, close it
* test that it can be opened, do APIFunc(inq) to check nvars = 0, etc.
* Try again in NC_NOCLOBBER mode, check error return
* On exit, delete this file
*/
int
TestFunc(create)(void)
{
int clobber; /* 0 for NC_NOCLOBBER, 1 for NC_CLOBBER */
int err;
int ncid;
int ndims; /* number of dimensions */
int nvars; /* number of variables */
int ngatts; /* number of global attributes */
int recdim; /* id of unlimited dimension */
int nok=0;
for (clobber = 0; clobber < 2; clobber++) {
err = FileCreate(scratch, clobber ? NC_CLOBBER : NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR)
error("create: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileOpen(scratch, NC_NOWRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, &recdim);
IF (err != NC_NOERR)
error("inq: %s", APIFunc(strerror)(err));
else IF (ndims != 0)
error("inq: wrong number of dimensions returned, %d", ndims);
else IF (nvars != 0)
error("inq: wrong number of variables returned, %d", nvars);
else IF (ngatts != 0)
error("inq: wrong number of global atts returned, %d", ngatts);
else IF (recdim != -1)
error("inq: wrong record dimension ID returned, %d", recdim);
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
}
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_EEXIST)
error("expecting NC_EEXIST but got %s", nc_err_code_name(err));
ELSE_NOK
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(redef)
* (In fact also tests APIFunc(enddef) - called from TestFunc(enddef))
* BAD_ID
* attempt redef (error) & enddef on read-only file
* create file, define dims & vars.
* attempt put var (error)
* attempt redef (error) & enddef.
* put vars
* attempt def new dims (error)
* redef
* def new dims, vars.
* put atts
* enddef
* put vars
* close
* check file: vars & atts
* check reopening with NC_WRITE and adding new dims, atts, vars
*/
int
TestFunc(redef)(AttVarArgs)
{
int ncid; /* netcdf id */
/* used to force effective test of ncio->move() in redef */
IntType sizehint = 8192;
int dimid; /* dimension id */
int varid; /* variable id */
int varid1; /* variable id */
int nok=0, err;
const char * title = "Not funny";
double var;
char name[NC_MAX_NAME];
IntType length;
int fmt_variant1, fmt_variant2;
/* BAD_ID tests */
err = APIFunc(redef)(BAD_ID);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(enddef)(BAD_ID);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* read-only tests */
err = FileOpen(testfile, NC_NOWRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(redef)(ncid);
IF (err != NC_EPERM)
error("expecting NC_EPERM but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(enddef)(ncid);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* tests using scratch file */
ifdef(`PNETCDF',`dnl
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);',`dnl
err = file__create(scratch, NC_NOCLOBBER, 0, &sizehint, &ncid);')
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
ifdef(`PNETCDF',,`dnl
/* limit for ncio implementations which have infinite chunksize */
if(sizehint > 32768) sizehint = 16384;')
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
err = APIFunc(inq_varid)(ncid, "d", &varid);
IF (err != NC_NOERR)
error("inq_varid: %s", APIFunc(strerror)(err));
var = 1.0;
ifdef(`PNETCDF', `
err = ncmpi_begin_indep_data(ncid);
IF (err != NC_EINDEFINE)
error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));')dnl
err = PutVar1TYPE(double)(ncid, varid, NULL, &var);
IF (err != NC_EINDEFINE)
error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));
ifdef(`PNETCDF', `
err = ncmpi_end_indep_data(ncid);
IF (err != NC_ENOTINDEP)
error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl
err = APIFunc(redef)(ncid);
IF (err != NC_EINDEFINE)
error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
ELSE_NOK
Put_Vars(ncid, numVars);
err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(set_fill)(ncid, NC_NOFILL, NULL);
IF (err != NC_NOERR)
error("set_fill: %s", APIFunc(strerror)(err));
err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid);
IF (err != NC_NOERR)
error("def_dim: %s", APIFunc(strerror)(err));
err = APIFunc(def_var)(ncid, "abcScalar", NC_INT, 0, NULL, &varid);
IF (err != NC_NOERR)
error("def_var: %s", APIFunc(strerror)(err));
err = APIFunc(def_var)(ncid, "abc", NC_INT, 1, &dimid, &varid1);
IF (err != NC_NOERR)
error("def_var: %s", APIFunc(strerror)(err));
{
int dimids[NDIMS +1];
int ii = 0;
for(ii = 0; ii < NDIMS; ii++) dimids[ii] = ii;
dimids[NDIMS] = dimid;
err = APIFunc(def_var)(ncid, "abcRec", NC_INT, NDIMS, dimids, &varid1);
IF (err != NC_NOERR)
error("def_var: %s", APIFunc(strerror)(err));
}
err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "title", 1+strlen(title), title);
IF (err != NC_NOERR)
error("put_att_text: %s", APIFunc(strerror)(err));
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
ELSE_NOK
var = 1.0;
ifdef(`PNETCDF', `
err = ncmpi_end_indep_data(ncid);
IF (err != NC_ENOTINDEP)
error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl
err = PutVar1TYPE(double)(ncid, varid, NULL, &var);
IF (err != NC_NOERR)
error("put_var1_double: %s", APIFunc(strerror)(err));
err = APIFunc(inq_format)(ncid, &fmt_variant1);
IF (err)
error("inq_format: %s", APIFunc(strerror)(err));
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* check scratch file written as expected */
Check_File(scratch, numGatts, numVars); /* checks all except "abc" stuff added above */
IF ((err = FileOpen(scratch, NC_NOWRITE, &ncid)))
error("open: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(inq_dim)(ncid, dimid, name, &length)))
error("inq_dim: %s", APIFunc(strerror)(err));
IF (strcmp(name, "abc") != 0)
error("Unexpected dim name");
IF (length != sizehint)
error("Unexpected dim length");
IF ((err = GetVar1TYPE(double)(ncid, varid, NULL, &var)))
error("get_var1_double: %s", APIFunc(strerror)(err));
IF (var != 1.0)
error("get_var1_double: unexpected value");
IF ((err = APIFunc(close)(ncid)))
error("close: %s", APIFunc(strerror)(err));
/* open scratch file for writing, add another dim, var, att, then check */
IF ((err = FileOpen(scratch, NC_WRITE, &ncid)))
error("open: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(redef)(ncid)))
error("redef: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(def_dim)(ncid, "def", sizehint, &dimid)))
error("def_dim: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(def_var)(ncid, "defScalar", NC_INT, 0, NULL, &varid)))
error("def_var: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(def_var)(ncid, "def", NC_INT, 1, &dimid, &varid1)))
error("def_var: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "Credits", 1+strlen("Thanks!"), "Thanks!")))
error("put_att_text: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(enddef)(ncid)))
error("enddef: %s", APIFunc(strerror)(err));
var = 2.0;
IF ((err = PutVar1TYPE(double)(ncid, varid, NULL, &var)))
error("put_var1_double: %s", APIFunc(strerror)(err));
IF ((err = APIFunc(close)(ncid)))
error("close: %s", APIFunc(strerror)(err));
/* check scratch file written as expected */
Check_File(scratch, numGatts, numVars);
err = FileOpen(scratch, NC_NOWRITE, &ncid);
IF (err)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(inq_dim)(ncid, dimid, name, &length);
IF (err)
error("inq_dim: %s", APIFunc(strerror)(err));
IF (strcmp(name, "def") != 0)
error("Unexpected dim name");
IF (length != sizehint)
error("Unexpected dim length");
err = GetVar1TYPE(double)(ncid, varid, NULL, &var);
IF (err)
error("get_var1_double: %s", APIFunc(strerror)(err));
IF (var != 2.0)
error("get_var1_double: unexpected value");
/* make sure format variant hasn't changed from when created */
err = APIFunc(inq_format)(ncid, &fmt_variant2);
IF (err)
error("inq_format: %s", APIFunc(strerror)(err));
IF (fmt_variant1 != fmt_variant2)
error("enddef changed format variant");
err = APIFunc(close)(ncid);
IF (err)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(enddef)
* Simply calls TestFunc(redef) which tests both APIFunc(redef) & APIFunc(enddef)
*/
int
TestFunc(enddef)(AttVarArgs)
{
ifdef(`PNETCDF',
`return test_ncmpi_redef(numGatts, numVars);',
`return test_nc_redef();')
}
/*
* Test APIFunc(sync)
* try with bad handle, check error
* try in define mode, check error
* try writing with one handle, reading with another on same netCDF
*/
int
TestFunc(sync)(AttVarArgs)
{
int ncidw; /* netcdf id for writing */
int ncidr; /* netcdf id for reading */
int nok=0, err;
/* BAD_ID test */
err = APIFunc(sync)(BAD_ID);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* create scratch file & try APIFunc(sync) in define mode */
err = FileCreate(scratch, NC_NOCLOBBER, &ncidw);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(sync)(ncidw);
IF (err != NC_EINDEFINE)
error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
/* write using same handle */
def_dims(ncidw);
Def_Vars(ncidw, numVars);
Put_Atts(ncidw, numGatts, numVars);
err = APIFunc(enddef)(ncidw);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
Put_Vars(ncidw, numVars);
err = APIFunc(sync)(ncidw);
IF (err != NC_NOERR)
error("sync of ncidw failed: %s", APIFunc(strerror)(err));
ELSE_NOK
/* open another handle, APIFunc(sync), read (check) */
err = FileOpen(scratch, NC_NOWRITE, &ncidr);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(sync)(ncidr);
IF (err != NC_NOERR)
error("sync of ncidr failed: %s", APIFunc(strerror)(err));
ELSE_NOK
check_dims(ncidr);
Check_Atts(ncidr, numGatts, numVars);
Check_Vars(ncidr, numVars);
/* close both handles */
err = APIFunc(close)(ncidr);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = APIFunc(close)(ncidw);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(abort)
* try with bad handle, check error
* try in define mode before anything written, check that file was deleted
* try after APIFunc(enddef), APIFunc(redef), define new dims, vars, atts
* try after writing variable
*/
int
TestFunc(abort)(AttVarArgs)
{
int ncid; /* netcdf id */
int err;
int ndims;
int nvars;
int ngatts;
int nok=0;
/* BAD_ID test */
err = APIFunc(abort)(BAD_ID);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* create scratch file & try APIFunc(abort) in define mode */
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
err = APIFunc(abort)(ncid);
IF (err != NC_NOERR)
error("abort of ncid failed: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(close)(ncid); /* should already be closed */
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
err = FileDelete(scratch, info); /* should already be deleted */
ifdef(`PNETCDF',
`IF (err != NC_ENOENT && err != NC_EFILE)
error("expecting NC_ENOENT or NC_EFILE but got %s", nc_err_code_name(err));',
`IF (err != ENOENT && err != NC_EIO)
error("expecting ENOENT or NC_EIO but got %s", nc_err_code_name(err));')dnl
/*
* create scratch file
* do APIFunc(enddef) & APIFunc(redef)
* define new dims, vars, atts
* try APIFunc(abort): should restore previous state (no dims, vars, atts)
*/
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
err = APIFunc(abort)(ncid);
IF (err != NC_NOERR)
error("abort of ncid failed: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(close)(ncid); /* should already be closed */
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
err = FileOpen(scratch, NC_NOWRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, NULL);
IF (err != NC_NOERR)
error("inq: %s", APIFunc(strerror)(err));
IF (ndims != 0)
error("ndims should be 0");
IF (nvars != 0)
error("nvars should be 0");
IF (ngatts != 0)
error("ngatts should be 0");
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* try APIFunc(abort) in data mode - should just close */
err = FileCreate(scratch, NC_CLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
Put_Vars(ncid, numVars);
err = APIFunc(abort)(ncid);
IF (err != NC_NOERR)
error("abort of ncid failed: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(close)(ncid); /* should already be closed */
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
Check_File(scratch, numGatts, numVars);
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(def_dim)
* try with bad netCDF handle, check error
* try in data mode, check error
* check that returned id is one more than previous id
* try adding same dimension twice, check error
* try with illegal sizes, check error
* make sure unlimited size works, shows up in APIFunc(inq_unlimdim)
* try to define a second unlimited dimension, check error
*/
int
TestFunc(def_dim)(VarArgs)
{
int ncid;
int err; /* status */
int i, nok=0;
int dimid; /* dimension id */
IntType length;
/* BAD_ID test */
err = APIFunc(def_dim)(BAD_ID, "abc", 8, &dimid);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* data mode test */
err = FileCreate(scratch, NC_CLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
err = APIFunc(def_dim)(ncid, "abc", 8, &dimid);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
/* define-mode tests: unlimited dim */
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
err = APIFunc(def_dim)(ncid, dim_name[0], NC_UNLIMITED, &dimid);
IF (err != NC_NOERR)
error("def_dim: %s", APIFunc(strerror)(err));
ELSE_NOK
IF (dimid != 0)
error("Unexpected dimid");
ELSE_NOK
err = APIFunc(inq_unlimdim)(ncid, &dimid);
IF (err != NC_NOERR)
error("inq_unlimdim: %s", APIFunc(strerror)(err));
IF (dimid != 0)
error("Unexpected recdim");
err = APIFunc(inq_dimlen)(ncid, dimid, &length);
IF (length != 0)
error("Unexpected length");
err = APIFunc(def_dim)(ncid, "abc", NC_UNLIMITED, &dimid);
IF (err != NC_EUNLIMIT)
error("expecting NC_EUNLIMIT but got %s", nc_err_code_name(err));
ELSE_NOK
/* define-mode tests: remaining dims */
for (i = 1; i < NDIMS; i++) {
err = APIFunc(def_dim)(ncid, dim_name[i-1], dim_len[i], &dimid);
IF (err != NC_ENAMEINUSE)
error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(def_dim)(ncid, BAD_NAME, dim_len[i], &dimid);
IF (err != NC_EBADNAME)
error("expecting NC_EBADNAME but got %s", nc_err_code_name(err));
ELSE_NOK
ifdef(`PNETCDF', ,`if(sizeof(long) > 4) /* Fix: dmh 11/4/2011: works only if sizeof(long) > 4 */')
{
err = APIFunc(def_dim)(ncid, dim_name[i], (IntType)(NC_UNLIMITED-1), &dimid);
IF (err != NC_EDIMSIZE)
error("expecting NC_EDIMSIZE but got %s", nc_err_code_name(err));
ELSE_NOK
}
err = APIFunc(def_dim)(ncid, dim_name[i], dim_len[i], &dimid);
IF (err != NC_NOERR)
error("def_dim: %s", APIFunc(strerror)(err));
ELSE_NOK
IF (dimid != i)
error("Unexpected dimid");
}
/* Following just to expand unlimited dim */
Def_Vars(ncid, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
Put_Vars(ncid, numVars);
/* Check all dims */
check_dims(ncid);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(rename_dim)
* try with bad netCDF handle, check error
* check that proper rename worked with APIFunc(inq_dim)
* try renaming to existing dimension name, check error
* try with bad dimension handle, check error
*/
int
TestFunc(rename_dim)(void)
{
int ncid;
int err, nok=0; /* status */
char name[NC_MAX_NAME];
/* BAD_ID test */
err = APIFunc(rename_dim)(BAD_ID, 0, "abc");
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* main tests */
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
err = APIFunc(rename_dim)(ncid, BAD_DIMID, "abc");
IF (err != NC_EBADDIM)
error("expecting NC_EBADDIM but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(rename_dim)(ncid, 2, "abc");
IF (err != NC_NOERR)
error("rename_dim: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_dimname)(ncid, 2, name);
IF (strcmp(name, "abc") != 0)
error("Unexpected name: %s", name);
err = APIFunc(rename_dim)(ncid, 0, "abc");
IF (err != NC_ENAMEINUSE)
error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(def_var)
* try with bad netCDF handle, check error
* try with bad name, check error
* scalar tests:
* check that proper define worked with APIFunc(inq_var)
* try redefining an existing variable, check error
* try with bad datatype, check error
* try with bad number of dimensions, check error
* try in data mode, check error
* check that returned id is one more than previous id
* try with bad dimension ids, check error
*/
int
TestFunc(def_var)(VarArgs)
{
int ncid;
int varid;
int err, nok=0; /* status */
int i;
int ndims;
int natts;
char name[NC_MAX_NAME];
int dimids[MAX_RANK];
nc_type datatype;
/* BAD_ID test */
err = APIFunc(def_var)(BAD_ID, "abc", NC_SHORT, 0, NULL, &varid);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
/* scalar tests */
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid);
IF (err != NC_NOERR)
error("def_var: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_var)(ncid, varid, name, &datatype, &ndims, dimids, &natts);
IF (err != NC_NOERR)
error("inq_var: %s", APIFunc(strerror)(err));
IF (strcmp(name, "abc") != 0)
error("Unexpected name: %s", name);
IF (datatype != NC_SHORT)
error("Unexpected datatype");
IF (ndims != 0)
error("Unexpected rank");
err = APIFunc(def_var)(ncid, BAD_NAME, NC_SHORT, 0, NULL, &varid);
IF (err != NC_EBADNAME)
error("expecting NC_EBADNAME but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid);
IF (err != NC_ENAMEINUSE)
error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(def_var)(ncid, "ABC", BAD_TYPE, -1, dimids, &varid);
IF (err != NC_EBADTYPE)
error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, -1, dimids, &varid);
IF (err != NC_EINVAL)
error("expecting NC_EINVAL but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, 0, dimids, &varid);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
/* general tests using global vars */
err = FileCreate(scratch, NC_CLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
for (i = 0; i < numVars; i++) {
err = APIFunc(def_var)(ncid, var_name[i], var_type[i], var_rank[i],
var_dimid[i], &varid);
IF (err != NC_NOERR)
error("def_var: %s", APIFunc(strerror)(err));
ELSE_NOK
IF (varid != i)
error("Unexpected varid");
ELSE_NOK
}
/* try bad dim ids */
dimids[0] = BAD_DIMID;
err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 1, dimids, &varid);
IF (err != NC_EBADDIM)
error("expecting NC_EBADDIM but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test PutVar1
*/
int
TestFunc(put_var1)(VarArgs)
{
int i, err, ncid, nok=0;
IntType j, index[MAX_RANK];
double value[1];
double buf[1]; /* (void *) buffer */
ifdef(`PNETCDF', `MPI_Datatype datatype;')
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
/* check if can detect a bad file ID */
err = PutVar1(BAD_ID, 0, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
/* check if can detect a bad variable ID */
err = PutVar1(ncid, BAD_VARID, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_ENOTVAR)
EXPECT_ERR(NC_ENOTVAR, err)
ELSE_NOK
for (i = 0; i < numVars; i++) {
assert(var_rank[i] <= MAX_RANK);
assert(var_nels[i] <= MAX_NELS);
value[0] = 5; /* reset to a value within bounds */
ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);')
ifdef(`PNETCDF',`dnl
/* for non-scalar variables, argument start cannot be NULL */
err = PutVar1(ncid, i, NULL, value, 1, datatype);
if (var_rank[i] == 0) { /* scalar variable */
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EINVALCOORDS) {
EXPECT_ERR(NC_EINVALCOORDS, err)
}
ELSE_NOK
')dnl
/* test NC_EINVALCOORDS */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) index[j] = 0;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
index[j] = var_shape[i][j]; /* out of boundary check */
err = PutVar1(ncid, i, index, value, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
index[j] = 0;
}
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err != 0) error("error in toMixedBase");
value[0] = hash(var_type[i], var_rank[i], index);
if (inRange(value[0], var_type[i])) {
err = dbl2nc(value[0], var_type[i], buf);
IF (err != NC_NOERR)
error("error in dbl2nc var:%s type:%s",
var_name[i],s_nc_type(var_type[i]));
err = PutVar1(ncid, i, index, buf, 1, datatype);
IF (err != NC_NOERR)
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
}
}
}
Check_Vars(ncid, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test PutVara
* Choose a random point dividing each dim into 2 parts
* Put 2^rank (nslabs) slabs so defined
* Redefine buffer for each put.
* At end check all variables using Check_Vars
*/
int
TestFunc(put_vara)(VarArgs)
{
int d, i, k, err, nslabs, ncid, nok=0;
IntType j, nels;
IntType start[MAX_RANK];
IntType edge[MAX_RANK];
IntType index[MAX_RANK];
IntType mid[MAX_RANK];
double buf[MAX_NELS]; /* (void *) buffer */
char *p; /* (void *) pointer */
double value = 0;
ifdef(`PNETCDF', `MPI_Datatype datatype;')
for(j = 0; j < MAX_RANK; j++ ) {
start[j] = 0;
edge[j] = 0;
index[j] = 0;
mid[j] = 0;
}
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
/* check if can detect a bad file ID */
err = PutVara(BAD_ID, 0, start, edge, buf, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
/* check if can detect a bad variable ID */
err = PutVara(ncid, BAD_VARID, start, edge, buf, 1, MPI_DATATYPE_NULL);
IF (err != NC_ENOTVAR)
EXPECT_ERR(NC_ENOTVAR, err)
ELSE_NOK
for (i = 0; i < numVars; i++) {
assert(var_rank[i] <= MAX_RANK);
assert(var_nels[i] <= MAX_NELS);
buf[0] = 5; /* reset to a value within bounds */
/* check if can detect a bad file ID */
err = PutVara(BAD_ID, i, start, edge, buf, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);')
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
start[j] = 0;
edge[j] = 1;
}
ifdef(`PNETCDF',`dnl
/* for non-scalar variables, argument start cannot be NULL */
err = PutVara(ncid, i, NULL, NULL, buf, 1, datatype);
if (var_rank[i] == 0) { /* scalar variable */
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EINVALCOORDS) {
EXPECT_ERR(NC_EINVALCOORDS, err)
}
ELSE_NOK
/* for non-scalar variables, argument count cannot be NULL */
err = PutVara(ncid, i, start, NULL, buf, 1, datatype);
if (var_rank[i] == 0) {
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EEDGE) {
EXPECT_ERR(NC_EEDGE, err)
}
ELSE_NOK
')dnl
/* first test when edge[*] > 0 */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVara(ncid, i, start, edge, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
edge[j] = var_shape[i][j] + 1;
err = PutVara(ncid, i, start, edge, buf, 1, datatype);
IF (err != NC_EEDGE)
EXPECT_ERR(NC_EEDG, err)
ELSE_NOK
edge[j] = 1;
}
/* Check correct error returned when nothing to put, when edge[*]==0 */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVara(ncid, i, start, edge, buf, 0, datatype);
IF (err != NC_NOERR) /* allowed when edge[j]==0 */
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
start[j] = var_shape[i][j]+1; /* out of boundary check */
err = PutVara(ncid, i, start, edge, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
}
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1;
/* Choose a random point dividing each dim into 2 parts */
/* put 2^rank (nslabs) slabs so defined */
nslabs = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
mid[j] = roll( var_shape[i][j] );
nslabs *= 2;
}
/* bits of k determine whether to put lower or upper part of dim */
for (k = 0; k < nslabs; k++) {
nels = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if ((k >> j) & 1) {
start[j] = 0;
edge[j] = mid[j];
}else{
start[j] = mid[j];
edge[j] = var_shape[i][j] - mid[j];
}
nels *= edge[j];
}
p = (char *) buf;
for (j = 0; j < nels; j++) {
err = toMixedBase(j, var_rank[i], edge, index);
IF (err != 0) error("error in toMixedBase");
for (d = 0; d < var_rank[i] && d < MAX_RANK; d++)
index[d] += start[d];
value = hash(var_type[i], var_rank[i], index);
if (!inRange(value, var_type[i]))
value = 0;
err = dbl2nc(value, var_type[i], p);
IF (err != NC_NOERR)
error("error in dbl2nc");
p += nctypelen(var_type[i]);
}
err = PutVara(ncid, i, start, edge, buf, nels, datatype);
IF (err != NC_NOERR)
error("%s", APIFunc(strerror)(err));
ELSE_NOK
}
}
Check_Vars(ncid, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test PutVars
* Choose a random point dividing each dim into 2 parts
* Put 2^rank (nslabs) slabs so defined
* Choose random stride from 1 to edge
* Redefine buffer for each put.
* At end check all variables using Check_Vars
*/
int
TestFunc(put_vars)(VarArgs)
{
int ncid, d, i, k, err, nslabs, nok=0;
PTRDType nstarts; /* number of different starts */
IntType j, m, nels;
IntType start[MAX_RANK];
IntType edge[MAX_RANK];
IntType index[MAX_RANK];
IntType index2[MAX_RANK];
IntType mid[MAX_RANK];
IntType count[MAX_RANK];
IntType sstride[MAX_RANK];
PTRDType stride[MAX_RANK];
double buf[MAX_NELS]; /* (void *) buffer */
char *p; /* (void *) pointer */
double value;
ifdef(`PNETCDF', `MPI_Datatype datatype;')
for(j = 0; j < MAX_RANK; j++ ) {
start[j] = 0;
edge[j] = 0;
index[j] = 0;
mid[j] = 0;
index2[j] = 0;
count[j] = 0;
sstride[j] = 1;
stride[j] = 1;
}
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
/* check if can detect a bad file ID */
err = PutVars(BAD_ID, 0, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
/* check if can detect a bad variable ID */
err = PutVars(ncid, BAD_VARID, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_ENOTVAR)
EXPECT_ERR(NC_ENOTVAR, err)
ELSE_NOK
for (i = 0; i < numVars; i++) {
assert(var_rank[i] <= MAX_RANK);
assert(var_nels[i] <= MAX_NELS);
buf[0] = 5; /* reset to a value within bounds */
/* check if can detect a bad file ID */
err = PutVars(BAD_ID, i, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);')
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
start[j] = 0;
edge[j] = 1;
stride[j] = 1;
}
ifdef(`PNETCDF',`dnl
/* for non-scalar variables, argument start cannot be NULL */
err = PutVars(ncid, i, NULL, NULL, NULL, buf, 1, datatype);
if (var_rank[i] == 0) { /* scalar variable */
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EINVALCOORDS) {
EXPECT_ERR(NC_EINVALCOORDS, err)
}
ELSE_NOK
/* for non-scalar variables, argument count cannot be NULL */
err = PutVars(ncid, i, start, NULL, NULL, buf, 1, datatype);
if (var_rank[i] == 0) {
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EEDGE) {
EXPECT_ERR(NC_EEDGE, err)
}
ELSE_NOK
')dnl
/* first test when edge[*] > 0 */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == 0) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
edge[j] = var_shape[i][j] + 1; /* edge error check */
err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype);
IF (err != NC_EEDGE)
EXPECT_ERR(NC_EEDG, err)
ELSE_NOK
edge[j] = 1;
stride[j] = 0; /* strided edge error check */
err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype);
IF (err != NC_ESTRIDE)
EXPECT_ERR(NC_ESTRIDE, err)
ELSE_NOK
stride[j] = 1;
}
/* Check correct error returned even when nothing to put */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == 0) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVars(ncid, i, start, edge, stride, buf, 0, datatype);
IF (err != NC_NOERR) /* allowed when edge[j]==0 */
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
start[j] = var_shape[i][j]+1; /* out of boundary check */
err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
}
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1;
/* Choose a random point dividing each dim into 2 parts */
/* put 2^rank (nslabs) slabs so defined */
nslabs = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
mid[j] = roll( var_shape[i][j] );
nslabs *= 2;
}
/* bits of k determine whether to put lower or upper part of dim */
/* choose random stride from 1 to edge */
for (k = 0; k < nslabs; k++) {
nstarts = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if ((k >> j) & 1) {
start[j] = 0;
edge[j] = mid[j];
}else{
start[j] = mid[j];
edge[j] = var_shape[i][j] - mid[j];
}
sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
stride[j] = (PTRDType)sstride[j];
nstarts *= stride[j];
}
for (m = 0; m < nstarts; m++) {
err = toMixedBase(m, var_rank[i], sstride, index);
IF (err != 0) error("error in toMixedBase");
nels = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]);
nels *= count[j];
index[j] += start[j];
}
/* Random choice of forward or backward */
/* TODO
if ( roll(2) ) {
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
index[j] += (count[j] - 1) * (IntType)stride[j];
stride[j] = -stride[j];
}
}
*/
p = (char *) buf;
for (j = 0; j < nels; j++) {
err = toMixedBase(j, var_rank[i], count, index2);
IF (err != 0) error("error in toMixedBase");
for (d = 0; d < var_rank[i] && d < MAX_RANK; d++)
index2[d] = index[d] + index2[d] * (IntType)stride[d];
value = hash(var_type[i], var_rank[i], index2);
if (!inRange(value, var_type[i]))
value = 0;
err = dbl2nc(value, var_type[i], p);
IF (err != NC_NOERR)
error("error in dbl2nc");
p += nctypelen(var_type[i]);
}
err = PutVars(ncid, i, index, count, stride, buf, nels, datatype);
IF (err != NC_NOERR)
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
}
}
}
Check_Vars(ncid, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test PutVarm
* Choose a random point dividing each dim into 2 parts
* Put 2^rank (nslabs) slabs so defined
* Choose random stride from 1 to edge
* Buffer is bit image of whole external variable.
* So all puts for a variable put different elements of buffer
* At end check all variables using Check_Vars
*/
int
TestFunc(put_varm)(VarArgs)
{
int ncid, nok=0;
int i;
int k;
int err;
int nslabs;
IntType j, m;
PTRDType nstarts; /* number of different starts */
IntType start[MAX_RANK];
IntType edge[MAX_RANK];
IntType index[MAX_RANK];
IntType mid[MAX_RANK];
IntType count[MAX_RANK];
IntType sstride[MAX_RANK];
PTRDType stride[MAX_RANK];
PTRDType imap[MAX_RANK];
PTRDType imap2[MAX_RANK];
ifdef(`PNETCDF', `IntType bufcount;')
double buf[MAX_NELS]; /* (void *) buffer */
char *p; /* (void *) pointer */
double value;
ifdef(`PNETCDF', `MPI_Datatype datatype;')
for(j = 0; j < MAX_RANK; j++ ) {
start[j] = 0;
edge[j] = 0;
index[j] = 0;
mid[j] = 0;
count[j] = 0;
sstride[j] = 1;
stride[j] = 1;
imap[j] = 0;
imap2[j] = 0;
}
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
/* check if can detect a bad file ID */
err = PutVarm(NC_EBADID, 0, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
/* check if can detect a bad variable ID */
err = PutVarm(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL);
IF (err != NC_ENOTVAR)
EXPECT_ERR(NC_ENOTVAR, err)
ELSE_NOK
for (i = 0; i < numVars; i++) {
assert(var_rank[i] <= MAX_RANK);
assert(var_nels[i] <= MAX_NELS);
buf[0] = 5; /* reset to a value within bounds */
/* check if can detect a bad file ID */
err = PutVarm(BAD_ID, i, NULL, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL);
IF (err != NC_EBADID)
EXPECT_ERR(NC_EBADID, err)
ELSE_NOK
ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);')
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
start[j] = 0;
edge[j] = 1;
stride[j] = 1;
imap[j] = 1;
mid[j] = 1;
}
ifdef(`PNETCDF',`dnl
/* for non-scalar variables, argument start cannot be NULL */
err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype);
if (var_rank[i] == 0) { /* scalar variable */
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EINVALCOORDS) {
EXPECT_ERR(NC_EINVALCOORDS, err)
}
ELSE_NOK
/* for non-scalar variables, argument count cannot be NULL */
err = PutVarm(ncid, i, start, NULL, NULL, NULL, buf, 1, datatype);
if (var_rank[i] == 0) {
IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
}
else IF (err != NC_EEDGE) {
EXPECT_ERR(NC_EEDGE, err)
}
ELSE_NOK
')dnl
/* first test when edge[*] > 0 */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == 0) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
edge[j] = var_shape[i][j] + 1; /* edge error check */
err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
IF (err != NC_EEDGE)
EXPECT_ERR(NC_EEDG, err)
ELSE_NOK
edge[j] = 1;
stride[j] = 0; /* strided edge error check */
err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
IF (err != NC_ESTRIDE)
EXPECT_ERR(NC_ESTRIDE, err)
ELSE_NOK
stride[j] = 1;
}
/* Check correct error returned even when nothing to put */
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if (var_dimid[i][j] == 0) continue; /* skip record dim */
start[j] = var_shape[i][j];
err = PutVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype);
IF (err != NC_NOERR) /* allowed when edge[j]==0 */
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
start[j] = var_shape[i][j]+1; /* out of boundary check */
err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
IF (err != NC_EINVALCOORDS)
EXPECT_ERR(NC_EINVALCOORDS, err)
ELSE_NOK
start[j] = 0;
}
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1;
if (var_rank[i] > 0) {
int jj = var_rank[i] - 1;
imap[jj] = nctypelen(var_type[i]); /* netCDF considers imap in bytes */
imap[jj] = 1; /* PnetCDF considers imap in elements */
for (; jj > 0; jj--)
imap[jj-1] = imap[jj] * (PTRDType)var_shape[i][jj];
}
p = (char *) buf;
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err != 0) error("error in toMixedBase");
value = hash(var_type[i], var_rank[i], index);
if (!inRange(value, var_type[i]))
value = 0;
err = dbl2nc(value, var_type[i], p);
IF (err != NC_NOERR)
error("error in dbl2nc");
p += nctypelen(var_type[i]);
}
/* Choose a random point dividing each dim into 2 parts */
/* put 2^rank (nslabs) slabs so defined */
nslabs = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
mid[j] = roll( var_shape[i][j] );
nslabs *= 2;
}
/* bits of k determine whether to put lower or upper part of dim */
/* choose random stride from 1 to edge */
for (k = 0; k < nslabs; k++) {
nstarts = 1;
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
if ((k >> j) & 1) {
start[j] = 0;
edge[j] = mid[j];
}else{
start[j] = mid[j];
edge[j] = var_shape[i][j] - mid[j];
}
sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
stride[j] = (PTRDType)sstride[j];
imap2[j] = imap[j] * (PTRDType)sstride[j];
nstarts *= stride[j];
}
for (m = 0; m < nstarts; m++) {
if (var_rank[i] == 0 && i%2 == 0) {
err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype);
} else {
err = toMixedBase(m, var_rank[i], sstride, index);
IF (err != 0) error("error in toMixedBase");
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]);
index[j] += start[j];
}
/* Random choice of forward or backward */
/* TODO
if ( roll(2) ) {
for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) {
index[j] += (count[j] - 1) * (IntType)stride[j];
stride[j] = -stride[j];
}
}
*/
j = fromMixedBase(var_rank[i], index, var_shape[i]);
p = (char *) buf + (int)j * nctypelen(var_type[i]);
ifdef(`PNETCDF', `for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= count[j];')
err = PutVarm(ncid, i, index, count, stride, imap2, p, bufcount, datatype);
}
IF (err != NC_NOERR)
EXPECT_ERR(NC_NOERR, err)
ELSE_NOK
}
}
}
Check_Vars(ncid, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(rename_var)
* try with bad netCDF handle, check error
* try with bad variable handle, check error
* try renaming to existing variable name, check error
* check that proper rename worked with APIFunc(inq_varid)
* try in data mode, check error
*/
int
TestFunc(rename_var)(VarArgs)
{
int ncid;
int varid;
int err, nok=0;
int i;
char name[NC_MAX_NAME];
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(rename_var)(ncid, BAD_VARID, "newName");
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
def_dims(ncid);
Def_Vars(ncid, numVars);
/* Prefix "new_" to each name */
for (i = 0; i < numVars; i++) {
err = APIFunc(rename_var)(BAD_ID, i, "newName");
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(rename_var)(ncid, i, var_name[numVars-1]);
IF (err != NC_ENAMEINUSE)
error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err));
ELSE_NOK
strcpy(name, "new_");
strcat(name, var_name[i]);
err = APIFunc(rename_var)(ncid, i, name);
IF (err != NC_NOERR)
error("rename_var: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_varid)(ncid, name, &varid);
IF (err != NC_NOERR)
error("inq_varid: %s", APIFunc(strerror)(err));
IF (varid != i)
error("Unexpected varid");
}
/* Change to data mode */
/* Try making names even longer. Then restore original names */
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
for (i = 0; i < numVars; i++) {
strcpy(name, "even_longer_");
strcat(name, var_name[i]);
err = APIFunc(rename_var)(ncid, i, name);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(rename_var)(ncid, i, var_name[i]);
IF (err != NC_NOERR)
error("rename_var: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_varid)(ncid, var_name[i], &varid);
IF (err != NC_NOERR)
error("inq_varid: %s", APIFunc(strerror)(err));
IF (varid != i)
error("Unexpected varid");
}
Put_Vars(ncid, numVars);
Check_Vars(ncid, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
int
TestFunc(put_att)(AttVarArgs)
{
int ncid, nok=0;
int varid;
int i;
int j;
IntType k, ndx[1];
int err;
double buf[MAX_NELS]; /* (void *) buffer */
char *p; /* (void *) pointer */
char *name; /* of att */
nc_type datatype; /* of att */
IntType length; /* of att */
double value;
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
for (i = -1; i < numVars; i++) {
varid = VARID(i);
for (j = 0; j < NATTS(i); j++) {
name = ATT_NAME(i,j);
datatype = ATT_TYPE(i,j);
length = ATT_LEN(i,j);
err = APIFunc(put_att)(BAD_ID, varid, name, datatype, length, buf);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(put_att)(ncid, varid, BAD_NAME, datatype, length, buf);
IF (err != NC_EBADNAME)
error("expecting NC_EBADNAME but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(put_att)(ncid, BAD_VARID, name, datatype, length, buf);
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(put_att)(ncid, varid, name, BAD_TYPE, length, buf);
IF (err != NC_EBADTYPE)
error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err));
ELSE_NOK
p = (char *) buf;
for (k=0; k<length; k++) {
ndx[0] = k;
value = hash(datatype, -1, ndx);
if (!inRange(value, datatype))
value = 0;
err = dbl2nc(value, datatype, p);
IF (err != NC_NOERR)
error("error in dbl2nc");
p += nctypelen(datatype);
}
err = APIFunc(put_att)(ncid, varid, name, datatype, length, buf);
IF (err != NC_NOERR)
error("%s", APIFunc(strerror)(err));
ELSE_NOK
}
}
Check_Atts(ncid, numGatts, numVars);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(copy_att)
* try with bad source or target netCDF handles, check error
* try with bad source or target variable handle, check error
* try with nonexisting attribute, check error
* check that NC_GLOBAL variable for source or target works
* check that new attribute put works with target in define mode
* check that old attribute put works with target in data mode
* check that changing type and length of an attribute work OK
* try with same ncid for source and target, different variables
* try with same ncid for source and target, same variable
*/
int
TestFunc(copy_att)(AttVarArgs)
{
int ncid_in;
int ncid_out;
int varid;
int err, nok=0;
int i;
int j=0;
char *name; /* of att */
nc_type datatype; /* of att */
IntType length; /* of att */
char value;
err = FileOpen(testfile, NC_NOWRITE, &ncid_in);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = FileCreate(scratch, NC_NOCLOBBER, &ncid_out);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid_out);
Def_Vars(ncid_out, numVars);
for (i = -1; i < numVars; i++) {
varid = VARID(i);
for (j = 0; j < NATTS(i); j++) {
name = ATT_NAME(i,j);
err = APIFunc(copy_att)(ncid_in, BAD_VARID, name, ncid_out, varid);
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, BAD_VARID);
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(copy_att)(BAD_ID, varid, name, ncid_out, varid);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(copy_att)(ncid_in, varid, name, BAD_ID, varid);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(copy_att)(ncid_in, varid, "noSuch", ncid_out, varid);
IF (err != NC_ENOTATT)
error("expecting NC_ENOTATT but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, varid);
IF (err != NC_NOERR)
error("copy_att: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(copy_att)(ncid_out, varid, name, ncid_out, varid);
IF (err != NC_NOERR)
error("source = target: %s", APIFunc(strerror)(err));
ELSE_NOK
}
}
err = APIFunc(close)(ncid_in);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* Close scratch. Reopen & check attributes */
err = APIFunc(close)(ncid_out);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileOpen(scratch, NC_WRITE, &ncid_out);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
Check_Atts(ncid_out, numGatts, numVars);
/*
* change to define mode
* define single char. global att. ':a' with value 'A'
* This will be used as source for following copies
*/
err = APIFunc(redef)(ncid_out);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
err = APIFunc(put_att_text)(ncid_out, NC_GLOBAL, "a", 1, "A");
IF (err != NC_NOERR)
error("put_att_text: %s", APIFunc(strerror)(err));
/*
* change to data mode
* Use scratch as both source & dest.
* try copy to existing att. change type & decrease length
* rename 1st existing att of each var (if any) 'a'
* if this att. exists them copy ':a' to it
*/
err = APIFunc(enddef)(ncid_out);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
for (i = 0; i < numVars; i++) {
if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) {
err = APIFunc(rename_att)(ncid_out, i, att_name[i][0], "a");
IF (err != NC_NOERR)
error("rename_att: %s", APIFunc(strerror)(err));
err = APIFunc(copy_att)(ncid_out, NC_GLOBAL, "a", ncid_out, i);
IF (err != NC_NOERR)
error("copy_att: %s", APIFunc(strerror)(err));
ELSE_NOK
}
}
err = APIFunc(close)(ncid_out);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* Reopen & check */
err = FileOpen(scratch, NC_WRITE, &ncid_out);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
for (i = 0; i < numVars; i++) {
if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) {
err = APIFunc(inq_att)(ncid_out, i, "a", &datatype, &length);
IF (err != NC_NOERR)
error("inq_att: %s", APIFunc(strerror)(err));
IF (datatype != NC_CHAR)
error("Unexpected type");
IF (length != 1)
error("Unexpected length");
err = APIFunc(get_att_text)(ncid_out, i, "a", &value);
IF (err != NC_NOERR)
error("get_att_text: %s", APIFunc(strerror)(err));
IF (value != 'A')
error("Unexpected value");
}
}
err = APIFunc(close)(ncid_out);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(rename_att)
* try with bad netCDF handle, check error
* try with bad variable handle, check error
* try with nonexisting att name, check error
* try renaming to existing att name, check error
* check that proper rename worked with APIFunc(inq_attid)
* try in data mode, check error
*/
int
TestFunc(rename_att)(AttVarArgs)
{
int ncid;
int varid;
int err;
int i;
int j;
IntType k, ndx[1];
int attnum;
char *attname;
char name[NC_MAX_NAME];
char oldname[NC_MAX_NAME];
char newname[NC_MAX_NAME];
int nok = 0; /* count of valid comparisons */
nc_type datatype;
nc_type atttype;
IntType length;
IntType attlength;
char text[MAX_NELS];
double value[MAX_NELS];
double expect;
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(rename_att)(ncid, BAD_VARID, "abc", "newName");
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
for (i = -1; i < numVars; i++) {
varid = VARID(i);
for (j = 0; j < NATTS(i); j++) {
attname = ATT_NAME(i,j);
err = APIFunc(rename_att)(BAD_ID, varid, attname, "newName");
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(rename_att)(ncid, varid, "noSuch", "newName");
IF (err != NC_ENOTATT)
error("expecting NC_ENOTATT but got %s", nc_err_code_name(err));
ELSE_NOK
strcpy(newname, "new_");
strcat(newname, attname);
err = APIFunc(rename_att)(ncid, varid, attname, newname);
IF (err != NC_NOERR)
error("rename_att: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_attid)(ncid, varid, newname, &attnum);
IF (err != NC_NOERR)
error("inq_attid: %s", APIFunc(strerror)(err));
IF (attnum != j)
error("Unexpected attnum");
}
}
/* Close. Reopen & check */
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileOpen(scratch, NC_WRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
for (i = -1; i < numVars; i++) {
varid = VARID(i);
for (j = 0; j < NATTS(i); j++) {
attname = ATT_NAME(i,j);
atttype = ATT_TYPE(i,j);
attlength = ATT_LEN(i,j);
strcpy(newname, "new_");
strcat(newname, attname);
err = APIFunc(inq_attname)(ncid, varid, j, name);
IF (err != NC_NOERR)
error("inq_attname: %s", APIFunc(strerror)(err));
IF (strcmp(name, newname) != 0)
error("inq_attname: unexpected name");
err = APIFunc(inq_att)(ncid, varid, name, &datatype, &length);
IF (err != NC_NOERR)
error("inq_att: %s", APIFunc(strerror)(err));
IF (datatype != atttype)
error("inq_att: unexpected type");
IF (length != attlength)
error("inq_att: unexpected length");
if (datatype == NC_CHAR) {
err = APIFunc(get_att_text)(ncid, varid, name, text);
IF (err != NC_NOERR)
error("get_att_text: %s", APIFunc(strerror)(err));
for (k = 0; k < attlength; k++) {
ndx[0] = k;
expect = hash(datatype, -1, ndx);
IF (text[k] != (char)expect)
error("get_att_text: unexpected value");
}
} else {
err = APIFunc(get_att_double)(ncid, varid, name, value);
IF (err != NC_NOERR)
error("get_att_double: %s", APIFunc(strerror)(err));
for (k = 0; k < attlength; k++) {
ndx[0] = k;
expect = hash(datatype, -1, ndx);
if (inRange(expect, datatype)) {
IF (!equal(value[k],expect,datatype,NCT_DOUBLE))
error("get_att_double: unexpected value");
}
}
}
}
}
/* Now in data mode */
/* Try making names even longer. Then restore original names */
for (i = -1; i < numVars; i++) {
varid = VARID(i);
for (j = 0; j < NATTS(i); j++) {
attname = ATT_NAME(i,j);
strcpy(oldname, "new_");
strcat(oldname, attname);
strcpy(newname, "even_longer_");
strcat(newname, attname);
err = APIFunc(rename_att)(ncid, varid, oldname, newname);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(rename_att)(ncid, varid, oldname, attname);
IF (err != NC_NOERR)
error("rename_att: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_attid)(ncid, varid, attname, &attnum);
IF (err != NC_NOERR)
error("inq_attid: %s", APIFunc(strerror)(err));
IF (attnum != j)
error("Unexpected attnum");
}
}
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(del_att)
* try with bad netCDF handle, check error
* try with bad variable handle, check error
* try with nonexisting att name, check error
* check that proper delete worked using:
* APIFunc(inq_attid), APIFunc(inq_natts), APIFunc(inq_varnatts)
*/
int
TestFunc(del_att)(AttVarArgs)
{
int ncid;
int err, nok=0;
int i;
int j;
int attnum;
int natts;
int numatts;
int varid;
char *name; /* of att */
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
err = APIFunc(del_att)(ncid, BAD_VARID, "abc");
IF (err != NC_ENOTVAR)
error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err));
ELSE_NOK
def_dims(ncid);
Def_Vars(ncid, numVars);
Put_Atts(ncid, numGatts, numVars);
for (i = -1; i < numVars; i++) {
varid = VARID(i);
numatts = NATTS(i);
for (j = 0; j < numatts; j++) {
name = ATT_NAME(i,j);
err = APIFunc(del_att)(BAD_ID, varid, name);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(del_att)(ncid, varid, "noSuch");
IF (err != NC_ENOTATT)
error("expecting NC_ENOTATT but got %s", nc_err_code_name(err));
ELSE_NOK
err = APIFunc(del_att)(ncid, varid, name);
IF (err != NC_NOERR)
error("del_att: %s", APIFunc(strerror)(err));
ELSE_NOK
err = APIFunc(inq_attid)(ncid, varid, name, &attnum);
IF (err != NC_ENOTATT)
error("expecting NC_ENOTATT but got %s", nc_err_code_name(err));
if (i < 0) {
err = APIFunc(inq_natts)(ncid, &natts);
IF (err != NC_NOERR)
error("inq_natts: %s", APIFunc(strerror)(err));
IF (natts != numatts-j-1)
error("natts: expected %d, got %d", numatts-j-1, natts);
}
err = APIFunc(inq_varnatts)(ncid, varid, &natts);
IF (err != NC_NOERR)
error("inq_natts: %s", APIFunc(strerror)(err));
IF (natts != numatts-j-1)
error("natts: expected %d, got %d", numatts-j-1, natts);
}
}
/* Close. Reopen & check no attributes left */
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileOpen(scratch, NC_WRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(inq_natts)(ncid, &natts);
IF (err != NC_NOERR)
error("inq_natts: %s", APIFunc(strerror)(err));
IF (natts != 0)
error("natts: expected %d, got %d", 0, natts);
for (i = -1; i < numVars; i++) {
varid = VARID(i);
err = APIFunc(inq_varnatts)(ncid, varid, &natts);
IF (err != NC_NOERR)
error("inq_natts: %s", APIFunc(strerror)(err));
IF (natts != 0)
error("natts: expected %d, got %d", 0, natts);
}
/* restore attributes. change to data mode. try to delete */
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
Put_Atts(ncid, numGatts, numVars);
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
for (i = -1; i < numVars; i++) {
varid = VARID(i);
numatts = NATTS(i);
for (j = 0; j < numatts; j++) {
name = ATT_NAME(i,j);
err = APIFunc(del_att)(ncid, varid, name);
IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));
ELSE_NOK
}
}
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test APIFunc(set_fill)
* try with bad netCDF handle, check error
* try in read-only mode, check error
* try with bad new_fillmode, check error
* try in data mode, check error
* check that proper set to NC_FILL works for record & non-record variables
* (note that it is not possible to test NC_NOFILL mode!)
* close file & create again for test using attribute _FillValue
*/
int
TestFunc(set_fill)(VarArgs)
{
int ncid;
int varid;
int err;
int i;
IntType j;
int old_fillmode;
int nok = 0; /* count of valid comparisons */
char text = 0;
double value = 0;
double fill;
IntType index[MAX_RANK];
/* bad ncid */
err = APIFunc(set_fill)(BAD_ID, NC_NOFILL, &old_fillmode);
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
/* try in read-only mode */
err = FileOpen(testfile, NC_NOWRITE, &ncid);
IF (err != NC_NOERR)
error("open: %s", APIFunc(strerror)(err));
err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode);
IF (err != NC_EPERM)
error("expecting NC_EPERM but got %s", nc_err_code_name(err));
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
/* create scratch */
err = FileCreate(scratch, NC_NOCLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
/* BAD_FILLMODE */
err = APIFunc(set_fill)(ncid, BAD_FILLMODE, &old_fillmode);
IF (err != NC_EINVAL)
error("expecting NC_EINVAL but got %s", nc_err_code_name(err));
/* proper calls */
err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode);
IF (err != NC_NOERR)
error("set_fill: %s", APIFunc(strerror)(err));
IF (old_fillmode != NC_NOFILL)
error("Unexpected old fill mode: %d", old_fillmode);
err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode);
IF (err != NC_NOERR)
error("set_fill: %s", APIFunc(strerror)(err));
IF (old_fillmode != NC_NOFILL)
error("Unexpected old fill mode: %d", old_fillmode);
/* define dims & vars */
def_dims(ncid);
Def_Vars(ncid, numVars);
/* Change to data mode. Set fillmode again */
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode);
ifdef(`PNETCDF',
`IF (err != NC_ENOTINDEFINE)
error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));',
`IF (err)
error("nc_set_fill: %s", nc_strerror(err));
IF (old_fillmode != NC_FILL)
error("Unexpected old fill mode: %d", old_fillmode);')dnl
/* Write record number NRECS to force writing of preceding records */
/* Assumes variable cr is char vector with UNLIMITED dimension */
err = APIFunc(inq_varid)(ncid, "cr", &varid);
IF (err != NC_NOERR)
error("inq_varid: %s", APIFunc(strerror)(err));
index[0] = NRECS;
ifdef(`PNETCDF', `
for (i=0; i<=index[0]; i++)
err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl
err = PutVar1TYPE(text)(ncid, varid, index, &text);
IF (err != NC_NOERR)
error("put_var1_text_all: %s", APIFunc(strerror)(err));
/* get all variables & check all values equal default fill */
for (i = 0; i < numVars; i++) {
ifdef(`PNETCDF', `if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */')
switch (var_type[i]) {
case NC_CHAR: fill = (double)NC_FILL_CHAR; break;
case NC_BYTE: fill = (double)NC_FILL_BYTE; break;
case NC_SHORT: fill = (double)NC_FILL_SHORT; break;
case NC_INT: fill = (double)NC_FILL_INT; break;
case NC_FLOAT: fill = (double)NC_FILL_FLOAT; break;
case NC_DOUBLE: fill = (double)NC_FILL_DOUBLE; break;
case NC_UBYTE: fill = (double)NC_FILL_UBYTE; break;
case NC_USHORT: fill = (double)NC_FILL_USHORT; break;
case NC_UINT: fill = (double)NC_FILL_UINT; break;
case NC_INT64: fill = (double)NC_FILL_INT64; break;
case NC_UINT64: fill = (double)NC_FILL_UINT64; break;
default: assert(0);
}
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err != 0) error("error in toMixedBase");
if (var_type[i] == NC_CHAR) {
err = GetVar1TYPE(text)(ncid, i, index, &text);
IF (err != NC_NOERR)
error("get_var1_text_all failed: %s", APIFunc(strerror)(err));
value = text;
} else {
err = GetVar1TYPE(double)(ncid, i, index, &value);
IF (err != NC_NOERR)
error("get_var1_double_all failed: %s", APIFunc(strerror)(err));
}
IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON)
error("\n\t\t%s Value expected: %-23.17e,\n\t\t read: %-23.17e\n",
var_name[i],fill, value);
ELSE_NOK
}
}
/* close scratch & create again for test using attribute _FillValue */
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileCreate(scratch, NC_CLOBBER, &ncid);
IF (err != NC_NOERR) {
error("create: %s", APIFunc(strerror)(err));
return nok;
}
def_dims(ncid);
Def_Vars(ncid, numVars);
/* set _FillValue = 42 for all vars */
fill = 42;
text = 42;
for (i = 0; i < numVars; i++) {
if (var_type[i] == NC_CHAR) {
err = APIFunc(put_att_text)(ncid, i, "_FillValue", 1, &text);
IF (err != NC_NOERR)
error("put_att_text: %s", APIFunc(strerror)(err));
} else {
err = APIFunc(put_att_double)(ncid, i, "_FillValue",var_type[i],1,&fill);
IF (err != NC_NOERR)
error("put_att_double: %s", APIFunc(strerror)(err));
}
}
/* data mode. write records */
err = APIFunc(enddef)(ncid);
IF (err != NC_NOERR)
error("enddef: %s", APIFunc(strerror)(err));
index[0] = NRECS;
ifdef(`PNETCDF', `
for (i=0; i<=index[0]; i++)
err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl
err = PutVar1TYPE(text)(ncid, varid, index, &text);
IF (err != NC_NOERR)
error("put_var1_text_all: %s", APIFunc(strerror)(err));
/* get all variables & check all values equal 42 */
for (i = 0; i < numVars; i++) {
if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err != 0) error("error in toMixedBase");
if (var_type[i] == NC_CHAR) {
err = GetVar1TYPE(text)(ncid, i, index, &text);
IF (err != NC_NOERR)
error("get_var1_text_all failed: %s", APIFunc(strerror)(err));
value = text;
} else {
err = GetVar1TYPE(double)(ncid, i, index, &value);
IF (err != NC_NOERR)
error("get_var1_double_all failed: %s", APIFunc(strerror)(err));
}
IF (value != fill)
error(" %s Value expected: %g, read: %g\n", var_name[i],fill, value);
ELSE_NOK
}
}
/* enter redef mode and add a new variable, check NC_ELATEFILL */
err = APIFunc(redef)(ncid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
/* it is not allowed to define fill value when variable already exists */
err = APIFunc(def_var_fill)(ncid, 0, 0, &value);
IF (err != NC_ELATEFILL)
error("redef: expect NC_ELATEFILL but got %s", nc_err_code_name(err));
err = APIFunc(def_var)(ncid, "new_var", NC_INT, 0, NULL, &varid);
IF (err != NC_NOERR)
error("redef: %s", APIFunc(strerror)(err));
err = APIFunc(def_var_fill)(ncid, varid, 0, &value);
IF (err != NC_NOERR)
error("def_var_fill: %s", APIFunc(strerror)(err));
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/* This function gets the version of a netCDF file, 1 is for netCDF
classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format,
5 for 64-bit data format (CDF-5).
*/
#define MAGIC_NUM_LEN 4
static
int
APIFunc(get_file_version)(char *path, int *version)
{
int fd;
ssize_t read_len;
char magic[MAGIC_NUM_LEN];
/* Need two valid pointers - check for NULL. */
if (!version || !path)
return NC_EINVAL;
/* Figure out if this is a netcdf or hdf5 file. */
fd = open(path, O_RDONLY, 0600);
if (fd == -1) return errno;
read_len = read(fd, magic, MAGIC_NUM_LEN);
if (-1 == close(fd)) return errno;
if (read_len == -1)
return errno;
if (read_len != MAGIC_NUM_LEN) {
printf("Error: reading NC magic string unexpected short read\n");
return 0;
}
if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) {
if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC ||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET
#ifdef NETCDF_ENABLE_CDF5
|| magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5
#endif
)
*version = magic[MAGIC_NUM_LEN-1];
else
return NC_ENOTNC;
}
/* tomorrow, tomorrow, I love you tomorrow, you're always a day
away! */
/*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F')
*version = 3;*/
return NC_NOERR;
}
/*
* Test APIFunc(set_default_format)
* try with bad default format
* try with NULL old_formatp
* try in data mode, check error
* check that proper set to NC_FILL works for record & non-record variables
* (note that it is not possible to test NC_NOFILL mode!)
* close file & create again for test using attribute _FillValue
*/
int
TestFunc(set_default_format)(void)
{
int ncid, nok=0;
int err;
int i;
int version=1;
int old_format;
/* bad format */
err = APIFunc(set_default_format)(BAD_DEFAULT_FORMAT, &old_format);
IF (err != NC_EINVAL)
error("expecting NC_EINVAL but got %s", nc_err_code_name(err));
ELSE_NOK
/* NULL old_formatp */
err = APIFunc(set_default_format)(NC_FORMAT_64BIT_OFFSET, NULL);
IF (err != NC_NOERR)
error("null old_fortmatp: status = %d", err);
ELSE_NOK
/* Cycle through available formats. */
for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++) {
if (i == NC_FORMAT_NETCDF4 || i == NC_FORMAT_NETCDF4_CLASSIC)
continue; /* test classic formats only */
if ((err = APIFunc(set_default_format)(i, NULL)))
error("setting classic format: status = %d", err);
ELSE_NOK
err = FileCreate(scratch, NC_CLOBBER, &ncid);
if (err != NC_NOERR)
error("bad nc_create: status = %d", err);
err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "testatt", sizeof("blah"), "blah");
if (err != NC_NOERR)
error("bad put_att: status = %d", err);
err = APIFunc(close)(ncid);
if (err != NC_NOERR)
error("bad close: status = %d", err);
err = APIFunc(get_file_version)(scratch, &version);
if (err != NC_NOERR)
error("bad file version = %d", err);
if (version != i) {
#if 0
if (i == 4) {
if (version == 3) continue;
printf("expect version 3 but got %d (file=%s)",version,scratch);
continue;
}
#endif
printf("expect version %d but got %d (file=%s)",i,version,scratch);
error("bad file version = %d", version);
}
}
/* Remove the left-over file. */
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}
/*
* Test FileDelete
* create netcdf file 'scratch.nc' with no data, close it
* delete the file
*/
int
TestFunc(delete)(void)
{
int err, nok=0;
int ncid;
err = FileCreate(scratch, NC_CLOBBER, &ncid);
IF (err != NC_NOERR)
error("error creating scratch file %s, status = %d\n", scratch,err);
err = APIFunc(close)(ncid);
IF (err != NC_NOERR)
error("close: %s", APIFunc(strerror)(err));
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
ELSE_NOK
return nok;
}