netcdf-c/nc_test4/tst_fill_attr_vanish.c

142 lines
4.4 KiB
C

/* This is part of the netCDF package.
Copyright 2018 University Corporation for Atmospheric Research/Unidata
See COPYRIGHT file for conditions of use.
Based on tst_fillbug.c
Added in support of https://github.com/Unidata/netcdf-c/issues/239
The issue in a nutshell is that if _FillValue is added to a file
defined without it, previously existing attributes with
preexisting variables are wiped out, only the _FillValue attribute
exists.
*/
#include <nc_tests.h>
#include "err_macros.h"
#include <stdio.h>
#include <stdlib.h>
#include <netcdf.h>
#define FILENAME "tst_fill_attr_vanish.nc"
#define RANK_Time 1
#define RANK_P 3
#define LEN 4
#define ATTNAME "TextAttribute"
#define ATTVAL "This is a text attribute used for testing."
#define ATTVAL_LEN 43
/*! Main function for tst_fill_attr_vanish.c
*
*/
int main()
{
int ncid, dimids[RANK_P], time_id, p_id, test_id, status;
int test_data[1] = {1};
size_t test_start[1] = {0}, test_count[1] = {1};
int test_fill_val[] = {5};
double data[1] = {3.14159};
size_t start[1] = {0}, count[1] = {1};
printf("\n*** Testing for a netCDF-4 fill-value bug.\n");
printf("*** Creating a file with no _FillValue defined. ***\n");
/* Create a 3D test file. */
if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
/* define dimensions */
if (nc_def_dim(ncid, "Time", NC_UNLIMITED, &dimids[0])) ERR;
if (nc_def_dim(ncid, "X", 4, &dimids[2])) ERR;
if (nc_def_dim(ncid, "Y", 3, &dimids[1])) ERR;
/* define variables */
if (nc_def_var(ncid, "Time", NC_DOUBLE, 1, dimids, &time_id)) ERR;
if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, dimids, &p_id)) ERR;
if (nc_def_var(ncid, "Test", NC_INT, 1, &dimids[1], &test_id)) ERR;
/* Add a _FillValue attribute */
if (nc_put_att_text(ncid, test_id, ATTNAME, strlen(ATTVAL), ATTVAL)) ERR;
/* Add a value to the test variable */
if (nc_put_vara(ncid, test_id, test_start, test_count, test_data)) ERR;
/* Add one record in coordinate variable. */
if (nc_put_vara(ncid, time_id, start, count, data)) ERR;
/* That's it! */
if (nc_close(ncid)) ERR;
/********************************************/
/* Reopen the file, add a fillvalue attribute. */
if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR;
if (nc_redef(ncid)) ERR;
if (nc_inq_varid(ncid, "Test", &test_id)) ERR;
/* Query existing attribute. */
{
char *attval = (char*)malloc(1+(sizeof(char) * strlen(ATTVAL)));
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
printf("**** Checking that attribute still exists:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval))
{printf("Fail\n"); ERR;}
else
{printf("%42s\n",attval);}
free(attval);
}
printf("**** Expecting NC_ELATEFILL when adding _FillValue attribute if variable exists.\n");
status = nc_put_att_int(ncid, test_id, "_FillValue", NC_INT, 1, test_fill_val);
if (status != NC_ELATEFILL) {
fflush(stdout); /* Make sure our stdout is synced with stderr. */
err++;
fprintf(stderr, "Sorry! Expecting NC_ELATEFILL but got %s, at file %s line: %d\n",
nc_strerror(status), __FILE__, __LINE__);
return 2;
}
/* Query existing attribute. */
{
char *attval = (char*)malloc(1+(sizeof(char) * strlen(ATTVAL)));
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
printf("**** Checking that attribute still exists, pre-write:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
else {printf("%s\n",attval);}
free(attval);
}
/* Close file again. */
printf( "**** Saving, closing file.\n");
if (nc_close(ncid)) ERR;
/********************************************/
printf( "*** Reopening file.\n");
/* Reopen the file, checking that all attributes are preserved. */
if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR;
if (nc_redef(ncid)) ERR;
if (nc_inq_varid(ncid, "Test", &test_id)) ERR;
/* Query existing attribute. */
{
char *attval = (char*)malloc(1+(sizeof(char) * strnlen(ATTVAL,ATTVAL_LEN)));
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
printf("**** Checking that attribute still exists:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
else {printf("%s\n",attval);}
free(attval);
}
if (nc_close(ncid)) ERR;
/********************************************/
SUMMARIZE_ERR;
FINAL_RESULTS;
return 0;
}