From: Simon Marchi Date: Thu, 21 Mar 2024 18:15:52 +0000 (-0400) Subject: tests/lib/conds: test clock compatibility post conditions X-Git-Url: https://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=c3211f0a28bc015d1fb04c600779d47f9896d4cc tests/lib/conds: test clock compatibility post conditions Add tests for the clock class compatibility post conditions in `iterator.c`. There is one test for each `BT_ASSERT_POST_DEV` in `assert_post_dev_clock_classes_are_compatible_one`. `addClockClsCompatTriggers()` adds a bunch of triggers that make a message iterator return two messages with incompatible clock classes. The message types that play a role in the clock compatibility checks are "stream beginning" and "message iterator inactivity". `addClockClsCompatTriggers()` adds all possible combinations of using these two message types for the first and second message. Since it's not possible to send a message iterator inactivity message without a clock class, some cases are skipped. The change in `Makefile.am` is needed for the test to work in builds with `--enable-built-in-plugins`, for the `RunIn` utility to be able to find the `utils` plugin. This was not needed before, because all the existing triggers make the program stop before `RunIn` attempts to load the `utils` plugin. Change-Id: Ib6c22923e4e9f02de64a87efddaee3c23d3891ea Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/11811 Reviewed-by: Philippe Proulx Tested-by: jenkins --- diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index e389f34b..229e53c0 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -1,5 +1,7 @@ # SPDX-License-Identifier: MIT +include $(top_srcdir)/src/Makefile.common.inc + AM_CPPFLAGS += -I$(top_srcdir)/tests/utils noinst_LTLIBRARIES = @@ -22,8 +24,6 @@ test_fields_bin_LDADD = $(COMMON_TEST_LDADD) \ if ENABLE_BUILT_IN_PLUGINS -include $(top_srcdir)/src/Makefile.common.inc - test_fields_bin_LDFLAGS = $(call pluginarchive,utils) test_fields_bin_LDADD += \ $(top_builddir)/src/plugins/common/param-validation/libparam-validation.la @@ -135,13 +135,23 @@ noinst_PROGRAMS += conds/conds-triggers conds_conds_triggers_SOURCES = \ conds/conds-triggers.cpp \ conds/utils.cpp \ - conds/utils.hpp + conds/utils.hpp \ + conds/clk-cls-compat-postconds-triggers.cpp \ + conds/clk-cls-compat-postconds-triggers.hpp conds_conds_triggers_LDADD = \ $(COMMON_TEST_LDADD) \ $(top_builddir)/src/lib/libbabeltrace2.la \ $(top_builddir)/src/cpp-common/vendor/fmt/libfmt.la +if ENABLE_BUILT_IN_PLUGINS + +conds_conds_triggers_LDFLAGS = $(call pluginarchive,utils) +conds_conds_triggers_LDADD += \ + $(top_builddir)/src/plugins/common/param-validation/libparam-validation.la + +endif # ENABLE_BUILT_IN_PLUGINS + dist_check_SCRIPTS += conds/test-conds.sh conds/test.py endif diff --git a/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp b/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp new file mode 100644 index 00000000..a8a4d626 --- /dev/null +++ b/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp @@ -0,0 +1,254 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2024 EfficiOS Inc. + */ + +#include "cpp-common/bt2s/make-unique.hpp" +#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */ + +#include "../utils/run-in.hpp" +#include "clk-cls-compat-postconds-triggers.hpp" + +namespace { + +/* + * `RunIn` implementation to trigger clock (in)compatibility postcondition + * assertions. + */ +class ClockClsCompatRunIn final : public RunIn +{ +public: + enum class MsgType + { + STREAM_BEG, + MSG_ITER_INACTIVITY, + }; + + using CreateClockCls = bt2::ClockClass::Shared (*)(bt2::SelfComponent); + + explicit ClockClsCompatRunIn(const MsgType msgType1, const CreateClockCls createClockCls1, + const MsgType msgType2, + const CreateClockCls createClockCls2) noexcept : + _mMsgType1 {msgType1}, + _mMsgType2 {msgType2}, _mCreateClockCls1 {createClockCls1}, _mCreateClockCls2 { + createClockCls2} + { + } + + void onMsgIterNext(bt2::SelfMessageIterator self, bt2::ConstMessageArray& msgs) override + { + /* In case the expected assertion doesn't trigger, avoid looping indefinitely. */ + BT_ASSERT(!_mBeenThere); + + const auto traceCls = self.component().createTraceClass(); + const auto trace = traceCls->instantiate(); + + msgs.append(this->_createOneMsg(self, _mMsgType1, _mCreateClockCls1, *trace)); + msgs.append(this->_createOneMsg(self, _mMsgType2, _mCreateClockCls2, *trace)); + _mBeenThere = true; + } + +private: + static bt2::Message::Shared _createOneMsg(const bt2::SelfMessageIterator self, + const MsgType msgType, + const CreateClockCls createClockCls, + const bt2::Trace trace) + { + const auto clockCls = createClockCls(self.component()); + + switch (msgType) { + case MsgType::STREAM_BEG: + { + const auto streamCls = trace.cls().createStreamClass(); + + if (clockCls) { + streamCls->defaultClockClass(*clockCls); + } + + return self.createStreamBeginningMessage(*streamCls->instantiate(trace)); + } + + case MsgType::MSG_ITER_INACTIVITY: + BT_ASSERT(clockCls); + return self.createMessageIteratorInactivityMessage(*clockCls, 12); + }; + + bt_common_abort(); + } + + MsgType _mMsgType1, _mMsgType2; + CreateClockCls _mCreateClockCls1, _mCreateClockCls2; + bool _mBeenThere = false; +}; + +__attribute__((used)) const char *format_as(const ClockClsCompatRunIn::MsgType msgType) +{ + switch (msgType) { + case ClockClsCompatRunIn::MsgType::STREAM_BEG: + return "sb"; + + case ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY: + return "mii"; + } + + bt_common_abort(); +} + +bt2::ClockClass::Shared noClockClass(bt2::SelfComponent) noexcept +{ + return bt2::ClockClass::Shared {}; +} + +const bt2c::Uuid uuidA {"f00aaf65-ebec-4eeb-85b2-fc255cf1aa8a"}; +const bt2c::Uuid uuidB {"03482981-a77b-4d7b-94c4-592bf9e91785"}; + +} /* namespace */ + +/* + * Add clock class compatibility postcondition failures triggers. + * + * Each trigger below makes a message iterator return two messages with + * incompatible clock classes, leading to a postcondition failure. + */ +void addClkClsCompatTriggers(CondTriggers& triggers) +{ + const auto addValidCases = [&triggers]( + const ClockClsCompatRunIn::CreateClockCls createClockCls1, + const ClockClsCompatRunIn::CreateClockCls createClockCls2, + const char * const condId) { + /* + * Add triggers for all possible combinations of message types. + * + * It's not possible to create message iterator inactivity messages + * without a clock class. + */ + static constexpr std::array msgTypes { + ClockClsCompatRunIn::MsgType::STREAM_BEG, + ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY, + }; + + const auto isInvalidCase = [](const ClockClsCompatRunIn::MsgType msgType, + const ClockClsCompatRunIn::CreateClockCls createClockCls) { + return msgType == ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY && + createClockCls == noClockClass; + }; + + for (const auto msgType1 : msgTypes) { + if (isInvalidCase(msgType1, createClockCls1)) { + continue; + } + + for (const auto msgType2 : msgTypes) { + if (isInvalidCase(msgType2, createClockCls2)) { + continue; + } + + triggers.emplace_back(bt2s::make_unique>( + ClockClsCompatRunIn {msgType1, createClockCls1, msgType2, createClockCls2}, + CondTrigger::Type::POST, condId, fmt::format("{}-{}", msgType1, msgType2))); + } + } + }; + + addValidCases( + noClockClass, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + "message-iterator-class-next-method:stream-class-has-no-clock-class"); + + addValidCases( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + noClockClass, + "message-iterator-class-next-method:stream-class-has-clock-class-with-unix-epoch-origin"); + + addValidCases( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-unix-epoch-origin"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + noClockClass, "message-iterator-class-next-method:stream-class-has-clock-class-with-uuid"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + "message-iterator-class-next-method:clock-class-has-non-unix-epoch-origin"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-uuid"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidB); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-expected-uuid"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + noClockClass, "message-iterator-class-next-method:stream-class-has-clock-class"); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-is-expected"); +} diff --git a/tests/lib/conds/clk-cls-compat-postconds-triggers.hpp b/tests/lib/conds/clk-cls-compat-postconds-triggers.hpp new file mode 100644 index 00000000..cabf25cf --- /dev/null +++ b/tests/lib/conds/clk-cls-compat-postconds-triggers.hpp @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2024 EfficiOS Inc. + */ + +#ifndef TESTS_LIB_CONDS_CLK_CLS_COMPAT_POSTCONDS_TRIGGERS_HPP +#define TESTS_LIB_CONDS_CLK_CLS_COMPAT_POSTCONDS_TRIGGERS_HPP + +#include "utils.hpp" + +void addClkClsCompatTriggers(CondTriggers& triggers); + +#endif diff --git a/tests/lib/conds/conds-triggers.cpp b/tests/lib/conds/conds-triggers.cpp index 857cfbcc..3e1cfe86 100644 --- a/tests/lib/conds/conds-triggers.cpp +++ b/tests/lib/conds/conds-triggers.cpp @@ -13,6 +13,7 @@ #include "cpp-common/bt2c/span.hpp" #include "cpp-common/bt2s/make-unique.hpp" +#include "clk-cls-compat-postconds-triggers.hpp" #include "utils.hpp" namespace { @@ -107,5 +108,6 @@ int main(const int argc, const char ** const argv) }, CondTrigger::Type::PRE, "field-class-integer-set-field-value-range:not-null:field-class")); + addClkClsCompatTriggers(triggers); condMain(bt2c::makeSpan(argv, argc), triggers); }