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:
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);