tests/lib/conds: test clock compatibility post conditions
[babeltrace.git] / tests / lib / conds / clk-cls-compat-postconds-triggers.cpp
CommitLineData
c3211f0a
SM
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 * Copyright (C) 2024 EfficiOS Inc.
5 */
6
7#include "cpp-common/bt2s/make-unique.hpp"
8#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
9
10#include "../utils/run-in.hpp"
11#include "clk-cls-compat-postconds-triggers.hpp"
12
13namespace {
14
15/*
16 * `RunIn` implementation to trigger clock (in)compatibility postcondition
17 * assertions.
18 */
19class ClockClsCompatRunIn final : public RunIn
20{
21public:
22 enum class MsgType
23 {
24 STREAM_BEG,
25 MSG_ITER_INACTIVITY,
26 };
27
28 using CreateClockCls = bt2::ClockClass::Shared (*)(bt2::SelfComponent);
29
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}, _mCreateClockCls2 {
35 createClockCls2}
36 {
37 }
38
39 void onMsgIterNext(bt2::SelfMessageIterator self, bt2::ConstMessageArray& msgs) override
40 {
41 /* In case the expected assertion doesn't trigger, avoid looping indefinitely. */
42 BT_ASSERT(!_mBeenThere);
43
44 const auto traceCls = self.component().createTraceClass();
45 const auto trace = traceCls->instantiate();
46
47 msgs.append(this->_createOneMsg(self, _mMsgType1, _mCreateClockCls1, *trace));
48 msgs.append(this->_createOneMsg(self, _mMsgType2, _mCreateClockCls2, *trace));
49 _mBeenThere = true;
50 }
51
52private:
53 static bt2::Message::Shared _createOneMsg(const bt2::SelfMessageIterator self,
54 const MsgType msgType,
55 const CreateClockCls createClockCls,
56 const bt2::Trace trace)
57 {
58 const auto clockCls = createClockCls(self.component());
59
60 switch (msgType) {
61 case MsgType::STREAM_BEG:
62 {
63 const auto streamCls = trace.cls().createStreamClass();
64
65 if (clockCls) {
66 streamCls->defaultClockClass(*clockCls);
67 }
68
69 return self.createStreamBeginningMessage(*streamCls->instantiate(trace));
70 }
71
72 case MsgType::MSG_ITER_INACTIVITY:
73 BT_ASSERT(clockCls);
74 return self.createMessageIteratorInactivityMessage(*clockCls, 12);
75 };
76
77 bt_common_abort();
78 }
79
80 MsgType _mMsgType1, _mMsgType2;
81 CreateClockCls _mCreateClockCls1, _mCreateClockCls2;
82 bool _mBeenThere = false;
83};
84
85__attribute__((used)) const char *format_as(const ClockClsCompatRunIn::MsgType msgType)
86{
87 switch (msgType) {
88 case ClockClsCompatRunIn::MsgType::STREAM_BEG:
89 return "sb";
90
91 case ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY:
92 return "mii";
93 }
94
95 bt_common_abort();
96}
97
98bt2::ClockClass::Shared noClockClass(bt2::SelfComponent) noexcept
99{
100 return bt2::ClockClass::Shared {};
101}
102
103const bt2c::Uuid uuidA {"f00aaf65-ebec-4eeb-85b2-fc255cf1aa8a"};
104const bt2c::Uuid uuidB {"03482981-a77b-4d7b-94c4-592bf9e91785"};
105
106} /* namespace */
107
108/*
109 * Add clock class compatibility postcondition failures triggers.
110 *
111 * Each trigger below makes a message iterator return two messages with
112 * incompatible clock classes, leading to a postcondition failure.
113 */
114void addClkClsCompatTriggers(CondTriggers& triggers)
115{
116 const auto addValidCases = [&triggers](
117 const ClockClsCompatRunIn::CreateClockCls createClockCls1,
118 const ClockClsCompatRunIn::CreateClockCls createClockCls2,
119 const char * const condId) {
120 /*
121 * Add triggers for all possible combinations of message types.
122 *
123 * It's not possible to create message iterator inactivity messages
124 * without a clock class.
125 */
126 static constexpr std::array<ClockClsCompatRunIn::MsgType, 2> msgTypes {
127 ClockClsCompatRunIn::MsgType::STREAM_BEG,
128 ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY,
129 };
130
131 const auto isInvalidCase = [](const ClockClsCompatRunIn::MsgType msgType,
132 const ClockClsCompatRunIn::CreateClockCls createClockCls) {
133 return msgType == ClockClsCompatRunIn::MsgType::MSG_ITER_INACTIVITY &&
134 createClockCls == noClockClass;
135 };
136
137 for (const auto msgType1 : msgTypes) {
138 if (isInvalidCase(msgType1, createClockCls1)) {
139 continue;
140 }
141
142 for (const auto msgType2 : msgTypes) {
143 if (isInvalidCase(msgType2, createClockCls2)) {
144 continue;
145 }
146
147 triggers.emplace_back(bt2s::make_unique<RunInCondTrigger<ClockClsCompatRunIn>>(
148 ClockClsCompatRunIn {msgType1, createClockCls1, msgType2, createClockCls2},
149 CondTrigger::Type::POST, condId, fmt::format("{}-{}", msgType1, msgType2)));
150 }
151 }
152 };
153
154 addValidCases(
155 noClockClass,
156 [](const bt2::SelfComponent self) {
157 return self.createClockClass();
158 },
159 "message-iterator-class-next-method:stream-class-has-no-clock-class");
160
161 addValidCases(
162 [](const bt2::SelfComponent self) {
163 return self.createClockClass();
164 },
165 noClockClass,
166 "message-iterator-class-next-method:stream-class-has-clock-class-with-unix-epoch-origin");
167
168 addValidCases(
169 [](const bt2::SelfComponent self) {
170 return self.createClockClass();
171 },
172 [](const bt2::SelfComponent self) {
173 const auto clockCls = self.createClockClass();
174
175 clockCls->originIsUnixEpoch(false);
176 return clockCls;
177 },
178 "message-iterator-class-next-method:clock-class-has-unix-epoch-origin");
179
180 addValidCases(
181 [](const bt2::SelfComponent self) {
182 const auto clockCls = self.createClockClass();
183
184 clockCls->originIsUnixEpoch(false).uuid(uuidA);
185 return clockCls;
186 },
187 noClockClass, "message-iterator-class-next-method:stream-class-has-clock-class-with-uuid");
188
189 addValidCases(
190 [](const bt2::SelfComponent self) {
191 const auto clockCls = self.createClockClass();
192
193 clockCls->originIsUnixEpoch(false).uuid(uuidA);
194 return clockCls;
195 },
196 [](const bt2::SelfComponent self) {
197 return self.createClockClass();
198 },
199 "message-iterator-class-next-method:clock-class-has-non-unix-epoch-origin");
200
201 addValidCases(
202 [](const bt2::SelfComponent self) {
203 const auto clockCls = self.createClockClass();
204
205 clockCls->originIsUnixEpoch(false).uuid(uuidA);
206 return clockCls;
207 },
208 [](const bt2::SelfComponent self) {
209 const auto clockCls = self.createClockClass();
210
211 clockCls->originIsUnixEpoch(false);
212 return clockCls;
213 },
214 "message-iterator-class-next-method:clock-class-has-uuid");
215
216 addValidCases(
217 [](const bt2::SelfComponent self) {
218 const auto clockCls = self.createClockClass();
219
220 clockCls->originIsUnixEpoch(false).uuid(uuidA);
221 return clockCls;
222 },
223 [](const bt2::SelfComponent self) {
224 const auto clockCls = self.createClockClass();
225
226 clockCls->originIsUnixEpoch(false).uuid(uuidB);
227 return clockCls;
228 },
229 "message-iterator-class-next-method:clock-class-has-expected-uuid");
230
231 addValidCases(
232 [](const bt2::SelfComponent self) {
233 const auto clockCls = self.createClockClass();
234
235 clockCls->originIsUnixEpoch(false);
236 return clockCls;
237 },
238 noClockClass, "message-iterator-class-next-method:stream-class-has-clock-class");
239
240 addValidCases(
241 [](const bt2::SelfComponent self) {
242 const auto clockCls = self.createClockClass();
243
244 clockCls->originIsUnixEpoch(false);
245 return clockCls;
246 },
247 [](const bt2::SelfComponent self) {
248 const auto clockCls = self.createClockClass();
249
250 clockCls->originIsUnixEpoch(false);
251 return clockCls;
252 },
253 "message-iterator-class-next-method:clock-class-is-expected");
254}
This page took 0.031314 seconds and 4 git commands to generate.