star-meteo

Time varying meteorological data
git clone git://git.meso-star.fr/star-meteo.git
Log | Files | Refs | README | LICENSE

commit 18fe4a98374f127d16f05790e9f0ad14885858e3
parent 7b7695523c25f2464e2681fe4954c9d3b0abc4c4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 12 Aug 2025 16:26:18 +0200

Improve the genericity and robustness of load tests

Prepare to test loading multiple time intervals by writing a generic
test function for the number of intervals to be loaded.

Write the floating-point data from the input file in hexadecimal
representation to ensure bit-by-bit correspondence with their
representation in C. This allows strict equality to be used to verify
the loaded data against the data used to generate the file.

Diffstat:
MMakefile | 2+-
Msrc/test_smeteo_load.c | 154++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 99 insertions(+), 57 deletions(-)

diff --git a/Makefile b/Makefile @@ -153,7 +153,7 @@ TEST_TGT = $(TEST_SRC:.c=.t) INCS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys smeteo-local.pc) LIBS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys smeteo-local.pc) -CFLAGS_TEST = -std=c89 $(CFLAGS_EXE) $(INCS_TEST) +CFLAGS_TEST = -std=c99 $(CFLAGS_EXE) $(INCS_TEST) LDFLAGS_TEST = $(LDFLAGS_EXE) $(LIBS_TEST) tests: library $(TEST_DEP) $(TEST_TGT) diff --git a/src/test_smeteo_load.c b/src/test_smeteo_load.c @@ -17,7 +17,6 @@ #include "smeteo.h" -#include <rsys/math.h> #include <rsys/mem_allocator.h> #include <string.h> @@ -41,9 +40,9 @@ check_api(struct smeteo* smeteo) #define CHECK_NO_DATA(Name) { \ CHK(smeteo_get_desc(smeteo, &desc) == RES_OK); \ CHK(!strcmp(desc.filename, Name)); \ - CHK(eq_eps(desc.albedo, albedo, 1e-6)); \ - CHK(eq_eps(desc.longitude, longitude, 1e-6)); \ - CHK(eq_eps(desc.latitude, latitude, 1e-6)); \ + CHK(desc.albedo == albedo); \ + CHK(desc.longitude == longitude); \ + CHK(desc.latitude == latitude); \ CHK(desc.entries == NULL); \ CHK(desc.nentries == 0); \ } (void)0 @@ -55,9 +54,9 @@ check_api(struct smeteo* smeteo) /* An empty file is not valid: at least the header is required */ CHK(smeteo_load(smeteo, filename) == RES_BAD_ARG); - CHK(fprintf(fp, "%g # Albedo\n", albedo) > 0); - CHK(fprintf(fp, "%g # Longitude [deg]\n", longitude) > 0); - CHK(fprintf(fp, "%g # Latitude [deg]\n", latitude) > 0); + CHK(fprintf(fp, "%a # Albedo\n", albedo) > 0); + CHK(fprintf(fp, "%a # Longitude [deg]\n", longitude) > 0); + CHK(fprintf(fp, "%a # Latitude [deg]\n", latitude) > 0); CHK(fprintf(fp, "0 # Date count\n") > 0); CHK(fflush(fp) == 0); @@ -81,78 +80,121 @@ check_api(struct smeteo* smeteo) } static void -check_one_entry(struct smeteo* smeteo) +check_n_time_intervals + (struct smeteo* smeteo, + const double albedo, + const double longitude, /* [deg] */ + const double latitude, /* [deg] */ + const size_t nintervals, + const char* date[], + const double Tsrf[], /* [K] */ + const double Tatm[], /* [K] */ + const double Ahum[], /* [g(water)/kg(air)] */ + const double Rhum[], + const double SWdn_direct[], /* [W/m^2] */ + const double SWdn_diffuse[], /* [W/m^2] */ + const double SWup[], /* [W.m^2] */ + const double Trad[], /* [K] */ + const double H[], /* [W/K/m^2] */ + const double LE[], /* W/m^2] */ + const double day_1850[]) { struct smeteo_desc desc = SMETEO_DESC_NULL; - char buf[32]; - const char* date = "01-JAN-1850 01:30:00"; + char buf[32] = {0}; + FILE* fp = NULL; + size_t i = 0; + + CHK((fp = tmpfile()) != NULL); + + CHK(fprintf(fp, "%a # albedo\n", albedo) > 0); + CHK(fprintf(fp, "%a # longitude [deg]\n", longitude) > 0); + CHK(fprintf(fp, "%a # latitude [deg]\n", latitude) > 0); + CHK(fprintf(fp, "%lu # Date count\n", (unsigned long)nintervals) > 0); + + FOR_EACH(i, 0, nintervals) { + CHK(fprintf(fp, "%s %a %a %a %a %a %a %a %a %a %a %a %a\n", + date[i], + Tsrf[i], + Tatm[i], + Ahum[i], + Rhum[i], + SWdn_direct[i] + SWdn_diffuse[i], + SWdn_direct[i], + SWdn_diffuse[i], + SWup[i], + Trad[i], + H[i], + LE[i], + day_1850[i]) > 0); + } + rewind(fp); + + CHK(smeteo_load_stream(smeteo, fp, "Test") == RES_OK); + CHK(smeteo_get_desc(smeteo, &desc) == RES_OK); + + /* Check header */ + #define CHK_HEADER(Var) CHK(Var == desc.Var) + CHK_HEADER(albedo); + CHK_HEADER(longitude); + CHK_HEADER(latitude); + CHK(desc.nentries == nintervals); + #undef CHK_HEADER + + #define CHK_ENTRY(Var) CHK(Var[i] == desc.entries[i].Var) + FOR_EACH(i, 0, nintervals) { + /* Check entry time */ + CHK(strftime(buf, sizeof(buf), "%d-%b-%Y %H:%M:%S", &desc.entries[i].time)); + CHK(strcasecmp(buf, date[i]) == 0); + + /* Check entry data */ + CHK_ENTRY(Tsrf); + CHK_ENTRY(Tatm); + CHK_ENTRY(Ahum); + CHK_ENTRY(Rhum); + CHK_ENTRY(SWdn_direct); + CHK_ENTRY(SWdn_diffuse); + CHK_ENTRY(SWup); + CHK_ENTRY(Trad); + CHK_ENTRY(H); + CHK_ENTRY(LE); + CHK_ENTRY(day_1850); + + } + #undef CHK_ENTRY + + CHK(fclose(fp) == 0); +} + +static void +check_1_time_interval(struct smeteo* smeteo) +{ /* Header */ const double albedo = 1; const double longitude = 91.1; /* [deg] */ const double latitude = 46.2; /* [deg] */ /* Time interval data */ + const char* date = "01-JAN-1850 01:30:00"; const double Tsrf = 287.85; /* [K] */ const double Tatm = 289.62; /* [K] */ const double Ahum = 4.23; /* [g(water)/kg(air)] */ const double Rhum = 12.28; const double SWdn_direct = 175.08; /* [W/m^2] */ const double SWdn_diffuse = 0; /* [W/m^2] */ - const double SWdn = SWdn_direct + SWdn_diffuse; /* [W/m^2] */ const double SWup = 55.43; /* [W/m^2] */ const double Trad = 271.21; /* [K] */ const double H = 12.60; /* [W/K/m^2] */ const double LE = 0.51; /* [W/m^2] */ const double day_1850 = 0.0625; - FILE* fp = NULL; - - CHK((fp = tmpfile()) != NULL); - - CHK(fprintf(fp, "%g # albedo\n", albedo) > 0); - CHK(fprintf(fp, "%g # longitude [deg]\n", longitude) > 0); - CHK(fprintf(fp, "%g # latitude [deg]\n", latitude) > 0); - CHK(fprintf(fp, "1 # Date count\n") > 0); - CHK(fprintf(fp, "%s %g %g %g %g %g %g %g %g %g %g %g %g\n", - date, Tsrf, Tatm, Ahum, Rhum, SWdn, SWdn_direct, SWdn_diffuse, SWup, - Trad, H, LE, day_1850) > 0); - - rewind(fp); - - CHK(smeteo_load_stream(smeteo, fp, "One entry") == RES_OK); - CHK(smeteo_get_desc(smeteo, &desc) == RES_OK); - - /* Check header */ - #define CHK_HEADER(Var) CHK(eq_eps(Var, desc.Var, Var*1e-6)) - CHK_HEADER(albedo); - CHK_HEADER(longitude); - CHK_HEADER(latitude); - CHK(desc.nentries == 1); - #undef CHK_HEADER + check_n_time_intervals(smeteo, albedo, longitude, latitude, 1, &date, &Tsrf, + &Tatm, &Ahum, &Rhum, &SWdn_direct, &SWdn_diffuse, &SWup, &Trad, &H, &LE, + &day_1850); +} - /* Check entry time */ - CHK(strftime(buf, sizeof(buf), "%d-%b-%Y %H:%M:%S", &desc.entries[0].time)); - CHK(strcasecmp(buf, date) == 0); - - /* Check entry data */ - #define CHK_ENTRY(Var) CHK(eq_eps(Var, desc.entries[0].Var, Var*1e-6)) - CHK_ENTRY(Tsrf); - CHK_ENTRY(Tatm); - CHK_ENTRY(Ahum); - CHK_ENTRY(Rhum); - CHK_ENTRY(SWdn_direct); - CHK_ENTRY(SWdn_diffuse); - CHK_ENTRY(SWup); - CHK_ENTRY(Trad); - CHK_ENTRY(H); - CHK_ENTRY(LE); - CHK_ENTRY(day_1850); - #undef CHK_ENTRY - CHK(fclose(fp) == 0); -} /******************************************************************************* * The test @@ -167,7 +209,7 @@ main(void) CHK(smeteo_create(&args, &smeteo) == RES_OK); check_api(smeteo); - check_one_entry(smeteo); + check_1_time_interval(smeteo); CHK(smeteo_ref_put(smeteo) == RES_OK); CHK(mem_allocated_size() == 0);