forked from COVESA/dlt-viewer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Make tempPayload a local var * establish tools lib and tests infra * rm redundant SearchDialog::is_TimeStampRangeValid state var If timestamp range search is selected the loop will only continue if range is valid. It does not make sense to check in functions below if range is valid since otherwise that code cannot be even reached * implement matching for ctx and app Ids * use ctxid and appid match functionality in app * TimestampRange * use new timestamp filtering * text search using dltmessagematcher * fix build move matcher to qdlt lib enable c++17 in qmake config The new code uses variant and optional added in c++17 standard while qmake config was setup restricted to c++11 enable tests only if gtest package found Set c++17 standard in cmake export class for windows linker Signed-off-by: Viktor Kopp <[email protected]>
- Loading branch information
Showing
11 changed files
with
331 additions
and
201 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]+$"))); | ||
} |
Oops, something went wrong.