compound_type: implement validate()

Validate the number of present components, then validate each of them.
A unit test for both the prefix and full instances is also added.
This commit is contained in:
Botond Dénes
2020-05-06 12:40:37 +03:00
parent 3e400cf54e
commit 84e38ae358
2 changed files with 43 additions and 3 deletions

View File

@@ -29,7 +29,6 @@
#include <boost/range/adaptor/transformed.hpp>
#include "utils/serialization.hh"
#include <seastar/util/backtrace.hh>
#include "unimplemented.hh"
enum class allow_prefixes { no, yes };
@@ -225,8 +224,18 @@ public:
return begin(v) == end(v);
}
void validate(bytes_view v) const {
// FIXME: implement
warn(unimplemented::cause::VALIDATION);
std::vector<bytes_view> values(begin(v), end(v));
if (AllowPrefixes == allow_prefixes::no && values.size() < _types.size()) {
throw marshal_exception(fmt::format("compound::validate(): non-prefixable compound cannot be a prefix"));
}
if (values.size() > _types.size()) {
throw marshal_exception(fmt::format("compound::validate(): cannot have more values than types, have {} values but only {} types",
values.size(), _types.size()));
}
for (size_t i = 0; i != values.size(); ++i) {
//FIXME: is it safe to assume internal serialization-format format?
_types[i]->validate(values[i], cql_serialization_format::internal());
}
}
bool equal(bytes_view v1, bytes_view v2) const {
if (_byte_order_equal) {

View File

@@ -370,3 +370,34 @@ BOOST_AUTO_TEST_CASE(test_composite_validity) {
BOOST_REQUIRE_EQUAL(is_valid({'\x00', '\x01', 'a'}), false);
BOOST_REQUIRE_EQUAL(is_valid({'\x00', '\x02', 'a'}), false);
}
BOOST_AUTO_TEST_CASE(test_full_compound_validity) {
const auto c = compound_type<allow_prefixes::no>({byte_type, utf8_type});
auto validate = [&] (bytes b) {
c.validate(b);
};
BOOST_REQUIRE_NO_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b'})); // full
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a'}), marshal_exception); // not enough bytes
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', -1}), marshal_exception); // invalid utf8 string
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0}), marshal_exception); // too few components (prefix)
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b', '\x00', '\x01', 'a'}), marshal_exception); // to many components
BOOST_REQUIRE_THROW(validate({'\x00', '\x02', 'a', 'b', '\x00', '\x01', 0}), marshal_exception); // wrong order of components
}
BOOST_AUTO_TEST_CASE(test_prefix_compound_validity) {
const auto c = compound_type<allow_prefixes::yes>({byte_type, utf8_type});
auto validate = [&] (bytes b) {
c.validate(b);
};
BOOST_REQUIRE_NO_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b'})); // full
BOOST_REQUIRE_NO_THROW(validate({'\x00', '\x01', 0})); // too few components (prefix)
BOOST_REQUIRE_NO_THROW(validate({})); // empty
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a'}), marshal_exception); // not enough bytes
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', -1}), marshal_exception); // invalid utf8 string
BOOST_REQUIRE_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b', '\x00', '\x01', 'a'}), marshal_exception); // to many components
BOOST_REQUIRE_THROW(validate({'\x00', '\x02', 'a', 'b', '\x00', '\x01', 0}), marshal_exception); // wrong order of components
}