wip(step097): checkpoint B fixes pending native release pairing
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
using namespace mbgl;
|
||||
@@ -63,7 +64,7 @@ struct Plane {
|
||||
std::vector<uint8_t> bytes;
|
||||
};
|
||||
|
||||
std::vector<uint8_t> qbin(uint64_t validTime, bool scalar = false) {
|
||||
std::vector<uint8_t> qbin(uint64_t validTime, bool scalar = false, uint8_t validity = 0x0f) {
|
||||
std::vector<Plane> planes;
|
||||
if (scalar)
|
||||
planes.push_back({99, 77, 0, 3, 0, 0, {1, 2, 3, 4}});
|
||||
@@ -71,7 +72,15 @@ std::vector<uint8_t> qbin(uint64_t validTime, bool scalar = false) {
|
||||
planes.push_back({1, 1, 1, 1, 1, 1, {1, 0, 2, 0, 3, 0, 4, 0}});
|
||||
planes.push_back({2, 1, 1, 1, 1, 2, {5, 0, 6, 0, 7, 0, 8, 0}});
|
||||
}
|
||||
planes.push_back({3, 0, 0, 6, 3, 0, {15}});
|
||||
for (auto& plane : planes) {
|
||||
if (plane.type == 6) continue;
|
||||
for (size_t cell = 0; cell < 4; ++cell) {
|
||||
if (validity & (1u << cell)) continue;
|
||||
const size_t bytesPerCell = plane.type == 1 || plane.type == 2 ? 2 : plane.type == 5 ? 4 : 1;
|
||||
std::fill_n(plane.bytes.begin() + cell * bytesPerCell, bytesPerCell, uint8_t{0});
|
||||
}
|
||||
}
|
||||
planes.push_back({3, 0, 0, 6, 3, 0, {validity}});
|
||||
std::sort(planes.begin(), planes.end(), [](const Plane& a, const Plane& b) { return a.semantic < b.semantic; });
|
||||
size_t payloadLength = 0;
|
||||
for (const auto& plane : planes) payloadLength = aligned16(payloadLength + plane.bytes.size());
|
||||
@@ -117,6 +126,11 @@ std::vector<uint8_t> qbin(uint64_t validTime, bool scalar = false) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void recomputeQbinCrc(std::vector<uint8_t>& bytes) {
|
||||
u32(bytes, 76, 0);
|
||||
u32(bytes, 76, crc(bytes));
|
||||
}
|
||||
|
||||
particle::ingress::EncodedFieldRuntimeMetadata metadata(const char* id, uint64_t generation, uint64_t version = 1) {
|
||||
return {id, generation, version};
|
||||
}
|
||||
@@ -296,6 +310,62 @@ TEST(Source, RasterArrayV4HostApiRejectsKeepPublicProjectionStable) {
|
||||
expectNoPartialMutation();
|
||||
}
|
||||
|
||||
TEST(Source, RasterArrayV4RejectsNumericOverflowBeforeReplacingAcceptedRevision) {
|
||||
style::RasterArraySource source{"v4-numeric-transaction"};
|
||||
submit(source, "wind", "wind", Base, 1);
|
||||
submit(source, "wind", "wind", Base + Hour, 2);
|
||||
source.setParticleBinding({particle::ParticleBindingMode::VectorComponents,
|
||||
"wind",
|
||||
{1, 1, particle::FieldComponent::UEast},
|
||||
{2, 1, particle::FieldComponent::VNorth},
|
||||
{},
|
||||
1});
|
||||
ASSERT_TRUE(source.setRequestedForecastTime(Base + Hour / 2));
|
||||
const auto baseline = source.resolveParticleProjection();
|
||||
ASSERT_TRUE(baseline.accepted());
|
||||
const auto materialized = source.impl().v4RendererState.particle;
|
||||
ASSERT_TRUE(materialized);
|
||||
const auto countersBefore = particle::rendererDebugCounterSnapshot();
|
||||
|
||||
auto overflowing = qbin(Base + Hour);
|
||||
const size_t firstPlaneDescriptor = Header;
|
||||
f32(overflowing, firstPlaneDescriptor + 4, std::numeric_limits<float>::max());
|
||||
f32(overflowing, firstPlaneDescriptor + 8, std::numeric_limits<float>::max());
|
||||
recomputeQbinCrc(overflowing);
|
||||
EXPECT_EQ(source.submitEncodedField("wind", metadata("wind", 3, 2), windContract(), overflowing),
|
||||
style::RasterArrayEncodedFieldSubmitResult::RejectedContract);
|
||||
|
||||
const auto after = source.resolveParticleProjection();
|
||||
ASSERT_TRUE(after.accepted());
|
||||
expectSameParticleProjection(*baseline.projection, *after.projection);
|
||||
EXPECT_EQ(after.projection->t1Frame, baseline.projection->t1Frame);
|
||||
EXPECT_EQ(source.impl().v4RendererState.particle, materialized);
|
||||
const auto countersAfter = particle::rendererDebugCounterSnapshot();
|
||||
EXPECT_EQ(countersAfter.v4ProjectionMaterialize, countersBefore.v4ProjectionMaterialize);
|
||||
EXPECT_EQ(countersAfter.fieldTextureUpload, countersBefore.fieldTextureUpload);
|
||||
}
|
||||
|
||||
TEST(Source, RasterArrayV4KeepsValidityZeroCellsAsLegalNoData) {
|
||||
style::RasterArraySource source{"v4-validity-nodata"};
|
||||
EXPECT_EQ(source.submitEncodedField("wind", metadata("wind", 1), windContract(), qbin(Base, false, 0x0e)),
|
||||
style::RasterArrayEncodedFieldSubmitResult::AcceptedInserted);
|
||||
submit(source, "wind", "wind", Base + Hour, 2);
|
||||
source.setParticleBinding({particle::ParticleBindingMode::VectorComponents,
|
||||
"wind",
|
||||
{1, 1, particle::FieldComponent::UEast},
|
||||
{2, 1, particle::FieldComponent::VNorth},
|
||||
{},
|
||||
1});
|
||||
ASSERT_TRUE(source.setRequestedForecastTime(Base + Hour / 2));
|
||||
const auto projection = source.resolveParticleProjection();
|
||||
ASSERT_TRUE(projection.accepted());
|
||||
const auto snapshots = particle::materializeParticleProjection(*projection.projection);
|
||||
ASSERT_TRUE(snapshots);
|
||||
ASSERT_EQ(snapshots->t0->valid.size(), 4u);
|
||||
EXPECT_EQ(snapshots->t0->valid[0], 0);
|
||||
EXPECT_EQ(snapshots->t0->valid[1], 1);
|
||||
}
|
||||
|
||||
TEST(Source, RasterArrayV4HostApiResolvesIndependentBindingsFromOneForecastClock) {
|
||||
style::RasterArraySource source{"v4"};
|
||||
submit(source, "wind", "wind", Base, 1);
|
||||
|
||||
Reference in New Issue
Block a user