libdballe  6.8
wr_export.h
1 #ifndef DBALLE_TESTS_WR_EXPORT_H
2 #define DBALLE_TESTS_WR_EXPORT_H
3 
4 namespace {
5 
6 // Common machinery for import -> export -> reimport tests
7 template<class B>
8 struct ReimportTest
9 {
10  typedef dballe::tests::MessageTweaker Tweaker;
11 
12  string fname;
13  Encoding type;
14  auto_ptr<Msgs> msgs1;
15  auto_ptr<Msgs> msgs2;
16  auto_ptr<Bulletin> exported;
17  msg::Importer::Options input_opts;
18  msg::Exporter::Options output_opts;
19  vector<Tweaker*> tweaks;
20  vector<Tweaker*> ecmwf_tweaks;
21  vector<Tweaker*> wmo_tweaks;
22  bool do_ecmwf_tweaks;
23  bool do_wmo_tweaks;
24  bool do_ignore_context_attrs;
25  bool do_round_geopotential;
26  bool verbose;
27 
28  void clear_tweaks()
29  {
30  for (typename vector<Tweaker*>::iterator i = tweaks.begin();
31  i != tweaks.end(); ++i)
32  delete *i;
33  tweaks.clear();
34  for (typename vector<Tweaker*>::iterator i = ecmwf_tweaks.begin();
35  i != ecmwf_tweaks.end(); ++i)
36  delete *i;
37  ecmwf_tweaks.clear();
38  for (typename vector<Tweaker*>::iterator i = wmo_tweaks.begin();
39  i != wmo_tweaks.end(); ++i)
40  delete *i;
41  wmo_tweaks.clear();
42  }
43 
44  ReimportTest(const std::string& fname, Encoding type=BUFR)
45  : fname(fname), type(type), do_ecmwf_tweaks(false), do_wmo_tweaks(false),
46  do_ignore_context_attrs(false), do_round_geopotential(false), verbose(false)
47  {
48  ecmwf_tweaks.push_back(new StripQCAttrs());
49  wmo_tweaks.push_back(new RoundLegacyVars());
50  }
51  ~ReimportTest()
52  {
53  clear_tweaks();
54  }
55 
56  void do_test(const dballe::tests::Location& loc, const char* tname1, const char* tname2=NULL)
57  {
58  if (verbose) cerr << "Running test " << loc.locstr() << endl;
59 
60  std::auto_ptr<msg::Importer> importer(msg::Importer::create(type, input_opts));
61 
62  // Import
63  if (verbose) cerr << "Importing " << fname << " " << input_opts.to_string() << endl;
64  msgs1 = inner_read_msgs_opts(fname.c_str(), type, input_opts);
65  inner_ensure(msgs1->size() > 0);
66 
67  // Run tweaks
68  for (typename vector<Tweaker*>::iterator i = tweaks.begin(); i != tweaks.end(); ++i)
69  {
70  if (verbose) cerr << "Running tweak " << (*i)->desc() << endl;
71  (*i)->tweak(*msgs1);
72  }
73  if (do_ecmwf_tweaks)
74  for (typename vector<Tweaker*>::iterator i = ecmwf_tweaks.begin(); i != ecmwf_tweaks.end(); ++i)
75  {
76  if (verbose) cerr << "Running ecmwf tweak " << (*i)->desc() << endl;
77  (*i)->tweak(*msgs1);
78  }
79  if (do_wmo_tweaks)
80  for (typename vector<Tweaker*>::iterator i = wmo_tweaks.begin(); i != wmo_tweaks.end(); ++i)
81  {
82  if (verbose) cerr << "Running wmo tweak " << (*i)->desc() << endl;
83  (*i)->tweak(*msgs1);
84  }
85 
86  // Export
87  exported.reset(B::create().release());
88  try {
89  if (tname1 != NULL)
90  output_opts.template_name = tname1;
91  else
92  output_opts.template_name.clear();
93  if (verbose) cerr << "Exporting " << output_opts.to_string() << endl;
94  std::auto_ptr<msg::Exporter> exporter(msg::Exporter::create(type, output_opts));
95  exporter->to_bulletin(*msgs1, *exported);
96  } catch (std::exception& e) {
97  dballe::tests::dump("bul1", *exported);
98  dballe::tests::dump("msg1", *msgs1);
99  throw tut::failure(loc.msg(string("exporting to bulletin (first template): ") + e.what()));
100  }
101 
102  // Encode
103  Rawmsg rawmsg;
104  try {
105  exported->encode(rawmsg);
106  //exporter->to_rawmsg(*msgs1, rawmsg);
107  } catch (std::exception& e) {
108  dballe::tests::dump("bul1", *exported);
109  dballe::tests::dump("msg1", *msgs1);
110  throw tut::failure(loc.msg(string("encoding to rawmsg (first template): ") + e.what()));
111  }
112 
113  // Import again
114  if (verbose) cerr << "Reimporting " << input_opts.to_string() << endl;
115  msgs2.reset(new Msgs);
116  try {
117  importer->from_rawmsg(rawmsg, *msgs2);
118  } catch (std::exception& e) {
119  dballe::tests::dump("msg1", *msgs1);
120  dballe::tests::dump("msg", rawmsg);
121  throw tut::failure(loc.msg(string("importing from rawmsg (first template): ") + e.what()));
122  }
123 
124  auto_ptr<Msgs> msgs3;
125  if (tname2)
126  {
127  // Export
128  auto_ptr<Bulletin> bulletin(B::create());
129  try {
130  output_opts.template_name = tname2;
131  if (verbose) cerr << "Reexporting " << output_opts.to_string() << endl;
132  std::auto_ptr<msg::Exporter> exporter(msg::Exporter::create(type, output_opts));
133  exporter->to_bulletin(*msgs2, *bulletin);
134  } catch (std::exception& e) {
135  dballe::tests::dump("bul2", *bulletin);
136  dballe::tests::dump("msg2", *msgs1);
137  throw tut::failure(loc.msg(string("exporting to bulletin (second template): ") + e.what()));
138  }
139 
140  // Encode
141  rawmsg.clear();
142  try {
143  bulletin->encode(rawmsg);
144  //exporter->to_rawmsg(*msgs1, rawmsg);
145  } catch (std::exception& e) {
146  dballe::tests::dump("bul2", *bulletin);
147  dballe::tests::dump("msg2", *msgs1);
148  throw tut::failure(loc.msg(string("encoding to rawmsg (second template): ") + e.what()));
149  }
150 
151  // Import again
152  msgs3.reset(new Msgs);
153  try {
154  if (verbose) cerr << "Reimporting " << input_opts.to_string() << endl;
155  importer->from_rawmsg(rawmsg, *msgs3);
156  } catch (std::exception& e) {
157  dballe::tests::dump("msg2", *msgs2);
158  dballe::tests::dump("raw2", rawmsg);
159  throw tut::failure(loc.msg(string("importing from rawmsg (first template): ") + e.what()));
160  }
161  } else
162  msgs3 = msgs2;
163 
164 #if 0
165  // Run tweaks
166  for (typename vector<Tweaker*>::iterator i = tweaks.begin(); i != tweaks.end(); ++i)
167  (*i)->clean_second(*msgs3);
168 #endif
169  if (do_ignore_context_attrs)
170  {
171  StripContextAttrs sca;
172  sca.tweak(*msgs1);
173  }
174  if (do_round_geopotential)
175  {
176  RoundGeopotential rg;
177  rg.tweak(*msgs1);
178  rg.tweak(*msgs3);
179  }
180 
181  // Compare
182  stringstream str;
183  notes::Collect c(str);
184  int diffs = msgs1->diff(*msgs3);
185  if (diffs)
186  {
187  dballe::tests::dump("msg1", *msgs1);
188  if (msgs2.get())
189  dballe::tests::dump("msg2", *msgs2);
190  dballe::tests::dump("msg3", *msgs3);
191  dballe::tests::dump("msg", rawmsg);
192  dballe::tests::dump("diffs", str.str(), "details of differences");
193  throw tut::failure(loc.msg(str::fmtf("found %d differences", diffs)));
194  }
195  }
196 
197 #define inner_do_test(name, ...) do_test(wibble::tests::Location(loc, __FILE__, __LINE__, name), __VA_ARGS__)
198  void do_ecmwf(const dballe::tests::Location& loc, const char* template_type="synop")
199  {
200  string ecmwf_template_name = string(template_type) + "-ecmwf";
201  string wmo_template_name = string(template_type) + "-wmo";
202  do_wmo_tweaks = false;
203 
204  input_opts.simplified = true;
205  do_round_geopotential = false;
206 
207  do_ecmwf_tweaks = false;
208  inner_do_test("simp-ecmwf-through-auto", NULL);
209  inner_do_test("simp-ecmwf-through-ecmwf", ecmwf_template_name.c_str());
210 
211  do_ecmwf_tweaks = true;
212  do_round_geopotential = true;
213  inner_do_test("simp-ecmwf-through-wmo", wmo_template_name.c_str());
214 
215  input_opts.simplified = false;
216  do_round_geopotential = false;
217 
218  do_ecmwf_tweaks = false;
219  inner_do_test("real-ecmwf-through-auto", NULL);
220  inner_do_test("real-ecmwf-through-ecmwf", ecmwf_template_name.c_str());
221 
222  do_ecmwf_tweaks = true;
223  do_round_geopotential = true;
224  inner_do_test("real-ecmwf-through-wmo", wmo_template_name.c_str());
225  }
226  void do_wmo(const dballe::tests::Location& loc, const char* template_type="synop")
227  {
228  string ecmwf_template_name = string(template_type) + "-ecmwf";
229  string wmo_template_name = string(template_type) + "-wmo";
230  do_ecmwf_tweaks = false;
231 
232  input_opts.simplified = true;
233  do_round_geopotential = false;
234 
235  do_wmo_tweaks = false;
236  inner_do_test("simp-wmo-through-auto", NULL);
237  inner_do_test("simp-wmo-through-wmo", wmo_template_name.c_str());
238 
239  do_wmo_tweaks = true;
240  do_ignore_context_attrs = true;
241  do_round_geopotential = true;
242  inner_do_test("simp-wmo-through-ecmwf", ecmwf_template_name.c_str());
243  do_ignore_context_attrs = false;
244 
245  input_opts.simplified = false;
246  do_round_geopotential = false;
247 
248  do_wmo_tweaks = false;
249  inner_do_test("real-wmo-through-auto", NULL);
250  inner_do_test("real-wmo-through-wmo", wmo_template_name.c_str());
251 
252  // There doesn't seem much sense testing this at the moment
253  //do_tweaks = true;
254  //inner_do_test("real-wmo-through-ecmwf", ecmwf_template_name.c_str());
255  }
256 #undef inner_do_test
257 };
258 typedef ReimportTest<BufrBulletin> BufrReimportTest;
259 typedef ReimportTest<CrexBulletin> CrexReimportTest;
260 #define run_test(obj, meth, ...) obj.meth(wibble::tests::Location(__FILE__, __LINE__, (obj.fname + " " #__VA_ARGS__).c_str()), __VA_ARGS__)
261 
262 }
263 
264 #endif