Skip to content

Commit

Permalink
Merge branch 'COVESA:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
bunty95 authored Sep 9, 2024
2 parents 3850e2d + c1a6854 commit 181f248
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 237 deletions.
2 changes: 1 addition & 1 deletion BuildDltViewer.pro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += qdlt src plugin commander
CONFIG += c++11
CONFIG += c++1z

ICON = Project.icns
QMAKE_INFO_PLIST = Info.plist
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(LINUX TRUE)
endif()

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand Down
12 changes: 11 additions & 1 deletion qdlt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ add_library(qdlt SHARED
qdltsettingsmanager.cpp
qdltexporter.cpp
qdltimporter.cpp
fieldnames.cpp)
fieldnames.cpp
dltmessagematcher.cpp
dltmessagematcher.h)

target_compile_definitions(qdlt PRIVATE
BYTE_ORDER=LITTLE_ENDIAN
Expand Down Expand Up @@ -116,3 +118,11 @@ foreach(SDK_EXAMPLE IN ITEMS ${SDK_EXAMPLES})
DESTINATION "${DLT_ADDITIONAL_FILES_INSTALLATION_PATH}/src"
COMPONENT qdlt_sdk)
endforeach()


find_package(GTest)
# configure unit tests only if gtest found on the system
if (GTest_FOUND)
enable_testing()
add_subdirectory(tests)
endif()
66 changes: 66 additions & 0 deletions qdlt/dltmessagematcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "dltmessagematcher.h"

#include <qdltmsg.h>

DltMessageMatcher::DltMessageMatcher() {}

bool DltMessageMatcher::match(const QDltMsg &msg, const Pattern& pattern) const
{
if (!matchAppId(msg.getApid()) || !matchCtxId(msg.getCtid()))
return false;

if (!matchTimestampRange(msg.getTimestamp())) {
return false;
}

bool matchFound = false;
if (m_headerSearchEnabled) {
auto header = msg.toStringHeader();
if (m_messageIdFormat)
header += ' ' + QString::asprintf(m_messageIdFormat->toUtf8(), msg.getMessageId());
if (std::holds_alternative<QRegularExpression>(pattern)) {
matchFound = header.contains(std::get<QRegularExpression>(pattern));
} else {
const auto& searchText = std::get<QString>(pattern);
matchFound = searchText.isEmpty() || header.contains(searchText, m_caseSensitivity);
}
}

if (matchFound)
return true;

if (m_payloadSearchEnabled) {
const auto payload = msg.toStringPayload();
if (std::holds_alternative<QRegularExpression>(pattern)) {
matchFound = payload.contains(std::get<QRegularExpression>(pattern));
} else {
const auto& searchText = std::get<QString>(pattern);
matchFound = payload.isEmpty() || payload.contains(searchText, m_caseSensitivity);
}
}

return matchFound;
}

bool DltMessageMatcher::matchAppId(const QString& appId) const
{
return m_appId.isEmpty() || appId.compare(m_appId, m_caseSensitivity) == 0;
}

bool DltMessageMatcher::matchCtxId(const QString& ctxId) const
{
return m_ctxId.isEmpty() || ctxId.compare(m_ctxId, m_caseSensitivity) == 0;
}

bool DltMessageMatcher::matchTimestampRange(unsigned int ts) const
{
if (!m_timestampRange)
return true;

// timestamp is displayed as floating number in UI and hence user provides timestamp ranges as floating numbers too
// in DltMsg stores timestamp as integer which is transformed to UI display floating number by QltMgs::toStringHeader
// method more or less as follows
const auto uiTs = static_cast<double>(ts) / 10'000;

return (m_timestampRange->start <= uiTs) && (uiTs <= m_timestampRange->end);
}
72 changes: 72 additions & 0 deletions qdlt/dltmessagematcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef DLTMESSAGEMATCHER_H
#define DLTMESSAGEMATCHER_H

#include "export_rules.h"

#include <QString>
#include <QRegularExpression>

#include <optional>
#include <variant>

class QDltMsg;

class QDLT_EXPORT DltMessageMatcher
{
public:
using Pattern = std::variant<QString, QRegularExpression>;

DltMessageMatcher();

void setCaseSentivity(Qt::CaseSensitivity caseSensitivity) {
m_caseSensitivity = caseSensitivity;
}

void setSearchAppId(const QString& appId) {
m_appId = appId;
}

void setSearchCtxId(const QString& ctxId) {
m_ctxId = ctxId;
}

void setTimestapmRange(double start, double end) {
m_timestampRange = {start, end};
}

void setHeaderSearchEnabled(bool enabled) {
m_headerSearchEnabled = enabled;
}

void setPayloadSearchEnabled(bool enabled) {
m_payloadSearchEnabled = enabled;
}

void setMessageIdFormat(const QString& msgIdFormat) {
m_messageIdFormat = msgIdFormat;
}

bool match(const QDltMsg& message, const Pattern& pattern) const;
private:
bool matchAppId(const QString& appId) const;
bool matchCtxId(const QString& ctxId) const;
bool matchTimestampRange(unsigned int ts) const;
private:
QString m_ctxId;
QString m_appId;

struct TimestampRange {
double start;
double end;
};
std::optional<TimestampRange> m_timestampRange;

Qt::CaseSensitivity m_caseSensitivity{Qt::CaseInsensitive};

bool m_headerSearchEnabled{true};
bool m_payloadSearchEnabled{true};

std::optional<QString> m_messageIdFormat;
};

#endif // DLTMESSAGEMATCHER_H
6 changes: 4 additions & 2 deletions qdlt/qdlt.pro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
PROJECT = qdlt
TEMPLATE = lib

CONFIG += c++11
CONFIG += c++1z
DEFINES += QDLT_LIBRARY
*-gcc* {
QMAKE_CFLAGS += -std=gnu99
Expand All @@ -11,7 +11,7 @@ DEFINES += QDLT_LIBRARY
}

*-g++* {
QMAKE_CXXFLAGS += -std=gnu++0x
QMAKE_CXXFLAGS += -std=c++17
QMAKE_CXXFLAGS += -Wall
QMAKE_CXXFLAGS += -Wextra
QMAKE_CXXFLAGS += -DPLUGIN_INSTALLATION_PATH=\\\"$$PREFIX/usr/share/dlt-viewer/plugins\\\"
Expand Down Expand Up @@ -65,6 +65,7 @@ SOURCES += \
qdltexporter.cpp \
fieldnames.cpp \
qdltimporter.cpp \
dltmessagematcher.cpp \

HEADERS += qdlt.h \
export_rules.h \
Expand Down Expand Up @@ -96,6 +97,7 @@ HEADERS += qdlt.h \
qdltexporter.h \
fieldnames.h \
qdltimporter.h \
dltmessagematcher.h \

unix:VERSION = 1.0.0

Expand Down
10 changes: 10 additions & 0 deletions qdlt/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_executable(test_tools
test_dltmessagematcher.cpp
)
target_link_libraries(
test_tools
PRIVATE
GTest::gtest_main
qdlt
)

122 changes: 122 additions & 0 deletions qdlt/tests/test_dltmessagematcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include <gtest/gtest.h>

#include "dltmessagematcher.h"
#include <qdltmsg.h>

TEST(DltMessageMatcher, matchAppId) {
QDltMsg msg;
msg.setApid("Bla");

DltMessageMatcher matcher;

// case insensitive search
matcher.setSearchAppId("bla");
EXPECT_TRUE(matcher.match(msg, QString{}));

// case sensitive search
matcher.setCaseSentivity(Qt::CaseSensitive);
EXPECT_FALSE(matcher.match(msg, QString{}));
}

TEST(DltMessageMatcher, matchCtxId) {
QDltMsg msg;
msg.setCtid("Bla");

DltMessageMatcher matcher;

// case insensitive search
matcher.setSearchCtxId("bla");
EXPECT_TRUE(matcher.match(msg, QString{}));

// case sensitive search
matcher.setCaseSentivity(Qt::CaseSensitive);
EXPECT_FALSE(matcher.match(msg, QString{}));
}

TEST(DltMessageMatcher, matchTimestampRange) {
QDltMsg msg;
msg.setTimestamp(50000);


DltMessageMatcher matcher;

// no timestamp range is set
EXPECT_TRUE(matcher.match(msg, QString{}));

// in the range
matcher.setTimestapmRange(static_cast<double>(msg.getTimestamp() - 10) / 10'000,
static_cast<double>(msg.getTimestamp() + 10) / 10'000);
EXPECT_TRUE(matcher.match(msg, QString{}));

// range is to the left
matcher.setTimestapmRange(static_cast<double>(msg.getTimestamp() - 100) / 10'000,
static_cast<double>(msg.getTimestamp() - 10) / 10'000);
EXPECT_FALSE(matcher.match(msg, QString{}));

// range is to the right
matcher.setTimestapmRange(static_cast<double>(msg.getTimestamp() + 10) / 10'000,
static_cast<double>(msg.getTimestamp() + 100) / 10'000);
EXPECT_FALSE(matcher.match(msg, QString{}));
}

TEST(DltMessageMatcher, matchMessageHeader) {
QDltMsg msg;
msg.setMicroseconds(4242);
msg.setTimestamp(45);
msg.setMessageCounter(2);
msg.setEcuid("ecuId");
msg.setApid("appId");
msg.setCtid("ctxId");
msg.setSessionid(56);
msg.setType(QDltMsg::DltTypeNwTrace);
msg.setSubtype(3);
msg.setMode(QDltMsg::DltModeNonVerbose);
msg.setNumberOfArguments(255);
msg.setTime(123456789);

DltMessageMatcher matcher;
matcher.setHeaderSearchEnabled(true);
matcher.setPayloadSearchEnabled(false);

// simple text match
// empty header matches
EXPECT_TRUE(matcher.match(msg, ""));
EXPECT_TRUE(matcher.match(msg, "2 ecuId appId"));
EXPECT_FALSE(matcher.match(msg, "4243"));

// regexp match
// simple text as regexp
EXPECT_TRUE(matcher.match(msg, QRegularExpression("ctxId")));
// actual regexp: message starts with a date
EXPECT_TRUE(matcher.match(msg, QRegularExpression("^\\d\\d\\d\\d/\\d\\d/\\d\\d ")));
// actual regexp: somewhere in the middle there is "appId"-word separated from a next word with a space,
// at the end of the string there is a number
EXPECT_TRUE(matcher.match(msg, QRegularExpression("appId \\w+ .+\\d+$")));
}

TEST(DltMessageMatcher, matchMessagePayload) {
QDltMsg msg;
msg.setIndex(42);
msg.setEcuid("efgh");
msg.setMode(QDltMsg::DltModeNonVerbose);
auto ba = QString{"abcd"}.toUtf8();
msg.setPayload(ba);
// version number is set to make QDltMsg::toStringPayload produce string with payload
msg.setVersionNumber(2);

DltMessageMatcher matcher;
matcher.setHeaderSearchEnabled(false);
matcher.setPayloadSearchEnabled(true);

// simple text match
// empty header matches
EXPECT_TRUE(matcher.match(msg, ""));
EXPECT_FALSE(matcher.match(msg, "efgh"));
EXPECT_TRUE(matcher.match(msg, "abc"));

//regexp match
// simple text as regexp
EXPECT_TRUE(matcher.match(msg, QRegularExpression("cd")));
// actual regexp, match string "[0] abcd|61 62 63 64"
EXPECT_TRUE(matcher.match(msg, QRegularExpression("^\\[\\d\\]\\s+\\w+|[\\d\\s]+$")));
}
Loading

0 comments on commit 181f248

Please sign in to comment.