1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/*
* (C) Copyright 1996- ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
* In applying this licence, ECMWF does not waive the privileges and immunities
* granted to it by virtue of its status as an intergovernmental organisation nor
* does it submit to any jurisdiction.
*/
#include <algorithm>
#include <map>
#include <random>
#include <string>
#include <vector>
#include "eckit/testing/Test.h"
#include "metkit/mars/MarsRequest.h"
#include "metkit/mars/Type.h"
namespace metkit::mars::test {
struct Expected {
const std::string verb;
std::map<std::string, std::vector<std::string>> keyvalue;
};
using Sequence = std::vector<unsigned long>;
Sequence make_random_sequence(Sequence::value_type min, Sequence::value_type max, Sequence::size_type N) {
static std::mt19937 gen{std::random_device{}()};
static std::uniform_int_distribution<Sequence::value_type> dist(min, max);
Sequence s(N);
std::generate(s.begin(), s.end(), [&] { return dist(gen); });
return s;
}
Sequence make_power_sequence(Sequence::value_type min, Sequence::value_type max) {
Sequence s;
for (auto i = min; i <= max; i *= 2) {
s.push_back(i);
}
return s;
}
void expect_mars(const std::string& text, const Expected& expected, bool strict = false) {
auto r = MarsRequest::parse(text, strict);
EXPECT_EQUAL(expected.verb, r.verb());
for (const auto& kv : expected.keyvalue) {
auto v = r.values(kv.first);
if (kv.first == "grid") {
EXPECT(kv.second.size() == 1 && v.size() == 1 && v[0] == kv.second[0]);
continue;
}
EXPECT_EQUAL(kv.second, kv.second);
}
}
// -----------------------------------------------------------------------------
CASE("grid: regular Gaussian grids") {
const Sequence F{16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 200, 256, 320,
400, 512, 576, 640, 800, 912, 1024, 1280, 1600, 2000, 2560, 4000, 8000};
const auto Fn = [](const auto& other) {
auto seq = make_random_sequence(2, 8000, 20);
seq.insert(seq.end(), other.begin(), other.end());
return seq;
}(F);
for (const auto& n : Fn) {
// known grids are expanded correctly (pattern matching doesn't work reliably here)
Expected expected{"retrieve", {{"grid", {"F" + std::to_string(n)}}}};
if (std::find(F.begin(), F.end(), n) == F.end()) {
expected.keyvalue.clear();
}
expect_mars("ret, date=-1, grid=F" + std::to_string(n), expected);
expect_mars("ret, date=-1, grid=f" + std::to_string(n), expected);
expect_mars("ret, date=-1, grid=" + std::to_string(n), expected);
}
}
// -----------------------------------------------------------------------------
CASE("grid: octahedral Gaussian grids") {
for (const auto& n : make_random_sequence(2, 8000, 20 /*reduced number of tests*/)) {
const Expected expected{"retrieve", {{"grid", {"O" + std::to_string(n)}}}};
expect_mars("ret, date=-1, grid=O" + std::to_string(n), expected);
expect_mars("ret, date=-1, grid=o" + std::to_string(n), expected);
}
}
// -----------------------------------------------------------------------------
CASE("grid: reduced classical Gaussian grids") {
for (const auto& n : Sequence{32, 48, 64, 80, 96, 128, 160, 200, 256, 320, 400, 512, 640, 800, 1024, 1280, 8000}) {
const Expected expected{"retrieve", {{"grid", {"N" + std::to_string(n)}}}};
expect_mars("ret, date=-1, grid=N" + std::to_string(n), expected);
expect_mars("ret, date=-1, grid=n" + std::to_string(n), expected);
}
}
// -----------------------------------------------------------------------------
CASE("grid: HEALPix grids") {
for (const auto& n : make_power_sequence(2, 8192)) {
const Expected expected{"retrieve", {{"grid", {"H" + std::to_string(n)}}}};
expect_mars("ret, date=-1, grid=H" + std::to_string(n), expected);
expect_mars("ret, date=-1, grid=h" + std::to_string(n), expected);
}
}
// -----------------------------------------------------------------------------
} // namespace metkit::mars::test
int main(int argc, char** argv) {
return eckit::testing::run_tests(argc, argv);
}
|