test_stardis_smeteo.c (5616B)
1 /* Copyright (C) 2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is dismshbuted in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #define _POSIX_C_SOURCE 200809L /* strdup */ 17 18 #include "smeteo.h" 19 #include "stardis_smeteo.h" 20 21 #include <rsys/mem_allocator.h> 22 23 /* FIXME required by the UINT_MAX constant used in the stardis-prog-properties 24 * header. It should by stardis, not by the caller. */ 25 #include <limits.h> 26 27 #include <string.h> /* strdup */ 28 29 /******************************************************************************* 30 * Helper functions 31 ******************************************************************************/ 32 static void* 33 check_lib_api(const char* filename) 34 { 35 struct stardis_program_context ctx = {0}; 36 char* argv[2] = {NULL}; 37 void* lib = NULL; 38 39 /* Input strings cannot be constants, so they must be duplicated */ 40 CHK(argv[0] = strdup("stardis-plugin")); /* dummy string */ 41 CHK(argv[1] = strdup(filename)); 42 43 ctx.name = argv[0]; 44 ctx.verbosity_level = 3; 45 46 /* Invalid function calls */ 47 CHK(stardis_create_library_data(NULL, 2, argv) == NULL); 48 CHK(stardis_create_library_data(&ctx, 1, argv) == NULL); 49 CHK(stardis_create_library_data(&ctx, 2, NULL) == NULL); 50 51 /* Valid function call */ 52 CHK((lib = stardis_create_library_data(&ctx, 2, argv)) != NULL); 53 54 /* Verify that, on a valid lib, the legal functions return a valid result */ 55 CHK(get_copyright_notice(lib) != NULL); 56 CHK(get_license_short(lib) != NULL); 57 CHK(get_license_text(lib) != NULL); 58 59 CHK(stardis_finalize_library_data(lib) == STARDIS_SUCCESS); 60 61 /* Check for error if file is invalid */ 62 free(argv[1]); 63 CHK(argv[1] = strdup("invalid_filename.txt")); 64 CHK(stardis_create_library_data(&ctx, 2, argv) == NULL); 65 66 /* Clean-up allocated memory */ 67 free(argv[0]); 68 free(argv[1]); 69 70 return lib; /* Return the created library */ 71 } 72 73 static void* 74 check_data_api(void* lib) 75 { 76 struct stardis_description_create_context ctx = {0}; 77 char* argv[2] = {"smeteo", "-hls"}; 78 size_t argc = sizeof(argv)/sizeof(char*); 79 void* data = NULL; 80 81 /* The input string cannot be constant, so it must be duplicated */ 82 CHK(argv[0] = strdup("boundary-condition")); /* dummy string */ 83 ctx.name = argv[0]; 84 85 /* Invalid function calls */ 86 CHK(stardis_create_data(NULL, lib, argc, argv) == NULL); 87 CHK(stardis_create_data(&ctx, NULL, argc, argv) == NULL); 88 CHK(stardis_create_data(&ctx, lib, 0, argv) == NULL); 89 CHK(stardis_create_data(&ctx, lib, argc, NULL) == NULL); 90 91 /* Valid function call */ 92 CHK((data = stardis_create_data(&ctx, lib, argc, argv)) != NULL); 93 94 free(argv[0]); 95 96 return data; 97 } 98 99 static double /* in [0-1[ */ 100 rand_canonical(void) 101 { 102 return rand() / (double)(RAND_MAX-1); 103 } 104 105 static void 106 check_getters(void* data, const struct smeteo* smeteo) 107 { 108 struct smeteo_desc desc = SMETEO_DESC_NULL; 109 double interval_duration = 0; /* [s] */ 110 111 size_t i = 0; 112 size_t nqueries = 1000; 113 114 struct stardis_vertex vtx = {0}; 115 struct stardis_interface_fragment frag = {0}; 116 117 CHK(smeteo_get_desc(smeteo, &desc) == RES_OK); 118 119 /* Multiplier to convert a time in day_1850 to seconds */ 120 #define M_DAY1850_TO_H (24/*[h]*/ * 3600/*[s]*/) 121 122 /* The dates of the intervals are relative to midnight on January 1, 1850. In 123 * addition, their time is defined at the center of the interval. Thus, for 124 * the first interval, calculate its duration by multiplying its date relative 125 * to January 1, 1850 by 2 */ 126 interval_duration = desc.entries[0].day_1850 * 2 * M_DAY1850_TO_H; 127 128 FOR_EACH(i, 0, nqueries) { 129 /* Randomly select a time interval */ 130 const size_t ientry = (size_t)(rand_canonical() * (double)desc.nentries); 131 const struct smeteo_entry* entry = desc.entries + ientry; 132 133 /* Randomly sample a time [s] in the selected interval */ 134 const double start = entry->day_1850*M_DAY1850_TO_H - interval_duration*0.5; 135 const double time = start + rand_canonical() * interval_duration; 136 137 vtx.time = frag.time = time; 138 139 /* query data */ 140 CHK(stardis_convection_coefficient(&frag, data) == entry->H); 141 CHK(stardis_reference_temperature(&frag, data) == entry->Tsrf); 142 CHK(stardis_boundary_temperature(&frag, data) == entry->Tsrf); 143 CHK(stardis_medium_temperature(&vtx, data) == entry->Tatm); 144 CHK(stardis_emissivity(&frag, STARDIS_INTERN_SOURCE_ID, data) == 1.0); 145 } 146 147 #undef M_DAY1850_TO_H 148 } 149 150 /******************************************************************************* 151 * The test 152 ******************************************************************************/ 153 int 154 main(void) 155 { 156 const char* filename = "samples/star-meteo_input.txt"; 157 158 struct smeteo* smeteo = NULL; 159 void* lib = NULL; 160 void* data = NULL; 161 162 CHK(smeteo_create(&SMETEO_CREATE_ARGS_DEFAULT, &smeteo) == RES_OK); 163 CHK(smeteo_load(smeteo, filename) == RES_OK); 164 165 lib = check_lib_api(filename); 166 data = check_data_api(lib); 167 168 check_getters(data, smeteo); 169 170 stardis_release_library_data(lib); 171 stardis_release_data(data); 172 173 CHK(smeteo_ref_put(smeteo) == RES_OK); 174 175 CHK(mem_allocated_size() == 0); 176 177 return 0; 178 }