Files
vision-anti-pinch/tests/session_test.cpp
T

67 lines
4.0 KiB
C++

#include "inference_session.hpp"
#include "camera_pipeline.hpp"
#include <chrono>
#include <cmath>
#include <iostream>
#include <stdexcept>
namespace cms {
std::uint64_t monotonicNs() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
}
using namespace cms;
void check(bool condition,char const* message){if(!condition)throw std::runtime_error(message);}
template<class F> void rejects(F f){bool failed=false;try{f();}catch(std::exception const&){failed=true;}check(failed,"Expected rejection");}
int main(int argc,char** argv)try {
if(argc!=2)return 2;
std::filesystem::path root=argv[1];
PipelineConfig c;c.record_session=root/"recorded";c.engines=root;c.door_mask=root/"mask.json";
c.camera.width=64;c.camera.height=48;c.detector_confidence=.42;
std::ofstream(c.door_mask)<<"{}";
for(auto name:{"yolo11s.engine","rtmw_l_384.engine"})std::ofstream(root/name)<<"fixture";
auto im=std::make_shared<BgrImage>();im->width=64;im->height=48;im->stride=200;
im->pixels.resize(9600);
for(int y=0;y<48;++y)for(int x=0;x<192;++x)im->pixels[y*200+x]=32+x/3+y%4;
FrameResult r;r.image=im;r.frame_index=3;r.capture.frame_index=3;r.capture.driver_sequence=42;
r.capture.capture_monotonic_ns=123;r.capture.received_monotonic_ns=124;
{
SessionWriter writer(c);writer.write(r,{{"raw_keypoints",{1,2,3}}});
r.frame_index=9;r.capture.frame_index=9;
for(auto& pixel:im->pixels)pixel+=80;
writer.write(r,{{"raw_keypoints",{4,5,6}}});
writer.finish();writer.finish();
rejects([&]{writer.write(r,{});});
}
rejects([&]{SessionWriter duplicate(c);});
PipelineConfig replay;replay.replay_session=c.record_session;
SessionReader reader(replay);check(replay.camera.width==64&&replay.detector_confidence==.42,"Settings not restored");
auto first=reader.read();check(first&&first->metadata.frame_index==3,"First index mismatch");
check(first->metadata.driver_sequence==42&&first->metadata.capture_monotonic_ns!=123,"Capture metadata mismatch");
check(first->replay_record->at("capture").at("capture_monotonic_ns")==123,"Original clock lost");
for(int y=0;y<48;++y)for(int x=0;x<192;++x)check(std::abs(int(first->image->pixels[y*192+x])-(32+x/3+y%4))<12,"Decoded first frame mismatch");
auto second=reader.read();check(second&&second->metadata.frame_index==9,"Gap/order lost");
check(second->image->pixels[0]>first->image->pixels[0]+60,"Video frame order lost");
check(!reader.read(),"EOF not drained");
// Unindexed temporary metadata must not become input.
std::ofstream(c.record_session/"frames/000000000002.json.tmp")<<"incomplete";
SessionReader prefix(replay);check(prefix.read()&&prefix.read()&&!prefix.read(),"Uncommitted data replayed");
std::filesystem::remove(c.record_session/"frames/000000000001.json");
SessionReader missing(replay);missing.read();rejects([&]{missing.read();});
std::ofstream(c.record_session/"frames.txt",std::ios::trunc)<<"../bad\n";
SessionReader invalid(replay);rejects([&]{invalid.read();});
std::ofstream(c.record_session/"frames.txt",std::ios::trunc)<<"000000000000";
SessionReader truncated(replay);rejects([&]{truncated.read();});
std::ofstream(c.record_session/"frames.txt",std::ios::trunc)<<"000000000000\n";
SessionReader shortIndex(replay);shortIndex.read();rejects([&]{shortIndex.read();});
std::filesystem::remove(c.record_session/"complete.json");
rejects([&]{SessionReader incomplete(replay);});
c.record_session=root/"empty";
{SessionWriter empty(c);empty.finish();}
replay.replay_session=c.record_session;
SessionReader empty(replay);check(!empty.read(),"Empty recording has frames");
c.camera.width=63;c.record_session=root/"odd";
rejects([&]{SessionWriter odd(c);});
std::cout<<"H.264 encode/decode, settings, order, EOF, stop finalization and corruption checks passed\n";
}catch(std::exception const& e){std::cerr<<e.what()<<'\n';return 1;}