2c2a53fc2f31ebd51a15f6a55e1be04490e01c9e
[babeltrace.git] / tests / lib / utils / run-in.cpp
1 /*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 * Copyright (C) 2020-2023 EfficiOS, inc.
5 */
6
7 #include <utility>
8
9 #include "run-in.hpp"
10 #include "common/assert.h"
11
12 struct RunInData final
13 {
14 RunInCompClsQueryFunc compClsCtxFunc;
15 RunInCompClsInitFunc compCtxFunc;
16 RunInMsgIterClsInitFunc msgIterCtxFunc;
17 };
18
19 static const RunInData& runInDataFromMethodData(void * const methodData)
20 {
21 return *static_cast<const RunInData *>(methodData);
22 }
23
24 static bt_component_class_initialize_method_status
25 compClsInit(bt_self_component_source * const selfComp, bt_self_component_source_configuration *,
26 const bt_value *, void * const initMethodData)
27 {
28 const auto status =
29 bt_self_component_source_add_output_port(selfComp, "out", initMethodData, nullptr);
30
31 BT_ASSERT(status == BT_SELF_COMPONENT_ADD_PORT_STATUS_OK);
32
33 auto& data = runInDataFromMethodData(initMethodData);
34
35 if (data.compCtxFunc) {
36 data.compCtxFunc(bt_self_component_source_as_self_component(selfComp));
37 }
38
39 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
40 }
41
42 static bt_component_class_query_method_status
43 compClsQuery(bt_self_component_class_source * const selfCompCls, bt_private_query_executor *,
44 const char *, const bt_value *, void * const methodData,
45 const bt_value ** const result)
46 {
47 auto& data = runInDataFromMethodData(methodData);
48
49 if (data.compClsCtxFunc) {
50 data.compClsCtxFunc(bt_self_component_class_source_as_self_component_class(selfCompCls));
51 }
52
53 *result = bt_value_null;
54 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK;
55 }
56
57 static bt_message_iterator_class_initialize_method_status
58 msgIterClsInit(bt_self_message_iterator * const selfMsgIter,
59 bt_self_message_iterator_configuration *, bt_self_component_port_output * const port)
60 {
61 auto& data = runInDataFromMethodData(bt_self_component_port_get_data(
62 bt_self_component_port_output_as_self_component_port(port)));
63
64 if (data.msgIterCtxFunc) {
65 data.msgIterCtxFunc(selfMsgIter);
66 }
67
68 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
69 }
70
71 static bt_message_iterator_class_next_method_status
72 msgIterClsNext(bt_self_message_iterator *, bt_message_array_const, uint64_t, uint64_t *)
73 {
74 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
75 }
76
77 struct DummySinkData
78 {
79 bt_message_iterator *msgIter;
80 };
81
82 static bt_component_class_initialize_method_status
83 dummySinkInit(bt_self_component_sink * const self, bt_self_component_sink_configuration * const,
84 const bt_value * const, void * const initMethodData)
85 {
86 const auto status = bt_self_component_sink_add_input_port(self, "in", NULL, nullptr);
87 BT_ASSERT(status == BT_SELF_COMPONENT_ADD_PORT_STATUS_OK);
88 bt_self_component_set_data(bt_self_component_sink_as_self_component(self), initMethodData);
89 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
90 }
91
92 static DummySinkData& dummySinkDataFromSelfCompSink(bt_self_component_sink * const self)
93 {
94 return *static_cast<DummySinkData *>(
95 bt_self_component_get_data(bt_self_component_sink_as_self_component(self)));
96 }
97
98 static bt_component_class_sink_graph_is_configured_method_status
99 dummySinkGraphIsConfigured(bt_self_component_sink *const self)
100 {
101 auto& data = dummySinkDataFromSelfCompSink(self);
102 const auto port = bt_self_component_sink_borrow_input_port_by_name(self, "in");
103 BT_ASSERT(port);
104 const auto status = bt_message_iterator_create_from_sink_component(self, port, &data.msgIter);
105 BT_ASSERT(status == BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK);
106 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
107 }
108
109 static bt_component_class_sink_consume_method_status dummySinkConsume(bt_self_component_sink *const self)
110 {
111 const auto& data = dummySinkDataFromSelfCompSink(self);
112 bt_message_array_const msgs;
113 uint64_t msgCount;
114 const auto status = bt_message_iterator_next(data.msgIter, &msgs, &msgCount);
115 BT_ASSERT(status == BT_MESSAGE_ITERATOR_NEXT_STATUS_END);
116 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
117 }
118
119 void runIn(RunInCompClsQueryFunc compClsCtxFunc, RunInCompClsInitFunc compCtxFunc,
120 RunInMsgIterClsInitFunc msgIterCtxFunc)
121 {
122 RunInData data {std::move(compClsCtxFunc), std::move(compCtxFunc), std::move(msgIterCtxFunc)};
123
124 /* Create and configure custom source component class */
125 const auto msgIterCls = bt_message_iterator_class_create(msgIterClsNext);
126
127 BT_ASSERT(msgIterCls);
128
129 {
130 const auto status =
131 bt_message_iterator_class_set_initialize_method(msgIterCls, msgIterClsInit);
132
133 BT_ASSERT(status == BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK);
134 }
135
136 const auto srcCompCls = bt_component_class_source_create("yo", msgIterCls);
137
138 BT_ASSERT(srcCompCls);
139
140 {
141 const auto status =
142 bt_component_class_source_set_initialize_method(srcCompCls, compClsInit);
143
144 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
145 }
146
147 {
148 const auto status = bt_component_class_source_set_query_method(srcCompCls, compClsQuery);
149
150 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
151 }
152
153 /* Execute a query (executes `compClsCtxFunc`) */
154 {
155 const auto queryExec = bt_query_executor_create_with_method_data(
156 bt_component_class_source_as_component_class(srcCompCls), "", nullptr, &data);
157
158 BT_ASSERT(queryExec);
159
160 const bt_value *queryRes;
161 const auto status = bt_query_executor_query(queryExec, &queryRes);
162
163 BT_ASSERT(status == BT_QUERY_EXECUTOR_QUERY_STATUS_OK);
164
165 bt_value_put_ref(queryRes);
166 bt_query_executor_put_ref(queryExec);
167 }
168
169 /* Create a dummy sink component */
170 const auto sinkCompCls = bt_component_class_sink_create("dummy", dummySinkConsume);
171 BT_ASSERT(sinkCompCls);
172
173 {
174 const auto status =
175 bt_component_class_sink_set_initialize_method(sinkCompCls, dummySinkInit);
176 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
177 }
178
179 {
180 const auto status = bt_component_class_sink_set_graph_is_configured_method(
181 sinkCompCls, dummySinkGraphIsConfigured);
182 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
183 }
184
185 /* Create graph */
186 const auto graph = bt_graph_create(0);
187
188 BT_ASSERT(graph);
189
190 /* Add custom source component (executes `compCtxFunc`) */
191 const bt_component_source *srcComp;
192
193 {
194 const auto status = bt_graph_add_source_component_with_initialize_method_data(
195 graph, srcCompCls, "the-source", NULL, &data, BT_LOGGING_LEVEL_NONE, &srcComp);
196
197 BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
198 }
199
200 /* Add dummy sink component */
201 const bt_component_sink *sinkComp;
202 DummySinkData dummySinkData;
203
204 {
205 const auto status = bt_graph_add_sink_component_with_initialize_method_data(
206 graph, sinkCompCls, "the-sink", NULL, &dummySinkData, BT_LOGGING_LEVEL_NONE, &sinkComp);
207 BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
208 }
209
210 /* Connect ports */
211 {
212 const auto outPort = bt_component_source_borrow_output_port_by_name_const(srcComp, "out");
213
214 BT_ASSERT(outPort);
215
216 const auto inPort = bt_component_sink_borrow_input_port_by_name_const(sinkComp, "in");
217
218 BT_ASSERT(inPort);
219
220 const auto status = bt_graph_connect_ports(graph, outPort, inPort, nullptr);
221
222 BT_ASSERT(status == BT_GRAPH_CONNECT_PORTS_STATUS_OK);
223 }
224
225 /* Run graph (executes `msgIterCtxFunc`) */
226 const auto status = bt_graph_run(graph);
227
228 BT_ASSERT(status == BT_GRAPH_RUN_STATUS_OK);
229
230 /* Discard plugin and graph */
231 bt_graph_put_ref(graph);
232 bt_component_class_source_put_ref(srcCompCls);
233 bt_component_class_sink_put_ref(sinkCompCls);
234 bt_message_iterator_class_put_ref(msgIterCls);
235 }
236
237 void runInCompClsQuery(RunInCompClsQueryFunc func)
238 {
239 runIn(std::move(func), nullptr, nullptr);
240 }
241
242 void runInCompClsInit(RunInCompClsInitFunc func)
243 {
244 runIn(nullptr, std::move(func), nullptr);
245 }
246
247 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func)
248 {
249 runIn(nullptr, nullptr, std::move(func));
250 }
This page took 0.033546 seconds and 3 git commands to generate.