libdballe 9.6
msg/tests.h
1#include <dballe/core/tests.h>
2#include <dballe/message.h>
3#include <dballe/importer.h>
4#include <dballe/exporter.h>
5#include <dballe/msg/msg.h>
6#include <vector>
7
8namespace wreport {
9struct Vartable;
10}
11
12namespace dballe {
13namespace tests {
14
15impl::Messages read_msgs(const char* filename, Encoding type, const dballe::ImporterOptions& opts=dballe::ImporterOptions::defaults);
16impl::Messages read_msgs(const char* filename, Encoding type, const std::string& opts);
17impl::Messages read_msgs_csv(const char* filename);
18
19struct ActualMessage : public Actual<const Message&>
20{
21 using Actual::Actual;
22
23 void is_undef(const impl::Shortcut& shortcut) const;
24};
25
26inline ActualMessage actual(const Message& message) { return ActualMessage(message); }
27
28std::unique_ptr<wreport::Bulletin> export_msgs(Encoding enctype, const impl::Messages& in, const std::string& tag, const dballe::ExporterOptions& opts=dballe::ExporterOptions::defaults);
29#define test_export_msgs(...) wcallchecked(export_msgs(__VA_ARGS__))
30
31void track_different_msgs(const Message& msg1, const Message& msg2, const std::string& prefix);
32void track_different_msgs(const impl::Messages& msgs1, const impl::Messages& msgs2, const std::string& prefix);
33
34extern const char* bufr_files[];
35extern const char* crex_files[];
36
37const wreport::Var& want_var(const Message& msg, const impl::Shortcut& shortcut);
38const wreport::Var& want_var(const Message& msg, wreport::Varcode code, const dballe::Level& lev, const dballe::Trange& tr);
39
40inline ActualVar actual_var(const Message& message, const impl::Shortcut& shortcut) { return ActualVar(want_var(message, shortcut)); }
41inline ActualVar actual_var(const Message& message, wreport::Varcode code, const dballe::Level& lev, const dballe::Trange& tr) { return ActualVar(want_var(message, code, lev, tr)); }
42
43void dump(const std::string& tag, const Message& msg, const std::string& desc="message");
44void dump(const std::string& tag, const impl::Messages& msgs, const std::string& desc="message");
45void dump(const std::string& tag, const wreport::Bulletin& bul, const std::string& desc="message");
46void dump(const std::string& tag, const BinaryMessage& msg, const std::string& desc="message");
47void dump(const std::string& tag, const std::string& str, const std::string& desc="message");
48
50{
51 virtual ~MessageTweaker() {}
52 virtual void tweak(impl::Messages&) {}
53 virtual std::string desc() const = 0;
54};
55
57{
58 std::vector<MessageTweaker*> tweaks;
59
61 // Takes ownership of memory management
62 void add(MessageTweaker* tweak);
63 void apply(impl::Messages& msgs);
64};
65
66namespace tweaks {
67
68// Strip attributes from all variables in a impl::Messages
70{
71 std::vector<wreport::Varcode> codes;
72
73 void tweak(impl::Messages& msgs);
74 virtual std::string desc() const { return "StripAttrs"; }
75};
76
77// Strip attributes from all variables in a impl::Messages
78struct StripQCAttrs : public StripAttrs
79{
81 virtual std::string desc() const { return "StripQCAttrs"; }
82};
83
84// Strip attributes with substituted values
86{
87 void tweak(impl::Messages& msgs);
88 virtual std::string desc() const { return "StripSubstituteAttrs"; }
89};
90
91// Strip context attributes from all variables in a impl::Messages
93{
95 virtual std::string desc() const { return "StripContextAttrs"; }
96};
97
98// Strip a user-defined list of vars from all levels
100{
101 std::vector<wreport::Varcode> codes;
102
103 StripVars() {}
104 StripVars(std::initializer_list<wreport::Varcode> codes) : codes(codes) {}
105 void tweak(impl::Messages& msgs);
106 virtual std::string desc() const { return "StripVars"; }
107};
108
109// Round variables to account for a passage through legacy vars
111{
112 const wreport::Vartable* table;
114 void tweak(impl::Messages& msgs);
115 virtual std::string desc() const { return "RoundLegacyVars"; }
116};
117
118// Remove synop vars present in WMO templates but not in ECMWF templates
120{
121 void tweak(impl::Messages& msgs);
122 virtual std::string desc() const { return "RemoveSynopWMOOnlyVars"; }
123};
124
125// Remove temp vars present in WMO templates but not in ECMWF templates
127{
128 void tweak(impl::Messages& msgs);
129 virtual std::string desc() const { return "RemoveTempWMOOnlyVars"; }
130};
131
132// Remove temp vars present only in an odd temp template for which we have
133// messages in the test suite
135{
137 virtual std::string desc() const { return "RemoveOddTempTemplateOnlyVars"; }
138};
139
140// Remove ground level with missing length of statistical processing, that
141// cannot be encoded in ECMWF templates
143{
144 void tweak(impl::Messages& msgs);
145 virtual std::string desc() const { return "RemoveSynopWMOOddprec"; }
146};
147
148// Truncate station name to its canonical length
150{
151 void tweak(impl::Messages& msgs);
152 virtual std::string desc() const { return "TruncStName"; }
153};
154
155// Round geopotential with a B10003->B10008->B10009->B10008->B10003 round trip
157{
158 const wreport::Vartable* table;
160 void tweak(impl::Messages& msgs);
161 virtual std::string desc() const { return "RoundGeopotential"; }
162};
163
164// Add B10008 GEOPOTENTIAL to all height levels, with its value taken from the height
166{
167 const wreport::Vartable* table;
169 void tweak(impl::Messages& msgs);
170 virtual std::string desc() const { return "HeightToGeopotential"; }
171};
172
173// Round vertical sounding significance with a B08042->B08001->B08042 round trip
175{
176 void tweak(impl::Messages& msgs);
177 virtual std::string desc() const { return "RoundVSS"; }
178};
179
180// Remove a context given its level and time range
182{
183 Level lev;
184 Trange tr;
185 RemoveContext(const Level& lev, const Trange& tr);
186 void tweak(impl::Messages& msgs);
187 virtual std::string desc() const { return "RemoveContext"; }
188};
189
190}
191
193{
194 std::string name;
195 Encoding type;
196 BinaryMessage raw;
197 wreport::Bulletin* bulletin = 0;
198 impl::Messages msgs;
199
200 TestMessage(Encoding type, const std::string& name);
201 ~TestMessage();
202
203 void read_from_file(const std::string& fname, const ImporterOptions& input_opts);
204 void read_from_raw(const BinaryMessage& msg, const ImporterOptions& input_opts);
205 void read_from_msgs(const impl::Messages& msgs, const ExporterOptions& export_opts);
206 void dump() const;
207};
208
210{
211 std::string fname;
212 Encoding type;
213 bool verbose = false;
214 impl::ImporterOptions input_opts;
215 impl::ExporterOptions output_opts;
216 std::string expected_template;
217 int expected_subsets = 1;
218 int expected_min_vars = 1;
219 int expected_data_category = MISSING_INT;
220 int expected_data_subcategory = MISSING_INT;
221 int expected_data_subcategory_local = MISSING_INT;
222 MessageTweakers after_reimport_import;
223 MessageTweakers after_reimport_reimport;
224 MessageTweakers after_convert_import;
225 MessageTweakers after_convert_reimport;
226
227 void do_compare(const TestMessage& msg1, const TestMessage& msg2);
228
229 TestCodec(const std::string& fname, Encoding type=Encoding::BUFR);
230
231 void configure_ecmwf_to_wmo_tweaks();
232
233 // "import, export, import again, compare" test
234 void run_reimport();
235
236 // "import, export as different template, import again, compare" test
237 void run_convert(const std::string& tplname);
238};
239
240
241#if 0
242
243/* Random message generation functions */
244
245class msg_generator : public generator
246{
247public:
248 dba_err fill_message(dba_msg msg, bool mobile);
249};
250
251
252/* Message reading functions */
253
254class msg_vector : public dba_raw_consumer, public std::vector<dba_msgs>
255{
256public:
257 virtual ~msg_vector()
258 {
259 for (iterator i = begin(); i != end(); i++)
260 dba_msgs_delete(*i);
261 }
262
263 virtual dba_err consume(dba_rawmsg raw)
264 {
265 dba_msgs msgs;
266
267 DBA_RUN_OR_RETURN(dba_marshal_decode(raw, &msgs));
268 push_back(msgs);
269
270 return dba_error_ok();
271 }
272};
273
274template <typename T>
275void my_ensure_msg_equals(const char* file, int line, dba_msg msg, int id, const char* idname, const T& value)
276{
277 dba_var var = my_want_var(file, line, msg, id, idname);
278 inner_ensure_var_equals(var, value);
279}
280#define gen_ensure_msg_equals(msg, id, value) my_ensure_msg_equals(__FILE__, __LINE__, (msg), (id), #id, (value))
281#define inner_ensure_msg_equals(msg, id, value) my_ensure_msg_equals(file, line, (msg), (id), #id, (value))
282#endif
283
284}
285}
286
287// vim:set ts=4 sw=4:
Binary message.
Definition: file.h:131
Options to control message export.
Definition: exporter.h:25
Options to control message import.
Definition: importer.h:25
static const ImporterOptions defaults
Default importer options.
Definition: importer.h:54
A bulletin that has been decoded and physically interpreted.
Definition: message.h:29
uint16_t Varcode
Vertical level or layer.
Definition: types.h:625
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:687
ExporterOptions with default constructor usable.
Definition: msg.h:39
ImporterOptions with default constructor usable.
Definition: msg.h:26
Definition: shortcuts.h:12
Definition: msg/tests.h:20
Definition: msg/tests.h:50
Definition: msg/tests.h:57
Definition: msg/tests.h:210
Definition: msg/tests.h:193
Definition: msg/tests.h:182
Definition: msg/tests.h:157
Definition: msg/tests.h:111
Definition: msg/tests.h:175
Definition: msg/tests.h:70
Definition: msg/tests.h:79
Definition: msg/tests.h:100
Definition: msg/tests.h:150