libdballe  9.14
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 
8 namespace wreport {
9 struct Vartable;
10 }
11 
12 namespace dballe {
13 namespace tests {
14 
15 impl::Messages read_msgs(
16  const char* filename, Encoding type,
18 impl::Messages read_msgs(const char* filename, Encoding type,
19  const std::string& opts);
20 impl::Messages read_msgs_csv(const char* filename);
21 
22 struct ActualMessage : public Actual<const Message&>
23 {
24  using Actual::Actual;
25 
26  void is_undef(const impl::Shortcut& shortcut) const;
27 };
28 
29 inline ActualMessage actual(const Message& message)
30 {
31  return ActualMessage(message);
32 }
33 
34 std::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 
39 void track_different_msgs(const Message& msg1, const Message& msg2,
40  const std::string& prefix);
41 void track_different_msgs(const impl::Messages& msgs1,
42  const impl::Messages& msgs2,
43  const std::string& prefix);
44 
45 extern const char* bufr_files[];
46 extern const char* crex_files[];
47 
48 const wreport::Var& want_var(const Message& msg,
49  const impl::Shortcut& shortcut);
50 const wreport::Var& want_var(const Message& msg, wreport::Varcode code,
51  const dballe::Level& lev,
52  const dballe::Trange& tr);
53 
54 inline ActualVar actual_var(const Message& message,
55  const impl::Shortcut& shortcut)
56 {
57  return ActualVar(want_var(message, shortcut));
58 }
59 inline 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 
65 void dump(const std::string& tag, const Message& msg,
66  const std::string& desc = "message");
67 void dump(const std::string& tag, const impl::Message& msg,
68  const std::string& desc);
69 void dump(const std::string& tag, const impl::Messages& msgs,
70  const std::string& desc = "message");
71 void dump(const std::string& tag, const wreport::Bulletin& bul,
72  const std::string& desc = "message");
73 void dump(const std::string& tag, const BinaryMessage& msg,
74  const std::string& desc = "message");
75 void 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 
89  ~MessageTweakers();
90  // Takes ownership of memory management
91  void add(MessageTweaker* tweak);
92  void apply(impl::Messages& msgs);
93 };
94 
95 namespace tweaks {
96 
97 // Strip attributes from all variables in a impl::Messages
98 struct StripAttrs : public MessageTweaker
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
107 struct 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
122 {
124  std::string desc() const override { return "StripContextAttrs"; }
125 };
126 
127 // Strip a user-defined list of vars from all levels
128 struct 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
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
164 {
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
189 {
190  const wreport::Vartable* table;
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
199 {
200  const wreport::Vartable* table;
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
207 struct RoundVSS : public MessageTweaker
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
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 
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 
245 struct 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 
281 class msg_generator : public generator
282 {
283 public:
284  dba_err fill_message(dba_msg msg, bool mobile);
285 };
286 
287 
288 /* Message reading functions */
289 
290 class msg_vector : public dba_raw_consumer, public std::vector<dba_msgs>
291 {
292 public:
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 
310 template <typename T>
311 void 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:134
Definition: msg/tests.h:128
Definition: msg/tests.h:181
Definition: msg/tests.h:225
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:688
Definition: msg/tests.h:98
Definition: cmdline.h:18
Options to control message export.
Definition: exporter.h:24
Definition: msg/tests.h:214
Definition: msg/tests.h:121
Options to control message import.
Definition: importer.h:24
Vertical level or layer.
Definition: types.h:624
Definition: msg/tests.h:207
A bulletin that has been decoded and physically interpreted.
Definition: message.h:28
Definition: msg/tests.h:85
Definition: msg/tests.h:78
Definition: msg/tests.h:22
ImporterOptions with default constructor usable.
Definition: msg.h:25
Definition: shortcuts.h:11
static const ImporterOptions defaults
Default importer options.
Definition: importer.h:52
Definition: msg/tests.h:107
Definition: msg/tests.h:139
ExporterOptions with default constructor usable.
Definition: msg.h:38
Definition: msg/tests.h:188