IQ.Pilot Release Commit @ 661a2de

This commit is contained in:
IQ.Lvbs CI [bot]
2026-08-08 14:37:51 -05:00
parent a6c27ac169
commit a1ef7d6c80
211 changed files with 7332 additions and 2756 deletions

View File

@@ -1,14 +1,15 @@
#undef INFO
#include <QDir>
#include <filesystem>
#include <sstream>
#include "catch2/catch.hpp"
#include "common/tests/native_test.h"
#include "tools/cabana/dbc/dbcfile.h"
#include "tools/cabana/dbc/dbcmanager.h"
const std::string TEST_RLOG_URL = "https://commadataci.blob.core.windows.net/openpilotci/0c94aa1e1296d7c6/2021-05-05--19-48-37/0/rlog.bz2";
TEST_CASE("DBCFile::generateDBC") {
QString fn = QString("%1/%2.dbc").arg(OPENDBC_FILE_PATH, "tesla_can");
void test_generate_dbc() {
std::string fn = std::string(OPENDBC_FILE_PATH) + "/tesla_can.dbc";
DBCFile dbc_origin(fn);
DBCFile dbc_from_generated("", dbc_origin.generateDBC());
@@ -28,9 +29,9 @@ TEST_CASE("DBCFile::generateDBC") {
}
}
TEST_CASE("DBCFile::generateDBC - comment order") {
void test_comment_order() {
// Ensure that message comments are followed by signal comments and in the correct order
auto content = R"(BO_ 160 message_1: 8 EON
std::string content = R"(BO_ 160 message_1: 8 EON
SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
BO_ 162 message_2: 8 EON
@@ -45,8 +46,8 @@ CM_ SG_ 162 signal_2 "signal comment";
REQUIRE(dbc.generateDBC() == content);
}
TEST_CASE("DBCFile::generateDBC -- preserve original header") {
QString content = R"(VERSION "1.0"
void test_preserve_original_header() {
std::string content = R"(VERSION "1.0"
NS_ :
CM_
@@ -65,8 +66,8 @@ CM_ SG_ 160 signal_1 "signal comment";
REQUIRE(dbc.generateDBC() == content);
}
TEST_CASE("DBCFile::generateDBC - escaped quotes") {
QString content = R"(BO_ 160 message_1: 8 EON
void test_escaped_quotes() {
std::string content = R"(BO_ 160 message_1: 8 EON
SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
CM_ BO_ 160 "message comment with \"escaped quotes\"";
@@ -76,8 +77,8 @@ CM_ SG_ 160 signal_1 "signal comment with \"escaped quotes\"";
REQUIRE(dbc.generateDBC() == content);
}
TEST_CASE("parse_dbc") {
QString content = R"(
void test_parse_dbc() {
std::string content = R"(
BO_ 160 message_1: 8 EON
SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
SG_ signal_2 : 12|1@1+ (1.0,0.0) [0.0|1] "" XXX
@@ -119,9 +120,9 @@ CM_ SG_ 162 signal_1 "signal comment with \"escaped quotes\"";
REQUIRE(sig_1->comment == "signal comment");
REQUIRE(sig_1->receiver_name == "XXX");
REQUIRE(sig_1->val_desc.size() == 3);
REQUIRE(sig_1->val_desc[0] == std::pair<double, QString>{0, "disabled"});
REQUIRE(sig_1->val_desc[1] == std::pair<double, QString>{1.2, "initializing"});
REQUIRE(sig_1->val_desc[2] == std::pair<double, QString>{2, "fault"});
REQUIRE(sig_1->val_desc[0] == std::pair<double, std::string>{0, "disabled"});
REQUIRE(sig_1->val_desc[1] == std::pair<double, std::string>{1.2, "initializing"});
REQUIRE(sig_1->val_desc[2] == std::pair<double, std::string>{2, "fault"});
auto &sig_2 = msg->sigs[1];
REQUIRE(sig_2->comment == "multiple line comment \n1\n2");
@@ -142,16 +143,66 @@ CM_ SG_ 162 signal_1 "signal comment with \"escaped quotes\"";
REQUIRE(msg->sigs[0]->comment == "signal comment with \"escaped quotes\"");
}
TEST_CASE("parse_iqdbc") {
QDir dir(OPENDBC_FILE_PATH);
QStringList errors;
for (auto fn : dir.entryList({"*.dbc"}, QDir::Files, QDir::Name)) {
// OPENDBC_FILE_PATH points at iqdbc/dbc here — this is the load-bearing check that
// cabana can still parse every DBC iqpilot ships.
void test_parse_iqdbc() {
std::vector<std::string> errors;
int parsed = 0;
for (const auto &entry : std::filesystem::directory_iterator(OPENDBC_FILE_PATH)) {
if (!entry.is_regular_file() || entry.path().extension() != ".dbc") continue;
try {
auto dbc = DBCFile(dir.filePath(fn));
auto dbc = DBCFile(entry.path().string());
++parsed;
} catch (std::exception &e) {
errors.push_back(e.what());
}
}
INFO(errors.join("\n").toStdString());
// guard against OPENDBC_FILE_PATH pointing somewhere empty, which would make the
// loop above pass vacuously
REQUIRE(parsed > 100);
std::ostringstream details;
for (const auto &error : errors) details << error << '\n';
if (!errors.empty()) std::cerr << details.str();
REQUIRE(errors.empty());
}
void test_dbc_manager() {
DBCManager manager;
int files_changed = 0;
int signals_added = 0;
int masks_updated = 0;
manager.setCallbacks({
.signal_added = [&](MessageId, const cabana::Signal *) { ++signals_added; },
.file_changed = [&]() { ++files_changed; },
.mask_updated = [&]() { ++masks_updated; },
});
std::string error;
REQUIRE(manager.open(SOURCE_ALL, "test", "BO_ 160 message: 8 XXX\n", &error));
REQUIRE(error.empty());
REQUIRE(files_changed == 1);
cabana::Signal signal{};
signal.name = "speed";
signal.start_bit = 0;
signal.size = 8;
signal.is_little_endian = true;
manager.addSignal({.source = 0, .address = 160}, signal);
REQUIRE(signals_added == 1);
REQUIRE(masks_updated == 1);
REQUIRE(manager.msg({.source = 0, .address = 160})->sig("speed") != nullptr);
}
void test_cabana_core() {
test_generate_dbc();
test_comment_order();
test_preserve_original_header();
test_escaped_quotes();
test_parse_dbc();
test_parse_iqdbc();
test_dbc_manager();
}
int main() {
return run_native_test(test_cabana_core);
}