mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-15 08:30:11 +08:00
Wiring in a large test to check against a regression for the issue described in https://github.com/Unidata/netcdf-c/pull/457
This commit is contained in:
parent
22d4754306
commit
85e9aaf368
@ -51,7 +51,7 @@ IF(USE_PNETCDF)
|
||||
ENDIF()
|
||||
|
||||
IF(LARGE_FILE_TESTS)
|
||||
SET(TESTS ${TESTS} quick_large_files tst_big_var6 tst_big_var2 tst_big_rvar tst_big_var tst_large)
|
||||
SET(TESTS ${TESTS} quick_large_files tst_big_var6 tst_big_var2 tst_big_rvar tst_big_var tst_large tst_large_cdf5)
|
||||
IF(NOT MSVC)
|
||||
SET(TESTS ${TESTS} large_files)
|
||||
ENDIF()
|
||||
|
@ -16,7 +16,8 @@ tst_*.nc t_nc.nc large_files.nc quick_large_files.nc \
|
||||
tst_diskless.nc tst_diskless2.nc \
|
||||
tst_diskless3.nc tst_diskless3_file.cdl tst_diskless3_memory.cdl \
|
||||
tst_diskless4.cdl tst_diskless4.nc tst_formatx.nc nc_test_cdf5.nc \
|
||||
unlim.nc tst_inq_type.nc tst_elatefill.nc tst_global_fillval.nc
|
||||
unlim.nc tst_inq_type.nc tst_elatefill.nc tst_global_fillval.nc \
|
||||
tst_large_cdf5.nc
|
||||
|
||||
check_PROGRAMS =
|
||||
|
||||
@ -45,7 +46,7 @@ AM_CPPFLAGS += -I$(top_builddir)/liblib -I$(top_builddir)/include -I$(top_srcdir
|
||||
# If the user asked for large file tests, then add them.
|
||||
if LARGE_FILE_TESTS
|
||||
TESTPROGRAMS += quick_large_files tst_big_var6 tst_big_var2 \
|
||||
tst_big_rvar tst_big_var tst_large large_files
|
||||
tst_big_rvar tst_big_var tst_large large_files tst_large_cdf5
|
||||
endif # LARGE_FILE_TESTS
|
||||
|
||||
if BUILD_BENCHMARKS
|
||||
|
179
nc_test/tst_large_cdf5.c
Normal file
179
nc_test/tst_large_cdf5.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
Copyright 2017, UCAR/Unidata
|
||||
See COPYRIGHT file for copying and redistribution conditions.
|
||||
|
||||
This program tests the large file bug in netCDF 3.6.2,
|
||||
creating byte and short variables larger than 4 GiB.
|
||||
|
||||
This program is based on tst_large.c, and tests against
|
||||
CDF5.
|
||||
|
||||
$Id: tst_large.c,v 1.16 2010/05/18 20:20:01 russ Exp $
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <nc_tests.h>
|
||||
#include "err_macros.h"
|
||||
#include <netcdf.h>
|
||||
|
||||
/* Test with both classic and 64-bit offset files. If netcdf-4 is
|
||||
* included, test with both netCDF-4 format variants also. */
|
||||
#ifdef USE_NETCDF4
|
||||
#define NUM_FORMATS (4)
|
||||
#else
|
||||
#define NUM_FORMATS (2)
|
||||
#endif
|
||||
|
||||
#define NUMDIMS 2 /* rank of each variable in tests */
|
||||
#define DIM1 2048
|
||||
#define DIM2 2097153 /* DIM1*DIM2*sizeof(char) > 2**32 */
|
||||
#define DIM3 1024
|
||||
#define DIM4 2097153 /* DIM3*DIM4*sizeof(short) > 2**32 */
|
||||
|
||||
/*
|
||||
* In netCDF-3.6.2, a divide by zero occurs on 32-bit platforms when
|
||||
* creating a variable for which the product of dimensions is exactly
|
||||
* 2**32. Check that this bug has been fixed.
|
||||
*/
|
||||
static int
|
||||
test_big_var(const char *testfile) {
|
||||
int ncid, varid, dimids[NUMDIMS];
|
||||
int cflag = NC_CLOBBER;
|
||||
nc_type type = NC_BYTE;
|
||||
size_t index[NUMDIMS];
|
||||
signed char nval = 99;
|
||||
int nval_in;
|
||||
|
||||
/* Define the file with one large variable. */
|
||||
if (nc_create(testfile, cflag|NC_64BIT_DATA, &ncid)) ERR;
|
||||
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
|
||||
if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
|
||||
if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR;
|
||||
if (nc_def_var(ncid, "var", type, NUMDIMS, dimids, &varid)) ERR;
|
||||
if (nc_enddef(ncid)) ERR;
|
||||
|
||||
/* Write one datum, near the end of the variable. */
|
||||
index[0] = DIM1 - 1;
|
||||
index[1] = DIM2 - 2;
|
||||
if (nc_put_var1_schar(ncid, varid, index, &nval)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
|
||||
/* Reopen the file and check that datum. */
|
||||
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_varid(ncid, "var", &varid)) ERR;
|
||||
if (nc_get_var1_int(ncid, varid, index, &nval_in)) ERR;
|
||||
if (nval != nval_in)
|
||||
ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_large_byte_var(const char *testfile) {
|
||||
int ncid, varid, dimids[NUMDIMS];
|
||||
size_t index[NUMDIMS] = {0, 0};
|
||||
signed char vals[DIM2];
|
||||
signed char char_val_in;
|
||||
size_t start[NUMDIMS], count[NUMDIMS];
|
||||
int j;
|
||||
|
||||
if (nc_create(testfile, NC_CLOBBER|NC_64BIT_DATA, &ncid)) ERR;
|
||||
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
|
||||
if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
|
||||
if (nc_def_dim(ncid, "dim2", DIM2, &dimids[1])) ERR;
|
||||
if (nc_def_var(ncid, "var", NC_BYTE, NUMDIMS, dimids, &varid)) ERR;
|
||||
if (nc_enddef(ncid)) ERR;
|
||||
|
||||
for (j = 0; j < DIM2; j++) {
|
||||
vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */
|
||||
}
|
||||
start[1] = 0;
|
||||
count[0] = 1;
|
||||
count[1] = DIM2;
|
||||
for (start[0] = 0; start[0] < DIM1; start[0]++) {
|
||||
if (nc_put_vara_schar(ncid, varid, start, count, vals))
|
||||
{
|
||||
ERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nc_close(ncid)) ERR;
|
||||
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_varid(ncid, "var", &varid)) ERR;
|
||||
if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR;
|
||||
if (char_val_in != 99) /* see above, the value written when start[0]==0, j==0 */
|
||||
ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_large_short_var(const char *testfile) {
|
||||
int ncid, varid, dimids[NUMDIMS];
|
||||
int int_val_in, int_val_out = 99;
|
||||
size_t index[2];
|
||||
int cflag = NC_CLOBBER;
|
||||
|
||||
if (nc_create(testfile, cflag|NC_64BIT_DATA, &ncid)) ERR;
|
||||
if (nc_def_dim(ncid, "dim3", DIM3, &dimids[0])) ERR;
|
||||
if (nc_def_dim(ncid, "dim4", DIM4, &dimids[1])) ERR;
|
||||
if (nc_def_var(ncid, "var", NC_SHORT, NUMDIMS, dimids, &varid)) ERR;
|
||||
if (nc_enddef(ncid)) ERR;
|
||||
index[0] = 0;
|
||||
index[1] = 1;
|
||||
if (nc_put_var1_int(ncid, varid, index, &int_val_out)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_varid(ncid, "var", &varid)) ERR;
|
||||
if (nc_get_var1_int(ncid, varid, index, &int_val_in)) ERR;
|
||||
if (int_val_in != int_val_out)
|
||||
ERR;
|
||||
#ifndef NOFILL
|
||||
index[0] = 1;
|
||||
index[1] = 2;
|
||||
if (nc_get_var1_int(ncid, varid, index, &int_val_in)) ERR;
|
||||
if (int_val_in != NC_FILL_SHORT)
|
||||
ERR;
|
||||
#endif
|
||||
if (nc_close(ncid)) ERR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FILE_NAME "tst_large_cdf5.nc"
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
int i;
|
||||
char testfile[NC_MAX_NAME + 1];
|
||||
|
||||
sprintf(testfile, "%s/%s", TEMP_LARGE, FILE_NAME);
|
||||
|
||||
printf("\n*** Testing fix for 3.6.2 large file bug in %s.\n",
|
||||
testfile);
|
||||
/* Go thru formats and run all tests for each of two (for netCDF-3
|
||||
* only builds), or 4 (for netCDF-4 builds) different formats. */
|
||||
for (i = NC_FORMAT_CLASSIC; i <= NUM_FORMATS; i++)
|
||||
{
|
||||
nc_set_default_format(i, NULL);
|
||||
|
||||
printf("*** testing format %d with a variable with 2**32 values...", i);
|
||||
test_big_var(testfile);
|
||||
(void) remove(testfile);
|
||||
SUMMARIZE_ERR;
|
||||
|
||||
printf("*** testing format %d with a byte variable with > 2**32 values...", i);
|
||||
test_large_byte_var(testfile);
|
||||
(void) remove(testfile);
|
||||
SUMMARIZE_ERR;
|
||||
|
||||
printf("*** testing format %d with a short variable with > 2**32 values...", i);
|
||||
test_large_short_var(testfile);
|
||||
(void) remove(testfile);
|
||||
SUMMARIZE_ERR;
|
||||
}
|
||||
|
||||
FINAL_RESULTS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user