mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-16 15:50:11 +00:00
222 lines
8.5 KiB
C++
222 lines
8.5 KiB
C++
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
|
|
#include "Telemetry/LocationTelemetryCodec.h"
|
|
|
|
namespace {
|
|
|
|
int passed = 0;
|
|
int failures = 0;
|
|
|
|
#define CHECK(expr) \
|
|
do { \
|
|
if (expr) { \
|
|
++passed; \
|
|
} else { \
|
|
++failures; \
|
|
std::cerr << "FAIL line " << __LINE__ << ": " #expr << '\n'; \
|
|
} \
|
|
} while (false)
|
|
|
|
// Generated by Columba's org.msgpack.core 0.9.10 codec at Android commit
|
|
// 7946af5ab61c53fad4aaa54d0555a45eb779a040.
|
|
constexpr uint8_t CANONICAL[] = {
|
|
0x84,
|
|
0xa5, 'c', 'e', 'a', 's', 'e', 0xc3,
|
|
0xa7, 'e', 'x', 'p', 'i', 'r', 'e', 's',
|
|
0xcf, 0x00, 0x00, 0x01, 0x8b, 0xcf, 0xe5, 0x68, 0x7b,
|
|
0xac, 'a', 'p', 'p', 'r', 'o', 'x', 'R', 'a', 'd', 'i', 'u', 's',
|
|
0xcc, 0xfa,
|
|
0xa2, 't', 's',
|
|
0xcf, 0x00, 0x00, 0x01, 0x8b, 0xcf, 0xe5, 0x69, 0xc8,
|
|
};
|
|
|
|
Telemetry::CustomLocationMeta expectedMeta() {
|
|
Telemetry::CustomLocationMeta value{};
|
|
value.has_cease = true;
|
|
value.cease = true;
|
|
value.has_expires = true;
|
|
value.expires_millis = 1700000000123ULL;
|
|
value.has_approx_radius = true;
|
|
value.approx_radius_meters = 250;
|
|
value.has_timestamp = true;
|
|
value.timestamp_millis = 1700000000456ULL;
|
|
return value;
|
|
}
|
|
|
|
bool equalMeta(const Telemetry::CustomLocationMeta& left,
|
|
const Telemetry::CustomLocationMeta& right) {
|
|
return left.has_cease == right.has_cease && left.cease == right.cease &&
|
|
left.has_expires == right.has_expires &&
|
|
left.expires_millis == right.expires_millis &&
|
|
left.has_approx_radius == right.has_approx_radius &&
|
|
left.approx_radius_meters == right.approx_radius_meters &&
|
|
left.has_timestamp == right.has_timestamp &&
|
|
left.timestamp_millis == right.timestamp_millis;
|
|
}
|
|
|
|
void decodesAndEncodesCanonicalColumbaMetadata() {
|
|
Telemetry::CustomLocationMeta decoded{};
|
|
CHECK(Telemetry::decodeCustomLocationMeta(CANONICAL, sizeof(CANONICAL), decoded) ==
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(equalMeta(decoded, expectedMeta()));
|
|
|
|
uint8_t encoded[128]{};
|
|
std::size_t written = 0;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
expectedMeta(), encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(written == sizeof(CANONICAL));
|
|
CHECK(std::memcmp(encoded, CANONICAL, sizeof(CANONICAL)) == 0);
|
|
}
|
|
|
|
void distinguishesAbsentFalseTrueAndEmpty() {
|
|
constexpr uint8_t explicit_false[] = {
|
|
0x81, 0xa5, 'c', 'e', 'a', 's', 'e', 0xc2,
|
|
};
|
|
Telemetry::CustomLocationMeta decoded{};
|
|
CHECK(Telemetry::decodeCustomLocationMeta(
|
|
explicit_false, sizeof(explicit_false), decoded) ==
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(decoded.has_cease && !decoded.cease);
|
|
|
|
uint8_t encoded[32]{};
|
|
std::size_t written = 99;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
decoded, encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(written == sizeof(explicit_false));
|
|
CHECK(std::memcmp(encoded, explicit_false, sizeof(explicit_false)) == 0);
|
|
|
|
Telemetry::CustomLocationMeta empty{};
|
|
written = 99;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
empty, encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::EMPTY);
|
|
CHECK(written == 0);
|
|
}
|
|
|
|
void acceptsReorderedKeysAndSkipsUnknownNestedValues() {
|
|
constexpr uint8_t packed[] = {
|
|
0x83,
|
|
0xa2, 't', 's', 0xcd, 0x03, 0xe8,
|
|
0xa7, 'u', 'n', 'k', 'n', 'o', 'w', 'n',
|
|
0x92, 0x01, 0x81, 0xa1, 'x', 0xc3,
|
|
0xa5, 'c', 'e', 'a', 's', 'e', 0xc3,
|
|
};
|
|
Telemetry::CustomLocationMeta decoded{};
|
|
CHECK(Telemetry::decodeCustomLocationMeta(packed, sizeof(packed), decoded) ==
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(decoded.has_timestamp && decoded.timestamp_millis == 1000);
|
|
CHECK(decoded.has_cease && decoded.cease);
|
|
CHECK(!decoded.has_expires && !decoded.has_approx_radius);
|
|
}
|
|
|
|
void rejectsMalformedAndPreservesOutput() {
|
|
constexpr uint8_t json[] = {'{', '"', 'c', 'e', 'a', 's', 'e', '"', ':', 't', 'r', 'u', 'e', '}'};
|
|
constexpr uint8_t wrong_cease_type[] = {
|
|
0x81, 0xa5, 'c', 'e', 'a', 's', 'e', 0x01,
|
|
};
|
|
constexpr uint8_t negative_expiry[] = {
|
|
0x81, 0xa7, 'e', 'x', 'p', 'i', 'r', 'e', 's', 0xff,
|
|
};
|
|
constexpr uint8_t duplicate_cease[] = {
|
|
0x82,
|
|
0xa5, 'c', 'e', 'a', 's', 'e', 0xc2,
|
|
0xa5, 'c', 'e', 'a', 's', 'e', 0xc3,
|
|
};
|
|
constexpr uint8_t too_many_entries[] = {0xde, 0x00, 0x11};
|
|
constexpr uint8_t huge_string[] = {0x81, 0xdb, 0xff, 0xff, 0xff, 0xff};
|
|
constexpr uint8_t timestamp_above_columba_long[] = {
|
|
0x81, 0xa2, 't', 's',
|
|
0xcf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
constexpr uint8_t expiry_above_columba_long[] = {
|
|
0x81, 0xa7, 'e', 'x', 'p', 'i', 'r', 'e', 's',
|
|
0xcf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
constexpr uint8_t radius_above_columba_int[] = {
|
|
0x81,
|
|
0xac, 'a', 'p', 'p', 'r', 'o', 'x', 'R', 'a', 'd', 'i', 'u', 's',
|
|
0xce, 0x80, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
struct Case { const uint8_t* data; std::size_t size; };
|
|
const Case cases[] = {
|
|
{json, sizeof(json)},
|
|
{wrong_cease_type, sizeof(wrong_cease_type)},
|
|
{negative_expiry, sizeof(negative_expiry)},
|
|
{duplicate_cease, sizeof(duplicate_cease)},
|
|
{too_many_entries, sizeof(too_many_entries)},
|
|
{huge_string, sizeof(huge_string)},
|
|
{timestamp_above_columba_long, sizeof(timestamp_above_columba_long)},
|
|
{expiry_above_columba_long, sizeof(expiry_above_columba_long)},
|
|
{radius_above_columba_int, sizeof(radius_above_columba_int)},
|
|
};
|
|
const auto sentinel = expectedMeta();
|
|
for (const auto& item : cases) {
|
|
auto output = sentinel;
|
|
CHECK(Telemetry::decodeCustomLocationMeta(item.data, item.size, output) ==
|
|
Telemetry::CustomMetaResult::MALFORMED);
|
|
CHECK(equalMeta(output, sentinel));
|
|
}
|
|
|
|
for (std::size_t size = 0; size < sizeof(CANONICAL); ++size) {
|
|
auto output = sentinel;
|
|
CHECK(Telemetry::decodeCustomLocationMeta(CANONICAL, size, output) !=
|
|
Telemetry::CustomMetaResult::OK);
|
|
CHECK(equalMeta(output, sentinel));
|
|
}
|
|
|
|
uint8_t trailing[sizeof(CANONICAL) + 1]{};
|
|
std::memcpy(trailing, CANONICAL, sizeof(CANONICAL));
|
|
trailing[sizeof(CANONICAL)] = 0xc0;
|
|
auto output = sentinel;
|
|
CHECK(Telemetry::decodeCustomLocationMeta(
|
|
trailing, sizeof(trailing), output) ==
|
|
Telemetry::CustomMetaResult::MALFORMED);
|
|
CHECK(equalMeta(output, sentinel));
|
|
}
|
|
|
|
void rejectsOutboundValuesOutsideColumbaSignedDomains() {
|
|
uint8_t encoded[128]{};
|
|
std::size_t written = 0;
|
|
|
|
Telemetry::CustomLocationMeta meta{};
|
|
meta.has_timestamp = true;
|
|
meta.timestamp_millis = -1;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
meta, encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::INVALID_ARGUMENT);
|
|
|
|
meta = Telemetry::CustomLocationMeta{};
|
|
meta.has_expires = true;
|
|
meta.expires_millis = -1;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
meta, encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::INVALID_ARGUMENT);
|
|
|
|
meta = Telemetry::CustomLocationMeta{};
|
|
meta.has_approx_radius = true;
|
|
meta.approx_radius_meters = -1;
|
|
CHECK(Telemetry::encodeCustomLocationMeta(
|
|
meta, encoded, sizeof(encoded), written) ==
|
|
Telemetry::CustomMetaResult::INVALID_ARGUMENT);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main() {
|
|
decodesAndEncodesCanonicalColumbaMetadata();
|
|
distinguishesAbsentFalseTrueAndEmpty();
|
|
acceptsReorderedKeysAndSkipsUnknownNestedValues();
|
|
rejectsMalformedAndPreservesOutput();
|
|
rejectsOutboundValuesOutsideColumbaSignedDomains();
|
|
std::cout << "custom location metadata codec: " << passed << " passed, "
|
|
<< failures << " failed\n";
|
|
return failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|