libdballe 9.9
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::Message& msg, const std::string& desc);
45void dump(const std::string& tag, const impl::Messages& msgs, const std::string& desc="message");
46void dump(const std::string& tag, const wreport::Bulletin& bul, const std::string& desc="message");
47void dump(const std::string& tag, const BinaryMessage& msg, const std::string& desc="message");
48void dump(const std::string& tag, const std::string& str, const std::string& desc="message");
49
51{
52 virtual ~MessageTweaker() {}
53 virtual void tweak(impl::Messages&) {}
54 virtual std::string desc() const = 0;
55};
56
58{
59 std::vector<MessageTweaker*> tweaks;
60
62 // Takes ownership of memory management
63 void add(MessageTweaker* tweak);
64 void apply(impl::Messages& msgs);
65};
66
67namespace tweaks {
68
69// Strip attributes from all variables in a impl::Messages
71{
72 std::vector<wreport::Varcode> codes;
73
74 void tweak(impl::Messages& msgs) override;
75 std::string desc() const override { return "StripAttrs"; }
76};
77
78// Strip attributes from all variables in a impl::Messages
79struct StripQCAttrs : public StripAttrs
80{
82 std::string desc() const override { return "StripQCAttrs"; }
83};
84
85// Strip attributes with substituted values
87{
88 void tweak(impl::Messages& msgs) override;
89 std::string desc() const override { return "StripSubstituteAttrs"; }
90};
91
92// Strip context attributes from all variables in a impl::Messages
94{
96 std::string desc() const override { return "StripContextAttrs"; }
97};
98
99// Strip a user-defined list of vars from all levels
101{
102 std::vector<wreport::Varcode> codes;
103
104 StripVars() {}
105 StripVars(std::initializer_list<wreport::Varcode> codes) : codes(codes) {}
106 void tweak(impl::Messages& msgs) override;
107 std::string desc() const override { return "StripVars"; }
108};
109
110// Round variables to account for a passage through legacy vars
112{
113 const wreport::Vartable* table;
115 void tweak(impl::Messages& msgs) override;
116 std::string desc() const override { return "RoundLegacyVars"; }
117};
118
119// Remove synop vars present in WMO templates but not in ECMWF templates
121{
122 void tweak(impl::Messages& msgs) override;
123 std::string desc() const override { return "RemoveSynopWMOOnlyVars"; }
124};
125
126// Remove temp vars present in WMO templates but not in ECMWF templates
128{
129 void tweak(impl::Messages& msgs) override;
130 std::string desc() const override { return "RemoveTempWMOOnlyVars"; }
131};
132
133// Remove temp vars present only in an odd temp template for which we have
134// messages in the test suite
136{
138 std::string desc() const override { return "RemoveOddTempTemplateOnlyVars"; }
139};
140
141// Remove ground level with missing length of statistical processing, that
142// cannot be encoded in ECMWF templates
144{
145 void tweak(impl::Messages& msgs) override;
146 std::string desc() const override { return "RemoveSynopWMOOddprec"; }
147};
148
149// Truncate station name to its canonical length
151{
152 void tweak(impl::Messages& msgs) override;
153 std::string desc() const override { return "TruncStName"; }
154};
155
156// Round geopotential with a B10003->B10008->B10009->B10008->B10003 round trip
158{
159 const wreport::Vartable* table;
161 void tweak(impl::Messages& msgs) override;
162 std::string desc() const override { return "RoundGeopotential"; }
163};
164
165// Add B10008 GEOPOTENTIAL to all height levels, with its value taken from the height
167{
168 const wreport::Vartable* table;
170 void tweak(impl::Messages& msgs) override;
171 std::string desc() const override { return "HeightToGeopotential"; }
172};
173
174// Round vertical sounding significance with a B08042->B08001->B08042 round trip
176{
177 void tweak(impl::Messages& msgs) override;
178 std::string desc() const override { return "RoundVSS"; }
179};
180
181// Remove a context given its level and time range
183{
184 Level lev;
185 Trange tr;
186 RemoveContext(const Level& lev, const Trange& tr);
187 void tweak(impl::Messages& msgs) override;
188 std::string desc() const override { return "RemoveContext"; }
189};
190
191}
192
194{
195 std::string name;
196 Encoding type;
197 BinaryMessage raw;
198 wreport::Bulletin* bulletin = 0;
199 impl::Messages msgs;
200
201 TestMessage(Encoding type, const std::string& name);
202 ~TestMessage();
203
204 void read_from_file(const std::string& fname, const ImporterOptions& input_opts);
205 void read_from_raw(const BinaryMessage& msg, const ImporterOptions& input_opts);
206 void read_from_msgs(const impl::Messages& msgs, const ExporterOptions& export_opts);
207 void dump() const;
208};
209
211{
212 std::string fname;
213 Encoding type;
214 bool verbose = false;
215 impl::ImporterOptions input_opts;
216 impl::ExporterOptions output_opts;
217 std::string expected_template;
218 int expected_subsets = 1;
219 int expected_min_vars = 1;
220 int expected_data_category = MISSING_INT;
221 int expected_data_subcategory = MISSING_INT;
222 int expected_data_subcategory_local = MISSING_INT;
223 MessageTweakers after_reimport_import;
224 MessageTweakers after_reimport_reimport;
225 MessageTweakers after_convert_import;
226 MessageTweakers after_convert_reimport;
227
228 void do_compare(const TestMessage& msg1, const TestMessage& msg2);
229
230 explicit TestCodec(const std::string& fname, Encoding type=Encoding::BUFR);
231
232 void configure_ecmwf_to_wmo_tweaks();
233
234 // "import, export, import again, compare" test
235 void run_reimport();
236
237 // "import, export as different template, import again, compare" test
238 void run_convert(const std::string& tplname);
239};
240
241
242#if 0
243
244/* Random message generation functions */
245
246class msg_generator : public generator
247{
248public:
249 dba_err fill_message(dba_msg msg, bool mobile);
250};
251
252
253/* Message reading functions */
254
255class msg_vector : public dba_raw_consumer, public std::vector<dba_msgs>
256{
257public:
258 virtual ~msg_vector()
259 {
260 for (iterator i = begin(); i != end(); i++)
261 dba_msgs_delete(*i);
262 }
263
264 virtual dba_err consume(dba_rawmsg raw)
265 {
266 dba_msgs msgs;
267
268 DBA_RUN_OR_RETURN(dba_marshal_decode(raw, &msgs));
269 push_back(msgs);
270
271 return dba_error_ok();
272 }
273};
274
275template <typename T>
276void my_ensure_msg_equals(const char* file, int line, dba_msg msg, int id, const char* idname, const T& value)
277{
278 dba_var var = my_want_var(file, line, msg, id, idname);
279 inner_ensure_var_equals(var, value);
280}
281#define gen_ensure_msg_equals(msg, id, value) my_ensure_msg_equals(__FILE__, __LINE__, (msg), (id), #id, (value))
282#define inner_ensure_msg_equals(msg, id, value) my_ensure_msg_equals(file, line, (msg), (id), #id, (value))
283#endif
284
285}
286}
287
288// 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:51
Definition msg/tests.h:58
Definition msg/tests.h:211
Definition msg/tests.h:194
Definition msg/tests.h:183
Definition msg/tests.h:112
Definition msg/tests.h:176
Definition msg/tests.h:71
Definition msg/tests.h:80
Definition msg/tests.h:101
Definition msg/tests.h:151