libdballe  8.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 
8 namespace wreport {
9 struct Vartable;
10 }
11 
12 namespace dballe {
13 namespace tests {
14 
15 impl::Messages read_msgs(const char* filename, Encoding type, const dballe::ImporterOptions& opts=dballe::ImporterOptions::defaults);
16 impl::Messages read_msgs(const char* filename, Encoding type, const std::string& opts);
17 impl::Messages read_msgs_csv(const char* filename);
18 
19 struct ActualMessage : public Actual<const Message&>
20 {
21  using Actual::Actual;
22 
23  void is_undef(const impl::Shortcut& shortcut) const;
24 };
25 
26 inline ActualMessage actual(const Message& message) { return ActualMessage(message); }
27 
28 std::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 
31 void track_different_msgs(const Message& msg1, const Message& msg2, const std::string& prefix);
32 void track_different_msgs(const impl::Messages& msgs1, const impl::Messages& msgs2, const std::string& prefix);
33 
34 extern const char* bufr_files[];
35 extern const char* crex_files[];
36 
37 const wreport::Var& want_var(const Message& msg, const impl::Shortcut& shortcut);
38 const wreport::Var& want_var(const Message& msg, wreport::Varcode code, const dballe::Level& lev, const dballe::Trange& tr);
39 
40 inline ActualVar actual_var(const Message& message, const impl::Shortcut& shortcut) { return ActualVar(want_var(message, shortcut)); }
41 inline 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 
43 void dump(const std::string& tag, const Message& msg, const std::string& desc="message");
44 void dump(const std::string& tag, const impl::Messages& msgs, const std::string& desc="message");
45 void dump(const std::string& tag, const wreport::Bulletin& bul, const std::string& desc="message");
46 void dump(const std::string& tag, const BinaryMessage& msg, const std::string& desc="message");
47 void 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 
60  ~MessageTweakers();
61  // Takes ownership of memory management
62  void add(MessageTweaker* tweak);
63  void apply(impl::Messages& msgs);
64 };
65 
66 namespace tweaks {
67 
68 // Strip attributes from all variables in a impl::Messages
69 struct StripAttrs : public MessageTweaker
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
78 struct StripQCAttrs : public StripAttrs
79 {
80  StripQCAttrs();
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
99 struct StripVars : public MessageTweaker
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;
113  RoundLegacyVars();
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
174 struct RoundVSS : public MessageTweaker
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 
209 struct TestCodec
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 
245 class msg_generator : public generator
246 {
247 public:
248  dba_err fill_message(dba_msg msg, bool mobile);
249 };
250 
251 
252 /* Message reading functions */
253 
254 class msg_vector : public dba_raw_consumer, public std::vector<dba_msgs>
255 {
256 public:
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 
274 template <typename T>
275 void 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:130
Definition: msg/tests.h:99
Definition: msg/tests.h:149
Definition: msg/tests.h:192
Definition: msg/tests.h:209
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:686
Definition: msg/tests.h:69
Definition: cmdline.h:18
Options to control message export.
Definition: exporter.h:24
Definition: msg/tests.h:181
Options to control message import.
Definition: importer.h:24
Vertical level or layer.
Definition: types.h:624
Definition: msg/tests.h:174
A bulletin that has been decoded and physically interpreted.
Definition: message.h:28
uint16_t Varcode
Definition: msg/tests.h:56
Definition: msg/tests.h:49
Definition: msg/tests.h:19
ImporterOptions with default constructor usable.
Definition: msg.h:25
Definition: shortcuts.h:11
static const ImporterOptions defaults
Default importer options.
Definition: importer.h:45
Definition: msg/tests.h:78
Definition: msg/tests.h:110
ExporterOptions with default constructor usable.
Definition: msg.h:38
Definition: msg/tests.h:156