From 49bd74f4da37a8432f78c66947f3baa199de041e Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 4 Oct 2024 11:10:08 -0400 Subject: [PATCH] ccv: adjust for MIP 1 Adjust the clock correlation validation code for MIP 1. The high level conceptual changes to adapt to are: - With MIP 0, the only way to have a known clock origin is for it to be the Unix epoch. In MIP 1, it's possible to have known user-defined clock origins. - With MIP 0, clock classes are optionally identified with UUIDs. With MIP 1, it's with a (namespace, name, UID) tuple. The concrete changes are: - Pass the MIP version down to `ClockCorrelationValidator::validate()`and `bt_clock_correlation_validator_validate_message()`. - Rename enumerators - Unix epoch -> Known origin - UUID -> ID (which comprises both UUIDs and (namespace, name, UID) tuples) - Adjust ClockCorrelationValidator::_validate() where the logic differs between MIP 0 and 1. - Adjust the error messages given by clients of `ClockCorrelationValidator` to reflect the differences between MIP 0 and 1. - Make `MessageComparator` take a graph MIP version, change the way `MessageComparator::compare()` compares trace identities based on the MIP version. - Adjust tests checking clock compatibility problems to run with MIP 0 and 1, using the right kind of identity depending on the MIP version. Change-Id: I12a5b5bed27fe6185ab407465901d285cbb23778 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/12785 Reviewed-by: Philippe Proulx Tested-by: jenkins --- src/Makefile.am | 1 + .../clock-correlation-validator.cpp | 106 ++++-- .../clock-correlation-validator.h | 18 +- .../clock-correlation-validator.hpp | 56 +-- src/cpp-common/bt2/clock-class.hpp | 21 ++ src/cpp-common/bt2/identity-view.hpp | 66 ++++ src/cpp-common/bt2/trace-ir.hpp | 5 + src/cpp-common/bt2c/c-string-view.hpp | 15 + src/lib/graph/iterator.c | 189 ++++++++-- src/plugins/common/muxing/muxing.cpp | 25 +- src/plugins/common/muxing/muxing.hpp | 9 + src/plugins/ctf/lttng-live/lttng-live.hpp | 3 +- src/plugins/utils/muxer/msg-iter.cpp | 233 ++++++++---- src/plugins/utils/muxer/msg-iter.hpp | 2 +- .../clk-cls-compat-postconds-triggers.cpp | 314 ++++++++++------ tests/lib/utils/run-in.cpp | 7 - tests/lib/utils/run-in.hpp | 5 - .../test-clock-compatibility.cpp | 338 ++++++++++++------ tests/utils/Makefile.am | 5 +- tests/utils/common.hpp | 22 ++ 20 files changed, 1039 insertions(+), 401 deletions(-) create mode 100644 src/cpp-common/bt2/identity-view.hpp create mode 100644 tests/utils/common.hpp diff --git a/src/Makefile.am b/src/Makefile.am index 8c5b0bd7..8bd81ddd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -133,6 +133,7 @@ cpp_common_libcpp_common_la_SOURCES = \ cpp-common/bt2/field-path.hpp \ cpp-common/bt2/field.hpp \ cpp-common/bt2/field-location.hpp \ + cpp-common/bt2/identity-view.hpp \ cpp-common/bt2/integer-range-set.hpp \ cpp-common/bt2/integer-range.hpp \ cpp-common/bt2/internal/comp-cls-bridge.hpp \ diff --git a/src/clock-correlation-validator/clock-correlation-validator.cpp b/src/clock-correlation-validator/clock-correlation-validator.cpp index 88e9c89f..195a684e 100644 --- a/src/clock-correlation-validator/clock-correlation-validator.cpp +++ b/src/clock-correlation-validator/clock-correlation-validator.cpp @@ -13,7 +13,32 @@ namespace bt2ccv { -void ClockCorrelationValidator::_validate(const bt2::ConstMessage msg) +namespace { + +bool clockClassHasKnownAndComparableIdentity(const bt2::ConstClockClass clockCls, + const std::uint64_t graphMipVersion) noexcept +{ + if (graphMipVersion == 0) { + return static_cast(clockCls.uuid()); + } else { + return clockCls.name() && clockCls.uid(); + } +} + +bool clockClassHasKnownAndComparableOrigin(const bt2::ConstClockClass clockCls, + const std::uint64_t graphMipVersion) noexcept +{ + if (graphMipVersion == 0) { + return clockCls.origin().isUnixEpoch(); + } else { + return clockCls.origin().isKnown(); + } +} + +} /* namespace */ + +void ClockCorrelationValidator::_validate(const bt2::ConstMessage msg, + const std::uint64_t graphMipVersion) { bt2::OptionalBorrowedObject clockCls; bt2::OptionalBorrowedObject streamCls; @@ -42,12 +67,14 @@ void ClockCorrelationValidator::_validate(const bt2::ConstMessage msg) if (clockCls) { _mRefClockClass = clockCls->shared(); - if (clockCls->origin().isUnixEpoch()) { - _mExpectation = PropsExpectation::OriginUnix; - } else if (const auto uuid = clockCls->uuid()) { - _mExpectation = PropsExpectation::OriginUnknownWithUuid; + if (clockClassHasKnownAndComparableOrigin(*clockCls, graphMipVersion)) { + _mExpectation = PropsExpectation::OriginKnown; } else { - _mExpectation = PropsExpectation::OriginUnknownWithoutUuid; + if (clockClassHasKnownAndComparableIdentity(*clockCls, graphMipVersion)) { + _mExpectation = PropsExpectation::OriginUnknownWithId; + } else { + _mExpectation = PropsExpectation::OriginUnknownWithoutId; + } } } else { _mExpectation = PropsExpectation::None; @@ -64,60 +91,82 @@ void ClockCorrelationValidator::_validate(const bt2::ConstMessage msg) break; - case PropsExpectation::OriginUnix: + case PropsExpectation::OriginKnown: if (!clockCls) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnixGotNoClockClass, + ClockCorrelationError::Type::ExpectingOriginKnownGotNoClockClass, {}, *_mRefClockClass, streamCls}; } - if (!clockCls->origin().isUnixEpoch()) { + if (!clockClassHasKnownAndComparableOrigin(*clockCls, graphMipVersion)) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnixGotUnknownOrigin, *clockCls, + ClockCorrelationError::Type::ExpectingOriginKnownGotUnknownOrigin, *clockCls, *_mRefClockClass, streamCls}; } + /* + * Under MIP 0, the only known clock origin is the Unix epoch. + * + * At this point, we know that both clock classes have known + * origins, therefore we also know they share the + * same origin. + */ + if (graphMipVersion > 0) { + if (bt2::isSameClockOrigin(clockCls->origin(), _mRefClockClass->origin(), + graphMipVersion)) { + throw ClockCorrelationError { + ClockCorrelationError::Type::ExpectingOriginKnownGotOtherOrigin, *clockCls, + *_mRefClockClass, streamCls}; + } + } + break; - case PropsExpectation::OriginUnknownWithUuid: + case PropsExpectation::OriginUnknownWithId: { if (!clockCls) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithUuidGotNoClockClass, + ClockCorrelationError::Type::ExpectingOriginUnknownWithIdGotNoClockClass, {}, *_mRefClockClass, streamCls}; } - if (clockCls->origin().isUnixEpoch()) { + if (clockClassHasKnownAndComparableOrigin(*clockCls, graphMipVersion)) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithUuidGotUnixOrigin, *clockCls, + ClockCorrelationError::Type::ExpectingOriginUnknownWithIdGotKnownOrigin, *clockCls, *_mRefClockClass, streamCls}; } - const auto uuid = clockCls->uuid(); - - if (!uuid) { + if (!clockClassHasKnownAndComparableIdentity(*clockCls, graphMipVersion)) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithUuidGotWithoutUuid, - *clockCls, *_mRefClockClass, streamCls}; + ClockCorrelationError::Type::ExpectingOriginUnknownWithIdGotWithoutId, *clockCls, + *_mRefClockClass, streamCls}; } - if (*uuid != *_mRefClockClass->uuid()) { - throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithUuidGotOtherUuid, *clockCls, - *_mRefClockClass, streamCls}; + if (graphMipVersion == 0) { + if (*clockCls->uuid() != *_mRefClockClass->uuid()) { + throw ClockCorrelationError { + ClockCorrelationError::Type::ExpectingOriginUnknownWithIdGotOtherId, *clockCls, + *_mRefClockClass, streamCls}; + } + } else { + if (clockCls->identity() != _mRefClockClass->identity()) { + throw ClockCorrelationError { + ClockCorrelationError::Type::ExpectingOriginUnknownWithIdGotOtherId, *clockCls, + *_mRefClockClass, streamCls}; + } } break; } - case PropsExpectation::OriginUnknownWithoutUuid: + case PropsExpectation::OriginUnknownWithoutId: if (!clockCls) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithoutUuidGotNoClockClass, + ClockCorrelationError::Type::ExpectingOriginUnknownWithoutIdGotNoClockClass, {}, *_mRefClockClass, streamCls}; @@ -125,7 +174,7 @@ void ClockCorrelationValidator::_validate(const bt2::ConstMessage msg) if (clockCls->libObjPtr() != _mRefClockClass->libObjPtr()) { throw ClockCorrelationError { - ClockCorrelationError::Type::ExpectingOriginUnknownWithoutUuidGotOtherClockClass, + ClockCorrelationError::Type::ExpectingOriginUnknownWithoutIdGotOtherClockClass, *clockCls, *_mRefClockClass, streamCls}; } @@ -150,12 +199,13 @@ bt_clock_correlation_validator *bt_clock_correlation_validator_create() noexcept bool bt_clock_correlation_validator_validate_message( bt_clock_correlation_validator * const validator, const bt_message * const msg, - bt_clock_correlation_validator_error_type * const type, + const std::uint64_t graphMipVersion, bt_clock_correlation_validator_error_type * const type, const bt_clock_class ** const actualClockClsOut, const bt_clock_class ** const refClockClsOut) noexcept { try { - reinterpret_cast(validator)->validate(bt2::wrap(msg)); + reinterpret_cast(validator)->validate(bt2::wrap(msg), + graphMipVersion); return true; } catch (const bt2ccv::ClockCorrelationError& error) { *type = static_cast(error.type()); diff --git a/src/clock-correlation-validator/clock-correlation-validator.h b/src/clock-correlation-validator/clock-correlation-validator.h index 25d9b420..ad9fdc16 100644 --- a/src/clock-correlation-validator/clock-correlation-validator.h +++ b/src/clock-correlation-validator/clock-correlation-validator.h @@ -24,16 +24,17 @@ enum bt_clock_correlation_validator_error_type { BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_NO_CLOCK_CLASS_GOT_ONE, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_NO_CLOCK_CLASS, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_UNKNOWN_ORIGIN, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_NO_CLOCK_CLASS, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_UNKNOWN_ORIGIN, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_OTHER_ORIGIN, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_NO_CLOCK_CLASS, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_UNIX_ORIGIN, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_WITHOUT_UUID, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_OTHER_UUID, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_NO_CLOCK_CLASS, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_KNOWN_ORIGIN, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_WITHOUT_ID, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_OTHER_ID, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_NO_CLOCK_CLASS, - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_OTHER_CLOCK_CLASS, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_NO_CLOCK_CLASS, + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_OTHER_CLOCK_CLASS, }; struct bt_clock_correlation_validator *bt_clock_correlation_validator_create( @@ -42,6 +43,7 @@ struct bt_clock_correlation_validator *bt_clock_correlation_validator_create( bool bt_clock_correlation_validator_validate_message( struct bt_clock_correlation_validator *validator, const struct bt_message *msg, + uint64_t graph_mip_version, enum bt_clock_correlation_validator_error_type *type, const struct bt_clock_class ** const actual_clock_cls, const struct bt_clock_class ** const ref_clock_cls) BT_NOEXCEPT; diff --git a/src/clock-correlation-validator/clock-correlation-validator.hpp b/src/clock-correlation-validator/clock-correlation-validator.hpp index 4326bdb3..aa82bd17 100644 --- a/src/clock-correlation-validator/clock-correlation-validator.hpp +++ b/src/clock-correlation-validator/clock-correlation-validator.hpp @@ -21,24 +21,26 @@ public: ExpectingNoClockClassGotOne = BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_NO_CLOCK_CLASS_GOT_ONE, - ExpectingOriginUnixGotNoClockClass = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_NO_CLOCK_CLASS, - ExpectingOriginUnixGotUnknownOrigin = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_UNKNOWN_ORIGIN, - - ExpectingOriginUnknownWithUuidGotNoClockClass = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_NO_CLOCK_CLASS, - ExpectingOriginUnknownWithUuidGotUnixOrigin = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_UNIX_ORIGIN, - ExpectingOriginUnknownWithUuidGotWithoutUuid = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_WITHOUT_UUID, - ExpectingOriginUnknownWithUuidGotOtherUuid = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_OTHER_UUID, - - ExpectingOriginUnknownWithoutUuidGotNoClockClass = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_NO_CLOCK_CLASS, - ExpectingOriginUnknownWithoutUuidGotOtherClockClass = - BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_OTHER_CLOCK_CLASS, + ExpectingOriginKnownGotNoClockClass = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_NO_CLOCK_CLASS, + ExpectingOriginKnownGotUnknownOrigin = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_UNKNOWN_ORIGIN, + ExpectingOriginKnownGotOtherOrigin = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_OTHER_ORIGIN, + + ExpectingOriginUnknownWithIdGotNoClockClass = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_NO_CLOCK_CLASS, + ExpectingOriginUnknownWithIdGotKnownOrigin = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_KNOWN_ORIGIN, + ExpectingOriginUnknownWithIdGotWithoutId = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_WITHOUT_ID, + ExpectingOriginUnknownWithIdGotOtherId = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_OTHER_ID, + + ExpectingOriginUnknownWithoutIdGotNoClockClass = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_NO_CLOCK_CLASS, + ExpectingOriginUnknownWithoutIdGotOtherClockClass = + BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_OTHER_CLOCK_CLASS, }; explicit ClockCorrelationError( @@ -90,28 +92,28 @@ private: /* Expect to have no clock. */ None, - /* Expect a clock with a Unix epoch origin. */ - OriginUnix, + /* Expect a clock with a known origin. */ + OriginKnown, - /* Expect a clock with an unknown origin, but with a UUID. */ - OriginUnknownWithUuid, + /* Expect a clock with an unknown origin, but with an identity. */ + OriginUnknownWithId, - /* Expect a clock with an unknown origin and without a UUID. */ - OriginUnknownWithoutUuid, + /* Expect a clock with an unknown origin and without an identity. */ + OriginUnknownWithoutId, }; public: - void validate(const bt2::ConstMessage msg) + void validate(const bt2::ConstMessage msg, const std::uint64_t graphMipVersion) { if (!msg.isStreamBeginning() && !msg.isMessageIteratorInactivity()) { return; } - this->_validate(msg); + this->_validate(msg, graphMipVersion); } private: - void _validate(const bt2::ConstMessage msg); + void _validate(const bt2::ConstMessage msg, std::uint64_t graphMipVersion); PropsExpectation _mExpectation = PropsExpectation::Unset; diff --git a/src/cpp-common/bt2/clock-class.hpp b/src/cpp-common/bt2/clock-class.hpp index 3024b1d5..386b75d2 100644 --- a/src/cpp-common/bt2/clock-class.hpp +++ b/src/cpp-common/bt2/clock-class.hpp @@ -18,6 +18,7 @@ #include "borrowed-object.hpp" #include "exc.hpp" +#include "identity-view.hpp" #include "internal/utils.hpp" #include "shared-object.hpp" #include "value.hpp" @@ -284,6 +285,11 @@ public: return bt_clock_class_get_uid(this->libObjPtr()); } + IdentityView identity() const noexcept + { + return IdentityView {this->nameSpace(), this->name(), this->uid()}; + } + bool hasSameIdentity(const CommonClockClass other) const noexcept { return static_cast( @@ -416,6 +422,11 @@ public: return bt_clock_class_origin_is_unix_epoch(_mClkCls.libObjPtr()); } + IdentityView identity() const noexcept + { + return IdentityView {this->nameSpace(), this->name(), this->uid()}; + } + private: ConstClockClass _mClkCls; }; @@ -426,6 +437,16 @@ ClockOriginView CommonClockClass::origin() const noexcept return ClockOriginView {*this}; } +inline bool isSameClockOrigin(const bt2::ClockOriginView& a, const bt2::ClockOriginView& b, + const std::uint64_t graphMipVersion) +{ + if (graphMipVersion == 0) { + return a.isUnixEpoch() == b.isUnixEpoch(); + } else { + return a.identity() == b.identity(); + } +} + } /* namespace bt2 */ #endif /* BABELTRACE_CPP_COMMON_BT2_CLOCK_CLASS_HPP */ diff --git a/src/cpp-common/bt2/identity-view.hpp b/src/cpp-common/bt2/identity-view.hpp new file mode 100644 index 00000000..0872b5cc --- /dev/null +++ b/src/cpp-common/bt2/identity-view.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 EfficiOS, Inc. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_IDENTITY_VIEW_HPP +#define BABELTRACE_CPP_COMMON_BT2_IDENTITY_VIEW_HPP + +#include "cpp-common/bt2c/c-string-view.hpp" + +namespace bt2 { + +class IdentityView final +{ +public: + explicit IdentityView(const bt2c::CStringView ns, const bt2c::CStringView name, + const bt2c::CStringView uid) : + _mNs {ns}, + _mName {name}, _mUid {uid} + { + } + + bt2c::CStringView nameSpace() const noexcept + { + return _mNs; + } + + bt2c::CStringView name() const noexcept + { + return _mName; + } + + bt2c::CStringView uid() const noexcept + { + return _mUid; + } + +private: + bt2c::CStringView _mNs; + bt2c::CStringView _mName; + bt2c::CStringView _mUid; +}; + +inline bool operator==(const IdentityView& a, const IdentityView& b) noexcept +{ + /* + * If an identity misses a name or a UID, it's never considered the + * same as another identity. + */ + if (!a.name() || !a.uid() || !b.name() || b.uid()) { + return false; + } + + return equalOrBothNull(a.nameSpace(), b.nameSpace()) && a.name() == b.name() && + a.uid() == b.uid(); +} + +inline bool operator!=(const IdentityView& a, const IdentityView& b) noexcept +{ + return !(a == b); +} + +} /* namespace bt2 */ + +#endif /* BABELTRACE_CPP_COMMON_BT2_IDENTITY_VIEW_HPP */ diff --git a/src/cpp-common/bt2/trace-ir.hpp b/src/cpp-common/bt2/trace-ir.hpp index d0e75a86..6067c8cf 100644 --- a/src/cpp-common/bt2/trace-ir.hpp +++ b/src/cpp-common/bt2/trace-ir.hpp @@ -691,6 +691,11 @@ public: return bt_trace_get_uid(this->libObjPtr()); } + IdentityView identity() const noexcept + { + return IdentityView {this->nameSpace(), this->name(), this->uid()}; + } + CommonTrace uuid(const bt2c::UuidView& uuid) const noexcept { bt_trace_set_uuid(this->libObjPtr(), uuid.begin()); diff --git a/src/cpp-common/bt2c/c-string-view.hpp b/src/cpp-common/bt2c/c-string-view.hpp index 52eacaca..5878982a 100644 --- a/src/cpp-common/bt2c/c-string-view.hpp +++ b/src/cpp-common/bt2c/c-string-view.hpp @@ -266,4 +266,19 @@ inline void operator+=(std::string& lhs, bt2c::CStringView rhs) lhs += rhs.data(); } +/* + * Returns true if (one of): + * + * • `a` and `b` are both non-`nullptr` and equal. + * • `a` and `b` are both `nullptr`. + */ +inline bool equalOrBothNull(const bt2c::CStringView a, const bt2c::CStringView b) +{ + if (a && b) { + return a == b; + } else { + return static_cast(a) == static_cast(b); + } +} + #endif /* BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP */ diff --git a/src/lib/graph/iterator.c b/src/lib/graph/iterator.c index 1724af33..6e8bbfad 100644 --- a/src/lib/graph/iterator.c +++ b/src/lib/graph/iterator.c @@ -688,10 +688,36 @@ void assert_post_dev_clock_classes_are_compatible_one( enum bt_clock_correlation_validator_error_type type; const bt_clock_class *actual_clock_cls; const bt_clock_class *ref_clock_cls; + const int graph_mip_version = iterator->graph->mip_version; if (!bt_clock_correlation_validator_validate_message( - iterator->correlation_validator, msg, &type, - &actual_clock_cls, &ref_clock_cls)) { + iterator->correlation_validator, msg, + graph_mip_version, &type, &actual_clock_cls, + &ref_clock_cls)) { +#define CC_ORIGIN_FMT(_prefix) \ + _prefix "cc-origin-ns=%s, " \ + _prefix "cc-origin-name=%s, " \ + _prefix "cc-origin-uid=%s" +#define EXP_CC_ORIGIN_FMT CC_ORIGIN_FMT("expected-") + +#define CC_ORIGIN_VALUES(_clock_cls) \ + (_clock_cls)->origin.ns ? (_clock_cls)->origin.ns : "(null)", \ + (_clock_cls)->origin.name ? (_clock_cls)->origin.name : "(null)", \ + (_clock_cls)->origin.uid ? (_clock_cls)->origin.uid : "(null)" +#define EXP_CC_ORIGIN_VALUES CC_ORIGIN_VALUES(ref_clock_cls) + +#define CC_ID_FMT(_prefix) \ + _prefix "cc-ns=%s, " \ + _prefix "cc-name=%s, " \ + _prefix "cc-uid=%s" +#define EXP_CC_ID_FMT CC_ID_FMT("expected-") + +#define CC_ID_VALUES(_clock_cls) \ + (_clock_cls)->ns ? (_clock_cls)->ns : "(null)", \ + (_clock_cls)->name ? (_clock_cls)->name : "(null)", \ + (_clock_cls)->uid ? (_clock_cls)->uid : "(null)" +#define EXP_CC_ID_VALUES CC_ID_VALUES(ref_clock_cls) + switch (type) { case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_NO_CLOCK_CLASS_GOT_ONE: BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, @@ -699,53 +725,142 @@ void assert_post_dev_clock_classes_are_compatible_one( "Expecting no clock class, got one: %![cc-]+K", actual_clock_cls); - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_NO_CLOCK_CLASS: - BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "stream-class-has-clock-class-with-unix-epoch-origin", false, - "Expecting a clock class with Unix epoch origin, got none."); + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_NO_CLOCK_CLASS: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "stream-class-has-clock-class-with-unix-epoch-origin", false, + "Expecting a clock class with a Unix epoch origin, got none."); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "stream-class-has-clock-class-with-known-origin", false, + "Expecting a clock class with a known origin, got none: " EXP_CC_ORIGIN_FMT, + EXP_CC_ORIGIN_VALUES); + } - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNIX_GOT_UNKNOWN_ORIGIN: - BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "clock-class-has-unix-epoch-origin", false, - "Expecting a clock class with Unix epoch origin, got one with " - "unknown origin: %![cc-]+K", - actual_clock_cls); + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_NO_CLOCK_CLASS: - BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "stream-class-has-clock-class-with-uuid", false, - "Expecting a clock class with unknown origin and a specific UUID, " - "got none: expected-uuid=%!u", - bt_clock_class_get_uuid(ref_clock_cls)); + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_UNKNOWN_ORIGIN: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-unix-epoch-origin", false, + "Expecting a clock class with a Unix epoch origin, got one with an" + "unknown origin: %![cc-]+K", + actual_clock_cls); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-known-origin", false, + "Expecting a clock class with a known origin: %![cc-]+K, " EXP_CC_ORIGIN_FMT, + actual_clock_cls, EXP_CC_ORIGIN_VALUES); + } - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_UNIX_ORIGIN: - BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "clock-class-has-unknown-origin", false, - "Expecting a clock class with unknown origin and a specific UUID, " - "got one with Unix epoch origin: %![cc-]+K, expected-uuid=%!u", - actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_WITHOUT_UUID: + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_KNOWN_GOT_OTHER_ORIGIN: + BT_ASSERT(graph_mip_version > 0); BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "clock-class-has-uuid", false, - "Expecting a clock class with unknown origin and a specific UUID, " - "got one without a UUID: %![cc-]+K, expected-uuid=%!u", - actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + "clock-class-has-expected-origin", false, + "Expecting a clock class with a specific origin: %![cc-]+K, " EXP_CC_ORIGIN_FMT, + actual_clock_cls, EXP_CC_ORIGIN_VALUES); + + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_NO_CLOCK_CLASS: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "stream-class-has-clock-class-with-uuid", false, + "Expecting a clock class with an unknown origin and a specific UUID, " + "got none: expected-uuid=%!u", + bt_clock_class_get_uuid(ref_clock_cls)); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "stream-class-has-clock-class-with-id", false, + "Expecting a clock class with an unknown origin and a specific identity, " + "got none: " EXP_CC_ID_FMT, + EXP_CC_ID_VALUES); + } - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_UUID_GOT_OTHER_UUID: - BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, - "clock-class-has-expected-uuid", false, - "Expecting a clock class with unknown origin and a specific UUID, " - "got one with a different UUID: %![cc-]+K, expected-uuid=%!u", - actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); + + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_KNOWN_ORIGIN: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-unknown-origin", false, + "Expecting a clock class with an unknown origin and a specific UUID, " + "got one with a Unix epoch origin: %![cc-]+K, expected-uuid=%!u", + actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-unknown-origin", false, + "Expecting a clock class with an unknown origin and a specific identity, " + "got one with a known origin: %![cc-]+K, " EXP_CC_ID_FMT, + actual_clock_cls, EXP_CC_ID_VALUES); + } + + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); + + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_WITHOUT_ID: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-uuid", false, + "Expecting a clock class with an unknown origin and a specific UUID, " + "got one without a UUID: %![cc-]+K, expected-uuid=%!u", + actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-id", false, + "Expecting a clock class with an unknown origin and a specific identity, " + "got one without identity: %![cc-]+K, " EXP_CC_ID_FMT, + actual_clock_cls, EXP_CC_ID_VALUES); + } + + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); + + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITH_ID_GOT_OTHER_ID: + if (graph_mip_version == 0) { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-expected-uuid", false, + "Expecting a clock class with an unknown origin and a specific UUID, " + "got one with a different UUID: %![cc-]+K, expected-uuid=%!u", + actual_clock_cls, bt_clock_class_get_uuid(ref_clock_cls)); + } else { + BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, + "clock-class-has-expected-id", false, + "Expecting a clock class with an unknown origin and a specific identity, " + "got one with a different identity: %![cc-]+K, " EXP_CC_ID_FMT, + actual_clock_cls, EXP_CC_ID_VALUES); + } + + /* + * GCC gives bogus `-Wimplicit-fallthrough` + * warnings: convince it that it's not possible. + */ + bt_common_abort(); - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_NO_CLOCK_CLASS: + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_NO_CLOCK_CLASS: BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, "stream-class-has-clock-class", false, "Expecting a clock class, got none: %![expected-cc-]+K", ref_clock_cls); - case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_UUID_GOT_OTHER_CLOCK_CLASS: + case BT_CLOCK_CORRELATION_VALIDATOR_ERROR_TYPE_EXPECTING_ORIGIN_UNKNOWN_WITHOUT_ID_GOT_OTHER_CLOCK_CLASS: BT_ASSERT_POST_DEV(NEXT_METHOD_NAME, "clock-class-is-expected", false, "Unexpected clock class: %![expected-cc-]+K, %![actual-cc-]+K", diff --git a/src/plugins/common/muxing/muxing.cpp b/src/plugins/common/muxing/muxing.cpp index a9984010..700d86db 100644 --- a/src/plugins/common/muxing/muxing.cpp +++ b/src/plugins/common/muxing/muxing.cpp @@ -166,6 +166,20 @@ int MessageComparator::_compareOptUuids(const bt2s::optional& left, const bt2s::optional& right) noexcept; + static int _compareIdentities(const bt2::IdentityView& left, + const bt2::IdentityView& right) noexcept; static int _compareEventClasses(const bt2::ConstEventClass left, const bt2::ConstEventClass right) noexcept; static int _compareClockClasses(const bt2::ConstClockClass left, @@ -52,6 +59,8 @@ private: const bt2::ConstMessage right) noexcept; static int _compareMessages(const bt2::ConstMessage left, const bt2::ConstMessage right) noexcept; + + std::uint64_t _mGraphMipVersion; }; } /* namespace muxing */ diff --git a/src/plugins/ctf/lttng-live/lttng-live.hpp b/src/plugins/ctf/lttng-live/lttng-live.hpp index 563cf14c..96703cbb 100644 --- a/src/plugins/ctf/lttng-live/lttng-live.hpp +++ b/src/plugins/ctf/lttng-live/lttng-live.hpp @@ -341,7 +341,8 @@ struct lttng_live_msg_iter const bt2::SelfComponent selfCompParam, const bt2::SelfMessageIterator selfMsgIter) : logger {parentLogger, "PLUGIN/SRC.CTF.LTTNG-LIVE/MSG-ITER"}, - selfComp {selfCompParam}, selfMsgIter {selfMsgIter} + selfComp {selfCompParam}, selfMsgIter {selfMsgIter}, + msgComparator {selfComp.graphMipVersion()} { } diff --git a/src/plugins/utils/muxer/msg-iter.cpp b/src/plugins/utils/muxer/msg-iter.cpp index 3cdc1a54..abfd6104 100644 --- a/src/plugins/utils/muxer/msg-iter.cpp +++ b/src/plugins/utils/muxer/msg-iter.cpp @@ -24,7 +24,7 @@ namespace bt2mux { MsgIter::MsgIter(const bt2::SelfMessageIterator selfMsgIter, const bt2::SelfMessageIteratorConfiguration cfg, bt2::SelfComponentOutputPort) : bt2::UserMessageIterator {selfMsgIter, "MSG-ITER"}, - _mHeap {_HeapComparator {_mLogger}} + _mHeap {_HeapComparator {_mLogger, selfMsgIter.component().graphMipVersion()}} { /* * Create one upstream message iterator for each connected @@ -232,6 +232,66 @@ void MsgIter::_seekBeginning() } } +namespace { + +std::string formatClkClsOrigin(const bt2::ClockOriginView clkClsOrigin, const char * const prefix, + const std::uint64_t graphMipVersion) +{ + if (graphMipVersion == 0) { + return fmt::format("{}clock-class-origin-is-unix-epoch={}", prefix, + clkClsOrigin.isUnixEpoch()); + } else { + return fmt::format("{0}clock-class-origin-ns={1}, {0}clock-class-origin-name={2}, " + "{0}clock-class-origin-uid={3}", + prefix, clkClsOrigin.nameSpace(), clkClsOrigin.name(), + clkClsOrigin.uid()); + } +} + +std::string formatClkClsId(const bt2::ConstClockClass clkCls, const char * const prefix, + const std::uint64_t graphMipVersion) +{ + if (graphMipVersion == 0) { + if (const auto uuid = clkCls.uuid()) { + return fmt::format("{}clock-class-uuid={}", prefix, *uuid); + } else { + return fmt::format("{}clock-class-uuid=(none)", prefix); + } + } else { + return fmt::format("{0}clock-class-ns={1}, {0}clock-class-name={2}, {0}clock-class-uid={3}", + prefix, clkCls.nameSpace(), clkCls.name(), clkCls.uid()); + } +} + +std::string formatClkCls(const bt2::ConstClockClass clkCls, const char * const prefix, + const std::uint64_t graphMipVersion) +{ + if (graphMipVersion == 0) { + return fmt::format("{}clock-class-addr={}, {}clock-class-name={}, {}, {}", prefix, + fmt::ptr(clkCls.libObjPtr()), prefix, clkCls.name(), + formatClkClsId(clkCls, prefix, graphMipVersion), + formatClkClsOrigin(clkCls.origin(), prefix, graphMipVersion)); + } else { + return fmt::format("{}clock-class-addr={}, {}, {}", prefix, fmt::ptr(clkCls.libObjPtr()), + formatClkClsId(clkCls, prefix, graphMipVersion), + formatClkClsOrigin(clkCls.origin(), prefix, graphMipVersion)); + } +} + +std::string formatStreamCls(const bt2ccv::ClockCorrelationError& error, + const bool withTrailingComma) +{ + if (const auto streamCls = error.streamCls()) { + return fmt::format("stream-class-addr={}, stream-class-name=\"{}\", stream-class-id={}{}", + fmt::ptr(streamCls->libObjPtr()), streamCls->name(), streamCls->id(), + withTrailingComma ? ", " : ""); + } else { + return std::string {}; + } +} + +} /* namespace */ + void MsgIter::_validateMsgClkCls(const bt2::ConstMessage msg) { if (G_LIKELY(!msg.isStreamBeginning() && !msg.isMessageIteratorInactivity())) { @@ -246,109 +306,138 @@ void MsgIter::_validateMsgClkCls(const bt2::ConstMessage msg) BT_CPPLOGD("Validating the clock class of a message: msg-type={}", msg.type()); try { - _mClkCorrValidator.validate(msg); + _mClkCorrValidator.validate(msg, this->_component()._graphMipVersion()); } catch (const bt2ccv::ClockCorrelationError& error) { using Type = bt2ccv::ClockCorrelationError::Type; const auto actualClkCls = error.actualClockCls(); const auto refClkCls = error.refClockCls(); - const auto formatClkClsOrigin = [](const bt2::ConstClockClass clockCls, - const char * const prefix) { - return fmt::format("{}clock-class-origin-is-unix-epoch={}", prefix, - clockCls.origin().isUnixEpoch()); - }; - const auto formatClkClsUuid = [](const bt2::ConstClockClass clockCls, - const char * const prefix) { - if (const auto uuid = clockCls.uuid()) { - return fmt::format("{}clock-class-uuid={}", prefix, *uuid); - } else { - return fmt::format("{}clock-class-uuid=(none)", prefix); - } + const auto graphMipVersion = this->_component()._graphMipVersion(); + const auto formatExpClkClsOrigin = [&] { + return formatClkClsOrigin(refClkCls->origin(), "expected-", graphMipVersion); }; - const auto formatExpClkClsUuid = [&] { - return formatClkClsUuid(*refClkCls, "expected-"); - }; - const auto formatClkCls = [&](const bt2::ConstClockClass clockCls, - const char * const prefix) { - return fmt::format("{}clock-class-addr={}, {}clock-class-name={}, {}, {}", prefix, - fmt::ptr(clockCls.libObjPtr()), prefix, clockCls.name(), - formatClkClsOrigin(clockCls, prefix), - formatClkClsUuid(clockCls, prefix)); + const auto clkCls = [&] { + return formatClkClsId(*refClkCls, "expected", graphMipVersion); }; const auto formatActClkCls = [&] { - return formatClkCls(*actualClkCls, ""); + return formatClkCls(*actualClkCls, "", graphMipVersion); }; const auto formatExpClkCls = [&] { - return formatClkCls(*refClkCls, "expected-"); - }; - const auto formatStreamCls = [&](const bool withTrailingComma) { - if (const auto streamCls = error.streamCls()) { - return fmt::format( - "stream-class-addr={}, stream-class-name=\"{}\", stream-class-id={}{}", - fmt::ptr(streamCls->libObjPtr()), streamCls->name(), streamCls->id(), - withTrailingComma ? ", " : ""); - } else { - return std::string {}; - } + return formatClkCls(*refClkCls, "expected-", graphMipVersion); }; switch (error.type()) { case Type::ExpectingNoClockClassGotOne: BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Expecting no clock class, got one: {}{}", - formatStreamCls(true), formatActClkCls()); + formatStreamCls(error, true), formatActClkCls()); - case Type::ExpectingOriginUnixGotNoClockClass: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, "Expecting a clock class with Unix epoch origin, got none: {}", - formatStreamCls(false)); + case Type::ExpectingOriginKnownGotNoClockClass: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, "Expecting a clock class with a Unix epoch origin, got none: {}", + formatStreamCls(error, false)); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, "Expecting a clock class with a known origin, got none: {}{}", + formatStreamCls(error, true), formatExpClkClsOrigin()); + } - case Type::ExpectingOriginUnixGotUnknownOrigin: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, - "Expecting a clock class with Unix epoch origin, got one with unknown " - "origin: {}{}", - formatStreamCls(true), formatActClkCls()); + case Type::ExpectingOriginKnownGotUnknownOrigin: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with a Unix epoch origin, got one with an unknown " + "origin: {}{}", + formatStreamCls(error, true), formatActClkCls()); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with a known origin, got one with an unknown origin: " + "{}{}, {}", + formatStreamCls(error, true), formatActClkCls(), formatExpClkClsOrigin()); + } - case Type::ExpectingOriginUnknownWithUuidGotNoClockClass: + case Type::ExpectingOriginKnownGotOtherOrigin: + BT_ASSERT(graphMipVersion > 0); BT_CPPLOGE_APPEND_CAUSE_AND_THROW( bt2::Error, - "Expecting a clock class with unknown origin and a specific UUID, got none: {}", - formatStreamCls(true), formatExpClkClsUuid()); + "Expecting a clock class with a known origin, got one with a wrong origin: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), formatExpClkClsOrigin()); + + case Type::ExpectingOriginUnknownWithIdGotNoClockClass: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific UUID, got none: {}{}", + formatStreamCls(error, true), clkCls()); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific identity, got none: {}{}", + formatStreamCls(error, true), clkCls()); + } - case Type::ExpectingOriginUnknownWithUuidGotUnixOrigin: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, - "Expecting a clock class with unknown origin and a specific UUID, got one " - "with Unix epoch origin: {}{}, {}", - formatStreamCls(true), formatActClkCls(), formatExpClkClsUuid()); + case Type::ExpectingOriginUnknownWithIdGotKnownOrigin: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific UUID, got one " + "with a Unix epoch origin: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific identity, got one " + "with a known origin: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } - case Type::ExpectingOriginUnknownWithUuidGotWithoutUuid: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, - "Expecting a clock class with unknown origin and a specific UUID, got one " - "without a UUID: {}{}, {}", - formatStreamCls(true), formatActClkCls(), formatExpClkClsUuid()); + case Type::ExpectingOriginUnknownWithIdGotWithoutId: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific UUID, got one " + "without a UUID: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific identity, got one " + "without identity: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } - case Type::ExpectingOriginUnknownWithUuidGotOtherUuid: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, - "Expecting a clock class with unknown origin and a specific UUID, got one with " - "a different UUID: {}{}, {}", - formatStreamCls(true), formatActClkCls(), formatExpClkClsUuid()); + case Type::ExpectingOriginUnknownWithIdGotOtherId: + if (graphMipVersion == 0) { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific UUID, got one with " + "a different UUID: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } else { + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Expecting a clock class with an unknown origin and a specific identity, got one with " + "a different identity: {}{}, {}", + formatStreamCls(error, true), formatActClkCls(), clkCls()); + } - case Type::ExpectingOriginUnknownWithoutUuidGotNoClockClass: + case Type::ExpectingOriginUnknownWithoutIdGotNoClockClass: BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Expecting a clock class, got none: {}{}", - formatStreamCls(true), formatExpClkCls()); + formatStreamCls(error, true), formatExpClkCls()); - case Type::ExpectingOriginUnknownWithoutUuidGotOtherClockClass: + case Type::ExpectingOriginUnknownWithoutIdGotOtherClockClass: BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Unexpected clock class: {}{}, {}", - formatStreamCls(true), formatActClkCls(), + formatStreamCls(error, true), formatActClkCls(), formatExpClkCls()); } } } -MsgIter::_HeapComparator::_HeapComparator(const bt2c::Logger& logger) : _mLogger {logger} +MsgIter::_HeapComparator::_HeapComparator(const bt2c::Logger& logger, + const std::uint64_t graphMipVersion) : + _mLogger {logger}, + _mMsgComparator {graphMipVersion} { } diff --git a/src/plugins/utils/muxer/msg-iter.hpp b/src/plugins/utils/muxer/msg-iter.hpp index e359c39e..1fe1b679 100644 --- a/src/plugins/utils/muxer/msg-iter.hpp +++ b/src/plugins/utils/muxer/msg-iter.hpp @@ -32,7 +32,7 @@ private: class _HeapComparator final { public: - explicit _HeapComparator(const bt2c::Logger& logger); + explicit _HeapComparator(const bt2c::Logger& logger, const std::uint64_t graphMipVersion); bool operator()(const UpstreamMsgIter *upstreamMsgIterA, const UpstreamMsgIter *upstreamMsgIterB) const noexcept; diff --git a/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp b/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp index 34429871..1f98ff00 100644 --- a/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp +++ b/tests/lib/conds/clk-cls-compat-postconds-triggers.cpp @@ -9,6 +9,7 @@ #include "../utils/run-in.hpp" #include "clk-cls-compat-postconds-triggers.hpp" +#include "common.hpp" namespace { @@ -97,6 +98,12 @@ __attribute__((used)) const char *format_as(const ClockClsCompatRunIn::MsgType m const bt2c::Uuid uuidA {"f00aaf65-ebec-4eeb-85b2-fc255cf1aa8a"}; const bt2c::Uuid uuidB {"03482981-a77b-4d7b-94c4-592bf9e91785"}; +constexpr const char *nsA = "namespace-a"; +constexpr const char *nameA = "name-a"; +constexpr const char *uidA = "uid-a"; +constexpr const char *nsB = "namespace-b"; +constexpr const char *nameB = "name-b"; +constexpr const char *uidB = "uid-b"; } /* namespace */ @@ -111,7 +118,7 @@ void addClkClsCompatTriggers(CondTriggers& triggers) const auto addValidCases = [&triggers]( const ClockClsCompatRunIn::CreateClockCls& createClockCls1, const ClockClsCompatRunIn::CreateClockCls& createClockCls2, - const char * const condId) { + const char * const condId, std::uint64_t graphMipVersion) { /* * Add triggers for all possible combinations of message types. * @@ -140,109 +147,212 @@ void addClkClsCompatTriggers(CondTriggers& triggers) triggers.emplace_back(bt2s::make_unique>( ClockClsCompatRunIn {msgType1, createClockCls1, msgType2, createClockCls2}, - CondTrigger::Type::Post, condId, 0u, fmt::format("{}-{}", msgType1, msgType2))); + CondTrigger::Type::Post, condId, graphMipVersion, + fmt::format("mip{}-{}-{}", graphMipVersion, msgType1, msgType2))); } } }; - addValidCases( - {}, - [](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(); - }, - {}, - "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; - }, - {}, "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-unknown-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; - }, - {}, "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"); + forEachMipVersion([&](const std::uint64_t graphMipVersion) { + addValidCases( + {}, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + "message-iterator-class-next-method:stream-class-has-no-clock-class", graphMipVersion); + + if (graphMipVersion == 0) { + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(true); + return clockCls; + }, + {}, + "message-iterator-class-next-method:stream-class-has-clock-class-with-unix-epoch-origin", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(true); + return clockCls; + }, + [](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", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + {}, "message-iterator-class-next-method:stream-class-has-clock-class-with-uuid", + graphMipVersion); + + 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(true); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-unknown-origin", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).uuid(uuidA); + return clkCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-uuid", graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).uuid(uuidA); + return clkCls; + }, + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).uuid(uuidB); + return clkCls; + }, + "message-iterator-class-next-method:clock-class-has-expected-uuid", + graphMipVersion); + } else { + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(true); + return clockCls; + }, + {}, + "message-iterator-class-next-method:stream-class-has-clock-class-with-known-origin", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(true); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-known-origin", graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + {}, "message-iterator-class-next-method:stream-class-has-clock-class-with-id", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(true); + return clockCls; + }, + "message-iterator-class-next-method:clock-class-has-unknown-origin", + graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).nameSpace(nsA).name(nameA).uid(uidA); + return clkCls; + }, + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false); + return clkCls; + }, + "message-iterator-class-next-method:clock-class-has-id", graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).nameSpace(nsA).name(nameA).uid(uidA); + return clkCls; + }, + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false).nameSpace(nsB).name(nameB).uid(uidB); + return clkCls; + }, + "message-iterator-class-next-method:clock-class-has-expected-id", graphMipVersion); + } + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false); + return clkCls; + }, + {}, "message-iterator-class-next-method:stream-class-has-clock-class", graphMipVersion); + + addValidCases( + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false); + return clkCls; + }, + [](const bt2::SelfComponent self) { + const auto clkCls = self.createClockClass(); + + clkCls->originIsUnixEpoch(false); + return clkCls; + }, + "message-iterator-class-next-method:clock-class-is-expected", graphMipVersion); + }); } diff --git a/tests/lib/utils/run-in.cpp b/tests/lib/utils/run-in.cpp index 56f637ab..5d3c5dc0 100644 --- a/tests/lib/utils/run-in.cpp +++ b/tests/lib/utils/run-in.cpp @@ -124,10 +124,3 @@ void runIn(RunIn& runIn, const std::uint64_t graphMipVersion) /* Run graph (executes `msgIterCtxFunc`) */ graph->run(); } - -void forEachMipVersion(const std::function& fn) -{ - for (std::uint64_t v = 0; v <= bt_get_maximal_mip_version(); ++v) { - fn(v); - } -} diff --git a/tests/lib/utils/run-in.hpp b/tests/lib/utils/run-in.hpp index 8067f438..c55a3a7b 100644 --- a/tests/lib/utils/run-in.hpp +++ b/tests/lib/utils/run-in.hpp @@ -54,9 +54,4 @@ public: */ void runIn(RunIn& runIn, std::uint64_t graphMipVersion); -/* - * Calls `fn` for each possible MIP version. - */ -void forEachMipVersion(const std::function& fn); - #endif /* BABELTRACE_TESTS_LIB_UTILS_RUN_IN_HPP */ diff --git a/tests/plugins/flt.utils.muxer/test-clock-compatibility.cpp b/tests/plugins/flt.utils.muxer/test-clock-compatibility.cpp index 02a72be1..0f233470 100644 --- a/tests/plugins/flt.utils.muxer/test-clock-compatibility.cpp +++ b/tests/plugins/flt.utils.muxer/test-clock-compatibility.cpp @@ -12,6 +12,8 @@ #include "cpp-common/bt2c/call.hpp" #include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */ +#include "common.hpp" + #include "tap/tap.h" namespace { @@ -155,10 +157,11 @@ class ErrorTestCase final public: /* Intentionally not explicit */ ErrorTestCase(CreateClockClass createClockClass1Param, CreateClockClass createClockClass2Param, - const char * const testName, const char * const expectedCauseMsg) : + const std::uint64_t graphMipVersion, const char * const testName, + const char * const expectedCauseMsg) : _mCreateClockClass1 {createClockClass1Param}, - _mCreateClockClass2 {createClockClass2Param}, _mTestName {testName}, - _mExpectedCauseMsg {expectedCauseMsg} + _mCreateClockClass2 {createClockClass2Param}, _mGraphMipVersion {graphMipVersion}, + _mTestName {testName}, _mExpectedCauseMsg {expectedCauseMsg} { } @@ -169,6 +172,7 @@ private: CreateClockClass _mCreateClockClass1; CreateClockClass _mCreateClockClass2; + std::uint64_t _mGraphMipVersion; const char *_mTestName; const char *_mExpectedCauseMsg; }; @@ -230,16 +234,16 @@ void ErrorTestCase::run() const noexcept } std::string makeSpecTestName(const char * const testName, const MsgType msgType1, - const MsgType msgType2) + const MsgType msgType2, const std::uint64_t graphMipVersion) { - return fmt::format("{} ({}, {})", testName, msgType1, msgType2); + return fmt::format("{} ({}, {}, MIP {})", testName, msgType1, msgType2, graphMipVersion); } void ErrorTestCase::_runOne(const MsgType msgType1, const MsgType msgType2) const noexcept { - const auto specTestName = makeSpecTestName(_mTestName, msgType1, msgType2); + const auto specTestName = makeSpecTestName(_mTestName, msgType1, msgType2, _mGraphMipVersion); const auto srcCompCls = bt2::SourceComponentClass::create(); - const auto graph = bt2::Graph::create(0); + const auto graph = bt2::Graph::create(_mGraphMipVersion); { /* @@ -328,113 +332,229 @@ void ErrorTestCase::_runOne(const MsgType msgType1, const MsgType msgType2) cons const bt2c::Uuid uuidA {"f00aaf65-ebec-4eeb-85b2-fc255cf1aa8a"}; const bt2c::Uuid uuidB {"03482981-a77b-4d7b-94c4-592bf9e91785"}; -const ErrorTestCase errorTestCases[] = { - {noClockClass, - [](const bt2::SelfComponent self) { - return self.createClockClass(); - }, - "no clock class followed by clock class", "Expecting no clock class, got one"}, - - {[](const bt2::SelfComponent self) { - return self.createClockClass(); - }, - noClockClass, "clock class with Unix epoch origin followed by no clock class", - "Expecting a clock class with Unix epoch origin, got none"}, - - {[](const bt2::SelfComponent self) { - return self.createClockClass(); - }, - [](const bt2::SelfComponent self) { - const auto clockCls = self.createClockClass(); - - clockCls->originIsUnixEpoch(false); - return clockCls; - }, - "clock class with Unix epoch origin followed by clock class with unknown origin", - "Expecting a clock class with Unix epoch origin, got one with unknown origin"}, - - {[](const bt2::SelfComponent self) { - const auto clockCls = self.createClockClass(); - - clockCls->originIsUnixEpoch(false).uuid(uuidA); - return clockCls; - }, - noClockClass, "clock class with unknown origin and a UUID followed by no clock class", - "Expecting a clock class with unknown origin and a specific UUID, got none"}, - - {[](const bt2::SelfComponent self) { - const auto clockCls = self.createClockClass(); - - clockCls->originIsUnixEpoch(false).uuid(uuidA); - return clockCls; - }, - [](const bt2::SelfComponent self) { - return self.createClockClass(); - }, - "clock class with unknown origin and a UUID followed by clock class with Unix epoch origin", - "Expecting a clock class with unknown origin and a specific UUID, got one with Unix epoch origin"}, - - {[](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; - }, - "clock class with unknown origin and a UUID followed by clock class with unknown origin and no UUID", - "Expecting a clock class with unknown origin and a specific UUID, got one without a UUID"}, - - {[](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; - }, - "clock class with unknown origin and a UUID followed by clock class with unknown origin and another UUID", - "Expecting a clock class with unknown origin and a specific UUID, got one with a different UUID"}, - - {[](const bt2::SelfComponent self) { - const auto clockCls = self.createClockClass(); - - clockCls->originIsUnixEpoch(false); - return clockCls; - }, - noClockClass, "clock class with unknown origin and no UUID followed by no clock class", - "Expecting a clock class, got none"}, - - {[](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; - }, - "clock class with unknown origin and no UUID followed by different clock class", - "Unexpected clock class"}, -}; +std::vector createErrorTestCases() +{ + std::vector cases; + + forEachMipVersion([&](const std::uint64_t graphMipVersion) { + cases.emplace_back( + noClockClass, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + graphMipVersion, "no clock class followed by clock class", + "Expecting no clock class, got one"); + + if (graphMipVersion == 0) { + cases.emplace_back( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + noClockClass, graphMipVersion, + "clock class with a Unix epoch origin followed by no clock class", + "Expecting a clock class with a Unix epoch origin, got none"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + graphMipVersion, + "clock class with a Unix epoch origin followed by clock class with an unknown origin", + "Expecting a clock class with a Unix epoch origin, got one with an unknown origin"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + noClockClass, graphMipVersion, + "clock class with an unknown origin and a UUID followed by no clock class", + "Expecting a clock class with an unknown origin and a specific UUID, got none"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).uuid(uuidA); + return clockCls; + }, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + graphMipVersion, + "clock class with an unknown origin and a UUID followed by clock class with a Unix epoch origin", + "Expecting a clock class with an unknown origin and a specific UUID, got one with a Unix epoch origin"); + + cases.emplace_back( + [](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; + }, + graphMipVersion, + "clock class with an unknown origin and a UUID followed by clock class with an unknown origin and no UUID", + "Expecting a clock class with an unknown origin and a specific UUID, got one without a UUID"); + + cases.emplace_back( + [](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; + }, + graphMipVersion, + "clock class with an unknown origin and a UUID followed by clock class with an unknown origin and another UUID", + "Expecting a clock class with an unknown origin and a specific UUID, got one with a different UUID"); + } else { + cases.emplace_back( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + noClockClass, graphMipVersion, + "clock class a known origin followed by no clock class", + "Expecting a clock class with a known origin, got none"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + graphMipVersion, + "clock class with a known origin followed by clock class with an unknown origin", + "Expecting a clock class with a known origin, got one with an unknown origin"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + noClockClass, graphMipVersion, + "clock class with an unknown origin and an identity followed by no clock class", + "Expecting a clock class with an unknown origin and a specific identity, got none"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + [](const bt2::SelfComponent self) { + return self.createClockClass(); + }, + graphMipVersion, + "clock class with an unknown origin and an identity followed by clock class with a known origin", + "Expecting a clock class with an unknown origin and a specific identity, got one with a known origin"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + graphMipVersion, + "clock class with an unknown origin and an identity followed by clock class with an unknown origin and no identity", + "Expecting a clock class with an unknown origin and a specific identity, got one without identity"); + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false).nameSpace("ze-ns").name("ze-name").uid( + "ze-uid"); + return clockCls; + }, + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false) + .nameSpace("another-ns") + .name("another-name") + .uid("another-uid"); + return clockCls; + }, + graphMipVersion, + "clock class with an unknown origin and an identity followed by clock class with an unknown origin and another identity", + "Expecting a clock class with an unknown origin and a specific identity, got one with a different identity"); + } + + cases.emplace_back( + [](const bt2::SelfComponent self) { + const auto clockCls = self.createClockClass(); + + clockCls->originIsUnixEpoch(false); + return clockCls; + }, + noClockClass, graphMipVersion, + "clock class with an unknown origin and no UUID/identity followed by no clock class", + "Expecting a clock class, got none"); + + cases.emplace_back( + [](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; + }, + graphMipVersion, + "clock class with an unknown origin and no UUID/identity followed by different clock class", + "Unexpected clock class"); + }); + + return cases; +} } /* namespace */ int main() { - plan_tests(150); + plan_tests(300); + + const auto errorTestCases = createErrorTestCases(); for (auto& errorTestCase : errorTestCases) { errorTestCase.run(); diff --git a/tests/utils/Makefile.am b/tests/utils/Makefile.am index e7065be2..8863b6cf 100644 --- a/tests/utils/Makefile.am +++ b/tests/utils/Makefile.am @@ -4,7 +4,10 @@ SUBDIRS = tap noinst_LTLIBRARIES = libtestcommon.la -libtestcommon_la_SOURCES = common.c common.h +libtestcommon_la_SOURCES = \ + common.c \ + common.h \ + common.hpp # Directories added to EXTRA_DIST will be recursively copied to the distribution. EXTRA_DIST = python diff --git a/tests/utils/common.hpp b/tests/utils/common.hpp new file mode 100644 index 00000000..6d2b0f7e --- /dev/null +++ b/tests/utils/common.hpp @@ -0,0 +1,22 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2024 EfficiOS Inc. + */ + +#ifndef BABELTRACE_TESTS_UTILS_COMMON_HPP +#define BABELTRACE_TESTS_UTILS_COMMON_HPP + +#include + +#include + +template +void forEachMipVersion(FuncT&& func) +{ + for (std::uint64_t v = 0; v <= bt_get_maximal_mip_version(); ++v) { + func(v); + } +} + +#endif /* BABELTRACE_TESTS_UTILS_COMMON_HPP */ -- 2.34.1