1 /** \file \internal
2 Basic NC_INMEMORY API tests both for netcdf-3 and netcdf-4
3
4 Copyright 2011, UCAR/Unidata. See COPYRIGHT file for copying and
5 redistribution conditions.
6 */
7
8 #undef DDBG
9
10 #include "config.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #include "netcdf.h"
18 #include "netcdf_mem.h"
19 #include "ncbytes.h"
20 #include "nc_tests.h"
21 #include "err_macros.h"
22
23 #ifdef USE_NETCDF4
24 #include <hdf5.h>
25 extern int H5Eprint1(FILE * stream);
26 #endif
27
28 #define FLAGS4 (NC_INMEMORY|NC_NETCDF4|NC_CLOBBER)
29 #define FLAGS3 (NC_INMEMORY|NCCLOBBER)
30
31 #define NC_NETCDF3 0
32 #define MODIFIED 1
33
34 #define LARGE_SPACE (1<<18)
35
36 #define FILE3 "tst_inmemory3.nc"
37 #define FILE4 "tst_inmemory4.nc"
38 #define CREATE3 "tst_inmemory3_create.nc"
39 #define CREATE4 "tst_inmemory4_create.nc"
40 #define XFAIL "tst_xfail.nc"
41 #define MISC "tst_misc.nc"
42
43 #define CREATEFILE3 "tst_memcreate3.nc"
44 #define CREATEFILE4 "tst_memcreate4.nc"
45
46 /* Make no dimension larger than this */
47 #define MAXDIMLEN 100
48 #define NDIMS 2
49 #define UNLIM_LEN 2
50 #define DIM0_NAME "fun"
51 #define DIM1_NAME "money"
52 #define DIM1_LEN 8
53 #define ATT0_NAME "home"
54 #define ATT0_TEXT "earthship"
55 #define NVARS 3
56 #define VAR0_NAME "nightlife"
57 #define VAR1_NAME "time"
58 #define VAR2_NAME "taxi_distance"
59 #define VAR3_NAME "miles"
60
61 #define FLOATVAL ((float)42.22)
62
63 /*
64 CDL for created file:
65 netcdf tst_inmemory3 {
66 dimensions:
67 fun = UNLIMITED ; // (2 currently)
68 money = 8 ;
69 variables:
70 int nightlife(fun, money) ;
71 float time ;
72 short taxi_distance(money) ;
73
74 // global attributes:
75 :home = "earthship" ;
76 data:
77
78 nightlife =
79 0, 100, 200, 300, 400, 500, 600, 700,
80 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ;
81
82 time = 42.22 ;
83
84 taxi_distance = 0, 1, 2, 3, 4, 5, 6, 7 ;
85 }
86 */
87
88 #ifdef DDBG
89 #undef ERR
90 static void
fail(int line)91 fail(int line) {
92 fflush(stdout);
93 fprintf(stderr,"\nline=%d\n",line);
94 fflush(stderr);
95 exit(1);
96 }
97 #define ERR fail(__LINE__)
98 #endif
99
100 static int
check(int stat,const char * file,int line,int xfail)101 check(int stat, const char* file, int line, int xfail)
102 {
103 /* int pass = ((!xfail && stat == NC_NOERR) || (xfail && stat != NC_NOERR)); */
104 fflush(stdout);
105 if(!xfail) {
106 if(stat != NC_NOERR) {
107 fprintf(stderr,"***Fail: line: %d; status=%d %s\n",
108 line,stat,nc_strerror(stat));
109 err++;
110 }
111 } else { /*xfail*/
112 if(stat == NC_NOERR) {
113 fprintf(stderr,"***XFail Fail: line: %d; passed instead of failed\n",
114 line);
115 err++;
116 } else {
117 fprintf(stderr,"\t***XFail: status=%d %s\n",
118 stat,nc_strerror(stat));
119 }
120 stat = NC_NOERR; /* because xfail */
121 }
122 fflush(stderr);
123 return stat;
124 }
125
126 #define CHECK(expr) {stat = check((expr),__FILE__,__LINE__,0); if(stat) return stat;}
127 #define XCHECK(expr) {stat = check((expr),__FILE__,__LINE__,1); if(stat) return stat;}
128
129 #define REPORT(xfail,expr) {if((xfail)) {XCHECK((expr));} else {CHECK((expr));}}
130
131 /**************************************************/
132
133 static void
removefile(const char * path)134 removefile(const char* path)
135 {
136 unlink(path);
137 }
138
139 static int
readfile(const char * path,NC_memio * memio)140 readfile(const char* path, NC_memio* memio)
141 {
142 int status = NC_NOERR;
143 FILE* f = NULL;
144 size_t filesize = 0;
145 size_t count = 0;
146 char* memory = NULL;
147 char* p = NULL;
148
149 /* Open the file for reading */
150 #ifdef _MSC_VER
151 f = fopen(path,"rb");
152 #else
153 f = fopen(path,"r");
154 #endif
155 if(f == NULL)
156 {status = errno; goto done;}
157 /* get current filesize */
158 if(fseek(f,0,SEEK_END) < 0)
159 {status = errno; goto done;}
160 filesize = (size_t)ftell(f);
161 /* allocate memory */
162 memory = malloc((size_t)filesize);
163 if(memory == NULL)
164 {status = NC_ENOMEM; goto done;}
165 /* move pointer back to beginning of file */
166 rewind(f);
167 count = filesize;
168 p = memory;
169 while(count > 0) {
170 size_t actual;
171 actual = fread(p,1,count,f);
172 if(actual == 0 || ferror(f))
173 {status = NC_EIO; goto done;}
174 count -= actual;
175 p += actual;
176 }
177 if(memio) {
178 memio->size = (size_t)filesize;
179 memio->memory = memory;
180 }
181 done:
182 if(status != NC_NOERR && memory != NULL)
183 free(memory);
184 if(f != NULL) fclose(f);
185 return status;
186 }
187
188
189 static int
writefile(const char * path,NC_memio * memio)190 writefile(const char* path, NC_memio* memio)
191 {
192 int status = NC_NOERR;
193 FILE* f = NULL;
194 size_t count = 0;
195 char* p = NULL;
196
197 /* Open the file for writing */
198 #ifdef _MSC_VER
199 f = fopen(path,"wb");
200 #else
201 f = fopen(path,"w");
202 #endif
203 if(f == NULL)
204 {status = errno; goto done;}
205 count = memio->size;
206 p = memio->memory;
207 while(count > 0) {
208 size_t actual;
209 actual = fwrite(p,1,count,f);
210 if(actual == 0 || ferror(f))
211 {status = NC_EIO; goto done;}
212 count -= actual;
213 p += actual;
214 }
215 done:
216 if(f != NULL) fclose(f);
217 return status;
218 }
219
220
221 /* Duplicate an NC_memio instance; needed to avoid
222 attempting to use memory that might have been realloc'd
223 Allow the new memory to be larger than the src memory
224 */
225 int
duplicatememory(NC_memio * src,NC_memio * target,size_t alloc)226 duplicatememory(NC_memio* src, NC_memio* target, size_t alloc)
227 {
228 if(src == NULL || target == NULL || src->size == 0 || src->memory == NULL)
229 return NC_EINVAL;
230 *target = *src;
231 if(alloc == 0) alloc = src->size;
232 target->memory = malloc(alloc);
233 if(target->memory == NULL)
234 return NC_ENOMEM;
235 memcpy(target->memory,src->memory,src->size);
236 target->size = alloc;
237 return NC_NOERR;
238 }
239
240 /*
241 Given an ncid of a created file, fill in the meta-data
242 and data as described by the above CDL. Do not close
243 the file.
244 */
245
246 static int
define_metadata(int ncid)247 define_metadata(int ncid)
248 {
249 int stat = NC_NOERR;
250 int dimid[NDIMS], varid0, varid1, varid2;
251 short short_data[DIM1_LEN];
252 size_t start[1] = {0};
253 size_t count[1] = {DIM1_LEN};
254 int dimprod = (UNLIM_LEN*DIM1_LEN);
255 int i;
256 float float_data;
257 int nightdata[UNLIM_LEN*DIM1_LEN] ;
258
259 /* Create data to write */
260 float_data = FLOATVAL;
261
262 for (i = 0; i < DIM1_LEN; i++)
263 short_data[i] = i;
264
265 for (i = 0; i < dimprod; i++)
266 nightdata[i] = (100*i);
267
268 CHECK(nc_put_att_text(ncid, NC_GLOBAL, ATT0_NAME,
269 sizeof(ATT0_TEXT), ATT0_TEXT));
270
271 CHECK(nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid[0]));
272 CHECK(nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimid[1]));
273
274 CHECK(nc_def_var(ncid, VAR0_NAME, NC_INT, NDIMS, dimid, &varid0));
275 CHECK(nc_def_var(ncid, VAR1_NAME, NC_FLOAT, 0, NULL, &varid1));
276 CHECK(nc_def_var(ncid, VAR2_NAME, NC_SHORT, 1, &dimid[1], &varid2));
277
278 CHECK(nc_enddef(ncid));
279
280 CHECK(nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data));
281 CHECK(nc_put_vara_short(ncid, varid2, start, count, short_data));
282
283 {
284 size_t start[2] = {0,0};
285 size_t count[2] = {2,DIM1_LEN};
286 CHECK(nc_put_vara_int(ncid, varid0, start, count, nightdata));
287 }
288
289 return stat;
290 }
291
292
293 /*
294 Create our reference file as a real on-disk file
295 and read it back into memory
296 */
297
298 static int
create_reference_file(const char * filename,int mode,NC_memio * filedata)299 create_reference_file(const char* filename, int mode, NC_memio* filedata)
300 {
301 int stat = NC_NOERR;
302 int ncid;
303
304 CHECK(nc_create(filename, mode|NC_CLOBBER, &ncid)); /* overwrite */
305 CHECK(define_metadata(ncid));
306 CHECK(nc_close(ncid));
307
308 /* Read back the contents of the file into memory */
309 if(filedata != NULL) {
310 memset(filedata,0,sizeof(NC_memio));
311 CHECK(readfile(filename,filedata));
312 }
313 return stat;
314 }
315
316 static int
modify_file(int ncid)317 modify_file(int ncid)
318 {
319 int stat = NC_NOERR;
320 size_t i;
321 int varid3;
322 int dimid[1];
323 size_t len;
324 int data[MAXDIMLEN];
325
326 /* Get id of the unlimited dimension */
327 if((stat=nc_inq_dimid(ncid, DIM0_NAME, dimid))) goto done;
328 /* get current dim length */
329 if((stat=nc_inq_dimlen(ncid, dimid[0], &len))) goto done;
330 /* open file for new meta-data */
331 if((stat=nc_redef(ncid))) goto done;
332 /* Define a new variable */
333 if((stat=nc_def_var(ncid, VAR3_NAME, NC_INT, 1, dimid, &varid3))) goto done;
334 /* close metadata */
335 if((stat=nc_enddef(ncid))) goto done;
336 /* Write data to new variable */
337 for(i=0;i<len;i++)
338 data[i] = i;
339 if((stat=nc_put_var_int(ncid,varid3,data))) goto done;
340 done:
341 return stat;
342 }
343
344 /* Verify the content of a file */
345 static int
verify_file(int ncid,int modified)346 verify_file(int ncid, int modified)
347 {
348 int stat = NC_NOERR;
349 int i;
350 int dimid_in[NDIMS];
351 int dimid[NDIMS];
352 int ndims_in, nvars_in, natts_in, unlimdimid_in;
353 char name_in[NC_MAX_NAME + 1], att0_in[NC_MAX_NAME + 1];
354 nc_type type_in;
355 size_t len_in;
356 int varid[4];
357 int nightdata_in[UNLIM_LEN*DIM1_LEN] ;
358 float float_data_in;
359 int milesdata_in[MAXDIMLEN];
360 int dimprod = UNLIM_LEN * DIM1_LEN;
361 #ifdef USE_NETCDF4
362 int tmp;
363 #endif
364
365 CHECK(nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in));
366 if (ndims_in != 2 || nvars_in != NVARS+modified || natts_in != 1 || unlimdimid_in != 0)
367 CHECK(NC_EINVAL);
368
369 /* Get all the dimids */
370 #ifdef USE_NETCDF4
371 tmp = 0;
372 CHECK((nc_inq_dimids(ncid,&tmp,dimid,1)));
373 if(tmp != NDIMS) CHECK(NC_EINVAL);
374
375 /* Get all the varids */
376 tmp = 0;
377 CHECK((nc_inq_varids(ncid,&tmp,varid)));
378 if(tmp != (NVARS+modified)) CHECK(NC_EINVAL);
379 #else
380 { /* Simulate nc_inq_varids and nc_inq_dimids */
381 int j;
382 int dimcnt = 0;
383 int varcnt = 0;
384 CHECK(nc_inq(ncid, &dimcnt, &varcnt, NULL, NULL));
385 for(j=0;j<dimcnt;j++) dimid[j] = j;
386 for(j=0;j<varcnt;j++) varid[j] = j;
387 }
388 #endif
389
390 CHECK(nc_get_att_text(ncid, NC_GLOBAL, ATT0_NAME, att0_in));
391 att0_in[sizeof(ATT0_TEXT)] = '\0';
392 if (strcmp(att0_in, ATT0_TEXT)) CHECK(NC_EINVAL);
393
394 /* CHECK dimensions. */
395 CHECK(nc_inq_dim(ncid, dimid[0], name_in, &len_in));
396 if (strcmp(name_in, DIM0_NAME)) CHECK(NC_EINVAL);
397 CHECK(nc_inq_dim(ncid, dimid[1], name_in, &len_in));
398 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) CHECK(NC_EINVAL);
399
400 /* CHECK variables. */
401 CHECK(nc_inq_var(ncid, varid[0], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
402 if (strcmp(name_in, VAR0_NAME) || type_in != NC_INT || ndims_in != NDIMS ||
403 dimid_in[0] != 0 || dimid_in[1] != 1 || natts_in != 0) CHECK(NC_EINVAL);
404 CHECK(nc_inq_var(ncid, varid[1], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
405 if (strcmp(name_in, VAR1_NAME) || type_in != NC_FLOAT || ndims_in != 0 ||
406 natts_in != 0) CHECK(NC_EINVAL);
407 CHECK(nc_inq_var(ncid, varid[2], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
408 if (strcmp(name_in, VAR2_NAME) || type_in != NC_SHORT || ndims_in != 1 ||
409 dimid_in[0] != 1 || natts_in != 0) CHECK(NC_EINVAL);
410
411 CHECK(nc_get_var_int(ncid, varid[0], nightdata_in));
412 for(i=0;i<dimprod;i++) {
413 if(nightdata_in[i] != (100*i)) CHECK(NC_EINVAL);
414 }
415
416 CHECK(nc_get_vara_float(ncid, varid[1], NULL, NULL, &float_data_in));
417 if (float_data_in != FLOATVAL) CHECK(NC_EINVAL);
418
419 if(modified) {
420 size_t unlimlen;
421 CHECK(nc_inq_var(ncid, varid[3], name_in, &type_in, &ndims_in, dimid_in, &natts_in));
422 if (strcmp(name_in, VAR3_NAME) || type_in != NC_INT || ndims_in != 1 ||
423 dimid_in[0] != 0 || natts_in != 0) CHECK(NC_EINVAL);
424 CHECK(nc_inq_dimlen(ncid, dimid_in[0], &unlimlen));
425 CHECK(nc_get_var_int(ncid, varid[3], milesdata_in));
426 for(i=0;i<unlimlen;i++) {
427 if(milesdata_in[i] != i) CHECK(NC_EINVAL);
428 }
429 }
430
431 return stat;
432 }
433
434 void
memiofree(NC_memio * memio)435 memiofree(NC_memio* memio)
436 {
437 if(memio != NULL) {
438 if(memio->memory != NULL)
439 free(memio->memory);
440 memio->memory = NULL;
441 }
442 }
443
444 static int
test_open(const char * path,NC_memio * filedata,int mode)445 test_open(const char* path, NC_memio* filedata, int mode)
446 {
447 int stat = NC_NOERR;
448 NC_memio duplicate;
449 NC_memio finaldata;
450 int ncid;
451 int xmode = mode; /* modified mode */
452
453 finaldata.memory = NULL;
454 finaldata.size = 0;
455 finaldata.flags = 0;
456
457 fprintf(stderr,"\n\t***Test open 1: nc_open_mem(): read-only\n");
458 CHECK(duplicatememory(filedata,&duplicate,0));
459 CHECK(nc_open_mem(path, xmode, duplicate.size, duplicate.memory, &ncid));
460 CHECK(verify_file(ncid,!MODIFIED));
461 CHECK(nc_close(ncid));
462 memiofree(&duplicate);
463
464 fprintf(stderr,"\n\t***Test open 2: nc_open_memio(): read-only\n");
465 CHECK(duplicatememory(filedata,&duplicate,0));
466 duplicate.flags = NC_MEMIO_LOCKED;
467 CHECK(nc_open_memio(path, xmode, &duplicate, &ncid))
468 CHECK(verify_file(ncid,!MODIFIED));
469 CHECK(nc_close_memio(ncid,&finaldata));
470 /* Published returned finaldata */
471 fprintf(stderr,"\tfinaldata: size=%lld memory=%p\n",(unsigned long long)finaldata.size,finaldata.memory);
472 /* Verify that finaldata is same */
473 if(finaldata.size != duplicate.size) CHECK(NC_EINVAL);
474 if(finaldata.memory != duplicate.memory) CHECK(NC_EINVAL);
475 memiofree(&finaldata);
476
477 fprintf(stderr,"\n\t***Test open 3: nc_open_memio(): read-write, copy\n");
478 xmode |= NC_WRITE; /* allow file to be modified */
479 CHECK(duplicatememory(filedata,&duplicate,0));
480 CHECK(nc_open_memio(path, xmode, &duplicate, &ncid))
481 /* modify file */
482 CHECK(modify_file(ncid));
483 CHECK(verify_file(ncid,MODIFIED));
484 CHECK(nc_close_memio(ncid,&finaldata));
485 /* Published returned finaldata */
486 fprintf(stderr,"\tfinaldata: size=%lld memory=%p\n",(unsigned long long)finaldata.size,finaldata.memory);
487 /* Verify that finaldata is same */
488 if(finaldata.size < filedata->size) CHECK(NC_EINVAL);
489 /* As a safeguard, the memory in duplicate should have been set to NULL*/
490 memiofree(&finaldata);
491
492 fprintf(stderr,"\n\t***Test open 4: nc_open_memio(): read-write, locked, extra space\n");
493 /* Store the filedata in a memory chunk that leaves room for modification */
494 CHECK(duplicatememory(filedata,&duplicate,LARGE_SPACE));
495 /* Lock the duplicate memory */
496 duplicate.flags |= NC_MEMIO_LOCKED;
497 xmode |= NC_WRITE; /* allow file to be modified */
498 CHECK(nc_open_memio(path, xmode, &duplicate, &ncid))
499 /* modify file */
500 CHECK(modify_file(ncid));
501 CHECK(verify_file(ncid,MODIFIED));
502 CHECK(nc_close_memio(ncid,&finaldata));
503 /* Published returned finaldata */
504 fprintf(stderr,"\tfinaldata: size=%lld memory=%p\n",(unsigned long long)finaldata.size,finaldata.memory);
505 /* Check returned finaldata:
506 should have same memory but
507 actual used final size should not exceed the original */
508 if(finaldata.size > duplicate.size) CHECK(NC_EINVAL);
509 if(finaldata.memory != duplicate.memory) CHECK(NC_EINVAL);
510 memiofree(&finaldata);
511 return stat;
512 }
513
514 static int
test_create(const char * path,int mode)515 test_create(const char* path, int mode)
516 {
517 int stat = NC_NOERR;
518 NC_memio finaldata;
519 int ncid;
520 int xmode = mode;
521
522 finaldata.memory = NULL;
523 finaldata.size = 0;
524 finaldata.flags = 0;
525
526 fprintf(stderr,"\n\t***Test create 1: nc_create_memio(): no initialsize\n");
527 CHECK(nc_create_mem(path, xmode, 0, &ncid))
528 /* create file metadata */
529 CHECK(define_metadata(ncid));
530 CHECK(verify_file(ncid,!MODIFIED));
531 CHECK(nc_close_memio(ncid,&finaldata));
532 /* Published returned finaldata */
533 fprintf(stderr,"\tfinaldata: size=%lld memory=%p\n",(unsigned long long)finaldata.size,finaldata.memory);
534 free(finaldata.memory);
535 fprintf(stderr,"\n\t***Test create 2: nc_create_memio(): initialsize; save file\n");
536 CHECK(nc_create_mem(path, xmode, LARGE_SPACE, &ncid))
537 /* create file metadata */
538 CHECK(define_metadata(ncid));
539 CHECK(verify_file(ncid,!MODIFIED));
540 CHECK(nc_close_memio(ncid,&finaldata));
541 /* Published returned finaldata */
542 fprintf(stderr,"\tfinaldata: size=%lld memory=%p\n",(unsigned long long)finaldata.size,finaldata.memory);
543 /* Write out the final data as a .nc file */
544 CHECK(writefile(path,&finaldata));
545 if(finaldata.memory != NULL)
546 free(finaldata.memory);
547 finaldata.memory = NULL;
548 return stat;
549 }
550
551 static int
test_misc(const char * path,int mode,NC_memio * filedata)552 test_misc(const char* path, int mode, NC_memio* filedata)
553 {
554 int stat = NC_NOERR;
555 int ncid;
556 int xmode = mode;
557 NC_memio duplicate;
558
559 fprintf(stderr,"\n\t***Test misc 1: use nc_close on created inmemory file\n");
560 CHECK(nc_create_mem(MISC, xmode, 0, &ncid))
561 CHECK(nc_close(ncid));
562 removefile(MISC);
563
564 fprintf(stderr,"\n\t***Test misc 2: use nc_close on opened inmemory file\n");
565 CHECK(duplicatememory(filedata,&duplicate,0));
566 CHECK(nc_open_memio(path, xmode, &duplicate, &ncid))
567 CHECK(verify_file(ncid,!MODIFIED));
568 CHECK(nc_close(ncid));
569 /* Do not free: nc_close will have done it memiofree(&duplicate); */
570 removefile(MISC);
571
572 return stat;
573 }
574
575 /* Test various edge conditions to ensure they fail correctly */
576 static int
test_xfail(const char * path,int mode,NC_memio * filedata)577 test_xfail(const char* path, int mode, NC_memio* filedata)
578 {
579 int stat = NC_NOERR;
580 NC_memio duplicate = {0,NULL,0};
581 int ncid;
582 int xmode = mode; /* modified mode */
583
584 fprintf(stderr,"\n\t***Test xfail 1: nc_open_mem(): write to read-only\n");
585 CHECK(duplicatememory(filedata,&duplicate,0));
586 CHECK(nc_open_mem(XFAIL, xmode, duplicate.size, duplicate.memory, &ncid));
587 XCHECK(nc_redef(ncid));
588 CHECK(nc_abort(ncid));
589 memiofree(&duplicate);
590
591 fprintf(stderr,"\n\t***Test xfail 2: nc_open_memio(): modify without overallocating\n");
592 if((mode & NC_NETCDF4)) {
593 fprintf(stderr,"\tSuppressed because of HDF5 library bug\n");
594 } else {
595 /* With HDF5 1.8.20, and possibly other versions,
596 this tests causes a seg fault in the HDF5 Library.
597 So until it is fixed, just leave well enough alone */
598 NC_memio finaldata;
599 memset(&finaldata,0,sizeof(finaldata));
600 CHECK(duplicatememory(filedata,&duplicate,0));
601 duplicate.flags = NC_MEMIO_LOCKED;
602 xmode |= NC_WRITE;
603 CHECK(nc_open_memio(XFAIL, xmode, &duplicate, &ncid))
604 XCHECK(modify_file(ncid));
605 CHECK(nc_abort(ncid));
606 memiofree(&finaldata);
607 memiofree(&duplicate);
608 }
609
610 return stat;
611 }
612
613 int
main(int argc,char ** argv)614 main(int argc, char **argv)
615 {
616 int stat = NC_NOERR;
617 NC_memio filedata3;
618 #ifdef USE_NETCDF4
619 NC_memio filedata4;
620 #endif
621
622 fprintf(stderr,"\n*** Testing the inmemory API: netcdf-3.\n");
623 CHECK(create_reference_file(FILE3,NC_NETCDF3,&filedata3)); /* netcdf-3 */
624 CHECK(test_open(FILE3,&filedata3,NC_NETCDF3));
625 CHECK(test_create(CREATE3,NC_NETCDF3));
626 CHECK(test_misc(FILE3, NC_NETCDF3, &filedata3));
627 CHECK(test_xfail(FILE3, NC_NETCDF3, &filedata3));
628 memiofree(&filedata3);
629
630 #ifdef USE_NETCDF4
631 fprintf(stderr,"\n*** Testing the inmemory API: netcdf-4.\n");
632 CHECK(create_reference_file(FILE4,NC_NETCDF4,&filedata4));
633 CHECK(test_open(FILE4,&filedata4,NC_NETCDF4));
634 CHECK(test_create(CREATE4,NC_NETCDF4));
635 CHECK(test_misc(FILE4,NC_NETCDF4, &filedata4));
636 CHECK(test_xfail(FILE4, NC_NETCDF4, &filedata4));
637 memiofree(&filedata4);
638 #endif
639
640 SUMMARIZE_ERR;
641
642 FINAL_RESULTS;
643
644 return 0;
645 }
646