#include #include #include #include #include "utils/config_expand.h" #include "utils/config_schema.h" #include "utils/simple_json.h" #include "utils/spsc_queue.h" namespace { int Fail(const char* expr, const char* file, int line) { std::cerr << "TEST FAIL: " << expr << " at " << file << ":" << line << "\n"; return 1; } #define CHECK(x) do { if (!(x)) return Fail(#x, __FILE__, __LINE__); } while (0) using rk3588::ParseSimpleJson; using rk3588::SimpleJson; int TestSimpleJsonBasic() { SimpleJson v; std::string err; CHECK(ParseSimpleJson("{\"a\":1,\"b\":true,\"c\":[\"x\",null]}", v, err)); CHECK(v.IsObject()); CHECK(v.ValueOr("a", 0) == 1); CHECK(v.ValueOr("b", false) == true); const SimpleJson* c = v.Find("c"); CHECK(c && c->IsArray()); CHECK(c->AsArray().size() == 2); CHECK(c->AsArray()[0].AsString("") == "x"); CHECK(c->AsArray()[1].IsNull()); SimpleJson bad; std::string err2; CHECK(!ParseSimpleJson("{\"a\":1} trailing", bad, err2)); CHECK(!err2.empty()); return 0; } int TestConfigExpandAndValidate() { // Root with templates/instances -> graphs const std::string src = R"JSON( { "queue": {"size": 8, "strategy": "drop_oldest"}, "templates": { "t": { "nodes": [ {"id": "n1", "type": "input_file", "role": "source", "path": "${path}"}, {"id": "n2", "type": "det_post", "role": "filter"} ], "edges": [ ["n1", "n2", {"queue": {"size": 4}}] ] } }, "instances": [ { "name": "cam1", "template": "t", "params": {"path": "/tmp/a.mp4"}, "override": {"nodes": {"n2": {"enable": true}}} } ] } )JSON"; SimpleJson root; std::string perr; CHECK(ParseSimpleJson(src, root, perr)); SimpleJson expanded; std::string eerr; CHECK(rk3588::ExpandRootConfig(root, expanded, eerr)); std::string verr; CHECK(rk3588::ValidateExpandedRootConfig(expanded, verr)); const SimpleJson* graphs = expanded.Find("graphs"); CHECK(graphs && graphs->IsArray()); CHECK(graphs->AsArray().size() == 1); const SimpleJson& g0 = graphs->AsArray()[0]; CHECK(g0.ValueOr("name", "") == "cam1"); const SimpleJson* nodes = g0.Find("nodes"); CHECK(nodes && nodes->IsArray()); CHECK(nodes->AsArray().size() == 2); // ids should be prefixed. CHECK(nodes->AsArray()[0].ValueOr("id", "") == "cam1_n1"); CHECK(nodes->AsArray()[1].ValueOr("id", "") == "cam1_n2"); // placeholder replaced. CHECK(nodes->AsArray()[0].ValueOr("path", "") == "/tmp/a.mp4"); return 0; } int TestSpscQueueBasic() { using rk3588::QueueDropStrategy; rk3588::SpscQueue q(2, QueueDropStrategy::DropOldest); CHECK(q.Push(1)); CHECK(q.Push(2)); // Full: DropOldest should drop 1 and accept 3. CHECK(q.Push(3)); int v = 0; CHECK(q.TryPop(v)); CHECK(v == 2); CHECK(q.TryPop(v)); CHECK(v == 3); return 0; } } // namespace int main() { if (int rc = TestSimpleJsonBasic(); rc != 0) return rc; if (int rc = TestConfigExpandAndValidate(); rc != 0) return rc; if (int rc = TestSpscQueueBasic(); rc != 0) return rc; std::cout << "All tests passed\n"; return 0; }