2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2024 EfficiOS Inc.
7 #include "cpp-common/bt2s/make-unique.hpp"
8 #include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
10 #include "../utils/run-in.hpp"
11 #include "clk-cls-compat-postconds-triggers.hpp"
16 * `RunIn` implementation to trigger clock (in)compatibility postcondition
19 class ClockClsCompatRunIn final
: public RunIn
28 using CreateClockCls
= bt2::ClockClass::Shared (*)(bt2::SelfComponent
);
30 explicit ClockClsCompatRunIn(const MsgType msgType1
, const CreateClockCls createClockCls1
,
31 const MsgType msgType2
,
32 const CreateClockCls createClockCls2
) noexcept
:
33 _mMsgType1
{msgType1
},
34 _mMsgType2
{msgType2
}, _mCreateClockCls1
{createClockCls1
},
35 _mCreateClockCls2
{createClockCls2
}
39 void onMsgIterNext(bt2::SelfMessageIterator self
, bt2::ConstMessageArray
& msgs
) override
41 /* In case the expected assertion doesn't trigger, avoid looping indefinitely. */
42 BT_ASSERT(!_mBeenThere
);
44 const auto traceCls
= self
.component().createTraceClass();
45 const auto trace
= traceCls
->instantiate();
47 msgs
.append(this->_createOneMsg(self
, _mMsgType1
, _mCreateClockCls1
, *trace
));
48 msgs
.append(this->_createOneMsg(self
, _mMsgType2
, _mCreateClockCls2
, *trace
));
53 static bt2::Message::Shared
_createOneMsg(const bt2::SelfMessageIterator self
,
54 const MsgType msgType
,
55 const CreateClockCls createClockCls
,
56 const bt2::Trace trace
)
58 const auto clockCls
= createClockCls(self
.component());
61 case MsgType::StreamBeg
:
63 const auto streamCls
= trace
.cls().createStreamClass();
66 streamCls
->defaultClockClass(*clockCls
);
69 return self
.createStreamBeginningMessage(*streamCls
->instantiate(trace
));
72 case MsgType::MsgIterInactivity
:
74 return self
.createMessageIteratorInactivityMessage(*clockCls
, 12);
80 MsgType _mMsgType1
, _mMsgType2
;
81 CreateClockCls _mCreateClockCls1
, _mCreateClockCls2
;
82 bool _mBeenThere
= false;
85 __attribute__((used
)) const char *format_as(const ClockClsCompatRunIn::MsgType msgType
)
88 case ClockClsCompatRunIn::MsgType::StreamBeg
:
91 case ClockClsCompatRunIn::MsgType::MsgIterInactivity
:
98 bt2::ClockClass::Shared
noClockClass(bt2::SelfComponent
) noexcept
100 return bt2::ClockClass::Shared
{};
103 const bt2c::Uuid uuidA
{"f00aaf65-ebec-4eeb-85b2-fc255cf1aa8a"};
104 const bt2c::Uuid uuidB
{"03482981-a77b-4d7b-94c4-592bf9e91785"};
109 * Add clock class compatibility postcondition failures triggers.
111 * Each trigger below makes a message iterator return two messages with
112 * incompatible clock classes, leading to a postcondition failure.
114 void addClkClsCompatTriggers(CondTriggers
& triggers
)
116 const auto addValidCases
= [&triggers
](
117 const ClockClsCompatRunIn::CreateClockCls createClockCls1
,
118 const ClockClsCompatRunIn::CreateClockCls createClockCls2
,
119 const char * const condId
) {
121 * Add triggers for all possible combinations of message types.
123 * It's not possible to create message iterator inactivity messages
124 * without a clock class.
126 static constexpr std::array
<ClockClsCompatRunIn::MsgType
, 2> msgTypes
{
127 ClockClsCompatRunIn::MsgType::StreamBeg
,
128 ClockClsCompatRunIn::MsgType::MsgIterInactivity
,
131 const auto isInvalidCase
= [](const ClockClsCompatRunIn::MsgType msgType
,
132 const ClockClsCompatRunIn::CreateClockCls createClockCls
) {
133 return msgType
== ClockClsCompatRunIn::MsgType::MsgIterInactivity
&&
134 createClockCls
== noClockClass
;
137 for (const auto msgType1
: msgTypes
) {
138 if (isInvalidCase(msgType1
, createClockCls1
)) {
142 for (const auto msgType2
: msgTypes
) {
143 if (isInvalidCase(msgType2
, createClockCls2
)) {
147 triggers
.emplace_back(bt2s::make_unique
<RunInCondTrigger
<ClockClsCompatRunIn
>>(
148 ClockClsCompatRunIn
{msgType1
, createClockCls1
, msgType2
, createClockCls2
},
149 CondTrigger::Type::Post
, condId
, fmt::format("{}-{}", msgType1
, msgType2
)));
156 [](const bt2::SelfComponent self
) {
157 return self
.createClockClass();
159 "message-iterator-class-next-method:stream-class-has-no-clock-class");
162 [](const bt2::SelfComponent self
) {
163 return self
.createClockClass();
166 "message-iterator-class-next-method:stream-class-has-clock-class-with-unix-epoch-origin");
169 [](const bt2::SelfComponent self
) {
170 return self
.createClockClass();
172 [](const bt2::SelfComponent self
) {
173 const auto clockCls
= self
.createClockClass();
175 clockCls
->originIsUnixEpoch(false);
178 "message-iterator-class-next-method:clock-class-has-unix-epoch-origin");
181 [](const bt2::SelfComponent self
) {
182 const auto clockCls
= self
.createClockClass();
184 clockCls
->originIsUnixEpoch(false).uuid(uuidA
);
187 noClockClass
, "message-iterator-class-next-method:stream-class-has-clock-class-with-uuid");
190 [](const bt2::SelfComponent self
) {
191 const auto clockCls
= self
.createClockClass();
193 clockCls
->originIsUnixEpoch(false).uuid(uuidA
);
196 [](const bt2::SelfComponent self
) {
197 return self
.createClockClass();
199 "message-iterator-class-next-method:clock-class-has-non-unix-epoch-origin");
202 [](const bt2::SelfComponent self
) {
203 const auto clockCls
= self
.createClockClass();
205 clockCls
->originIsUnixEpoch(false).uuid(uuidA
);
208 [](const bt2::SelfComponent self
) {
209 const auto clockCls
= self
.createClockClass();
211 clockCls
->originIsUnixEpoch(false);
214 "message-iterator-class-next-method:clock-class-has-uuid");
217 [](const bt2::SelfComponent self
) {
218 const auto clockCls
= self
.createClockClass();
220 clockCls
->originIsUnixEpoch(false).uuid(uuidA
);
223 [](const bt2::SelfComponent self
) {
224 const auto clockCls
= self
.createClockClass();
226 clockCls
->originIsUnixEpoch(false).uuid(uuidB
);
229 "message-iterator-class-next-method:clock-class-has-expected-uuid");
232 [](const bt2::SelfComponent self
) {
233 const auto clockCls
= self
.createClockClass();
235 clockCls
->originIsUnixEpoch(false);
238 noClockClass
, "message-iterator-class-next-method:stream-class-has-clock-class");
241 [](const bt2::SelfComponent self
) {
242 const auto clockCls
= self
.createClockClass();
244 clockCls
->originIsUnixEpoch(false);
247 [](const bt2::SelfComponent self
) {
248 const auto clockCls
= self
.createClockClass();
250 clockCls
->originIsUnixEpoch(false);
253 "message-iterator-class-next-method:clock-class-is-expected");