IODA Bundle
test_select_iterator.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #include "odc_ecbuild_config.h"
12 
13 #include "eckit/eckit_config.h"
14 #include "eckit/config/Resource.h"
15 #include "eckit/system/SystemInfo.h"
16 #include "eckit/filesystem/PathName.h"
17 #include "eckit/testing/Test.h"
18 
19 #include "odc/Select.h"
20 #include "odc/Reader.h"
21 
22 #include "TemporaryFiles.h"
23 
24 #include <algorithm>
25 
26 using namespace eckit::testing;
27 
28 
29 // ------------------------------------------------------------------------------------------------------
30 
31 // TODO: Test with WHERE clause in SELECT?
32 
33 CASE("Test reading with iterators") {
34 SETUP("An odb file containing some pre-prepared data") {
35 
36  // Write (and clean up) a temporary ODB file
37  class TemporaryODB : public TemporaryFile {
38  public:
39  TemporaryODB() {
40  odc::Writer<> oda(path());
42 
43  writer->setNumberOfColumns(3);
44  writer->setColumn(0, "ifoo", odc::api::INTEGER);
45  writer->setColumn(1, "nbar", odc::api::REAL);
46  writer->setColumn(2, "string", odc::api::STRING);
47  writer->writeHeader();
48 
49  for (size_t i = 1; i <= 10; i++) {
50  writer->data()[0] = i; // col 0
51  writer->data()[1] = i; // col 1
52  ++writer;
53  }
54  }
55  };
56 
57  TemporaryODB tmpODB;
58 
59 #if __cplusplus > 199711L // C++11
60  SECTION("Test select iterator for each") {
61 
62  odc::Select oda("select * from \"" + tmpODB.path() + "\";", tmpODB.path());
63 
64  long count = 0;
65  std::for_each(oda.begin(), oda.end(), [&](odc::Select::row& row) {
66  ++count;
67  int64_t i = row[0];
68  double n = row[1];
69  EXPECT(i == count);
70  EXPECT(int(n) == count);
71  });
72 
73  EXPECT(count == 10);
74  }
75 
76 
77  SECTION("Test read iterator for_each") {
78 
79  odc::Reader oda(tmpODB.path());
80 
81  long count = 0;
82  std::for_each(oda.begin(), oda.end(), [&](odc::Reader::row& row) {
83  ++count;
84  int64_t i = row[0];
85  double n = row[1];
86  EXPECT(i == count);
87  EXPECT(int(n) == count);
88  });
89 
90  EXPECT(count == 10);
91  }
92 #endif
93 
94 
95  SECTION("Test select data in explicit loop") {
96 
97  odc::Select oda("select * from \"" + tmpODB.path() + "\";", tmpODB.path());
98 
99  int count = 0;
100  for (odc::Select::iterator it = oda.begin(); it != oda.end(); ++it) {
101  ++count;
102  EXPECT((*it)[0] == count);
103  EXPECT((*it)[1] == count);
104  }
105  EXPECT(count == 10);
106  }
107 
108 
109  SECTION("Test read data in explicit loop") {
110 
111  odc::Reader oda(tmpODB.path());
112 
113  int count = 0;
114  for (odc::Reader::iterator it = oda.begin(); it != oda.end(); ++it) {
115  ++count;
116  int i = (*it)[0];
117  double d = (*it)[1];
118  EXPECT(i == count);
119  EXPECT(d == count);
120  }
121  EXPECT(count == 10);
122  }
123 }}
124 
125 
126 CASE("Test bugfix 01, quote <<UnitTest problem fixed with p4 change 23687>>") {
127 
128  unsigned char REF_DATA[] = {
129  0x0,0x0,0x0,0x60,0x9b,0x5e,0x41,0x40, // 34.7391
130  0x0,0x0,0x0,0x20,0xcc,0xf,0x11,0xc0, // -4.26543
131  0x0,0x0,0x0,0x60,0x66,0x46,0x6b,0x40, // 218.2
132  0x0,0x0,0x0,0x0,0x77,0xc8,0x3b,0x40, // 27.7831
133  0x0,0x0,0x0,0x80,0xed,0xb,0xef,0xbf, // -0.970206
134  0x0,0x0,0x0,0xc0,0xcc,0xcc,0x6b,0x40, // 222.4
135  0x0,0x0,0x0,0x80,0x6,0xff,0x48,0x40, // 49.9924
136  0x0,0x0,0x0,0x80,0x81,0xec,0xeb,0x3f, // 0.87262
137  0x0,0x0,0x0,0x60,0x66,0x26,0x6b,0x40, // 217.2
138  0x0,0x0,0x0,0x0,0xc7,0x18,0x45,0x40, // 42.1936
139  0x0,0x0,0x0,0xc0,0x56,0x91,0xe7,0x3f, // 0.736492
140  0x0,0x0,0x0,0xc0,0xcc,0xec,0x6a,0x40, // 215.4
141  0x0,0x0,0x0,0x0,0xc7,0x18,0x45,0x40, // 42.1936
142  0x0,0x0,0x0,0xc0,0x56,0x91,0xe7,0xbf, // -0.736492
143  0x0,0x0,0x0,0xc0,0xcc,0xec,0x6a,0x40, // 215.4
144  0x0,0x0,0x0,0xa0,0xa5,0x7c,0x45,0x40, // 42.9738
145  0x0,0x0,0x0,0x40,0xc7,0x2,0xf8,0xbf, // -1.50068
146  0x0,0x0,0x0,0x60,0x66,0xe6,0x6a,0x40, // 215.2
147  0x0,0x0,0x0,0x60,0xf9,0xcb,0x45,0x40, // 43.5935
148  0x0,0x0,0x0,0x80,0x9,0x63,0x8,0xc0, // -3.04836
149  0x0,0x0,0x0,0x60,0x66,0xe6,0x6a,0x40, // 215.2
150  0x0,0x0,0x0,0x40,0xa3,0x22,0x36,0x40 // 22.1353
151  };
152 
153  if(eckit::system::SystemInfo::isBigEndian()) { // Swap the data on this big-endian box.
154  for (int i = 0; i < sizeof(REF_DATA) / 8; i++)
155  {
156  for (int j = 0; j < 4; j++)
157  std::swap(REF_DATA[i * 8 + j], REF_DATA[(i + 1) * 8 - 1 - j]);
158  //cout << *(reinterpret_cast<double *>(&REF_DATA[i * 8])) << std::endl;
159  }
160  }
161 
162  const double *OBSVALUE = reinterpret_cast<const double*>(REF_DATA);
163 
164  eckit::Resource<eckit::PathName> testDataPath("$TEST_DATA_DIRECTORY", "..");
165  std::stringstream ss_select;
166  ss_select << "select obsvalue from \"" << (testDataPath / "2000010106.odb") << "\";";
167 
168  odc::Select oda(ss_select.str());
169 
170  // Only consider the first section of the file...
171  size_t count = 0;
172  for (odc::Select::iterator it = oda.begin();
173  it != oda.end() && count < sizeof(REF_DATA)/sizeof(double);
174  ++it, ++count) {
175 
176 // eckit::Log::info() << "testBug01: it[" << count << "]=" << (*it)[0] << ", should be " << OBSVALUE[count] << std::endl;
177  EXPECT((*it)[0] == OBSVALUE[count] );
178  }
179 }
180 
181 
182 CASE("Test bugfix 02, quote <<UnitTest problem fixed with p4 change 23687>>") {
183 
184  std::vector<double> VALUE;
185  VALUE.push_back(1);
186  VALUE.push_back(2);
187  VALUE.push_back(3);
188 
189  class TemporaryODB : public TemporaryFile {
190  public:
191  TemporaryODB(const std::vector<double>& values) {
192  odc::Writer<> oda(path());
194 
195  writer->setNumberOfColumns(1);
196  writer->setColumn(0, "value", odc::api::INTEGER);
197  writer->writeHeader();
198 
199  for (size_t i = 0; i < values.size(); ++i) {
200  (*writer)[0] = values[i];
201  ++writer;
202  }
203  }
204  };
205 
206  // Write (and clean up) a temporary ODB file
207  TemporaryODB tmpODB(VALUE);
208 
209  odc::Select oda("select * from \"" + tmpODB.path() + "\";", tmpODB.path());
210 
211  size_t count = 0;
212  for (odc::Select::iterator it = oda.begin(); it != oda.end(); ++it, ++count) {
213 // eckit::Log::info() << "testBug02: it[" << count << "]=" << (*it)[0] << ", should be " << VALUE[count] << std::endl;
214  EXPECT((*it)[0] == VALUE[count]);
215  }
216 
217  EXPECT(count == 3);
218 }
219 
220 // ------------------------------------------------------------------------------------------------------
221 
222 int main(int argc, char* argv[]) {
223  return run_tests(argc, argv);
224 }
225 
void oda
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
eckit::Resource< eckit::PathName > testDataPath("$TEST_DATA_DIRECTORY", "..")
int main(int argc, char *argv[])
CASE("Test reading with iterators")