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