tests: add framework to run code in comp cls / comp / msg iter context
[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 void runIn(RunInCompClsQueryFunc compClsCtxFunc, RunInCompClsInitFunc compCtxFunc,
78 RunInMsgIterClsInitFunc msgIterCtxFunc)
79 {
80 RunInData data {std::move(compClsCtxFunc), std::move(compCtxFunc), std::move(msgIterCtxFunc)};
81
82 /* Create and configure custom source component class */
83 const auto msgIterCls = bt_message_iterator_class_create(msgIterClsNext);
84
85 BT_ASSERT(msgIterCls);
86
87 {
88 const auto status =
89 bt_message_iterator_class_set_initialize_method(msgIterCls, msgIterClsInit);
90
91 BT_ASSERT(status == BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK);
92 }
93
94 const auto srcCompCls = bt_component_class_source_create("yo", msgIterCls);
95
96 BT_ASSERT(srcCompCls);
97
98 {
99 const auto status =
100 bt_component_class_source_set_initialize_method(srcCompCls, compClsInit);
101
102 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
103 }
104
105 {
106 const auto status = bt_component_class_source_set_query_method(srcCompCls, compClsQuery);
107
108 BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
109 }
110
111 /* Execute a query (executes `compClsCtxFunc`) */
112 {
113 const auto queryExec = bt_query_executor_create_with_method_data(
114 bt_component_class_source_as_component_class(srcCompCls), "", nullptr, &data);
115
116 BT_ASSERT(queryExec);
117
118 const bt_value *queryRes;
119 const auto status = bt_query_executor_query(queryExec, &queryRes);
120
121 BT_ASSERT(status == BT_QUERY_EXECUTOR_QUERY_STATUS_OK);
122
123 bt_value_put_ref(queryRes);
124 bt_query_executor_put_ref(queryExec);
125 }
126
127 /* Create graph */
128 const auto graph = bt_graph_create(0);
129
130 BT_ASSERT(graph);
131
132 /* Add custom source component (executes `compCtxFunc`) */
133 const bt_component_source *srcComp;
134
135 {
136 const auto status = bt_graph_add_source_component_with_initialize_method_data(
137 graph, srcCompCls, "whatever", NULL, &data, BT_LOGGING_LEVEL_NONE, &srcComp);
138
139 BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
140 }
141
142 /* Find `sink.utils.dummy` component class */
143 const bt_plugin *utilsPlugin = nullptr;
144
145 {
146 const auto status =
147 bt_plugin_find("utils", BT_TRUE, BT_TRUE, BT_TRUE, BT_TRUE, BT_TRUE, &utilsPlugin);
148
149 BT_ASSERT(status == BT_PLUGIN_FIND_STATUS_OK);
150 }
151
152 /* Add `sink.utils.dummy` component */
153 const bt_component_sink *sinkComp;
154
155 {
156 const auto dummyCompCls =
157 bt_plugin_borrow_sink_component_class_by_name_const(utilsPlugin, "dummy");
158
159 BT_ASSERT(dummyCompCls);
160
161 const auto status = bt_graph_add_sink_component(graph, dummyCompCls, "the-sink", nullptr,
162 BT_LOGGING_LEVEL_NONE, &sinkComp);
163
164 BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
165 }
166
167 /* Connect ports */
168 {
169 const auto outPort = bt_component_source_borrow_output_port_by_name_const(srcComp, "out");
170
171 BT_ASSERT(outPort);
172
173 const auto inPort = bt_component_sink_borrow_input_port_by_name_const(sinkComp, "in");
174
175 BT_ASSERT(inPort);
176
177 const auto status = bt_graph_connect_ports(graph, outPort, inPort, nullptr);
178
179 BT_ASSERT(status == BT_GRAPH_CONNECT_PORTS_STATUS_OK);
180 }
181
182 /* Run graph (executes `msgIterCtxFunc`) */
183 const auto status = bt_graph_run(graph);
184
185 BT_ASSERT(status == BT_GRAPH_RUN_STATUS_OK);
186
187 /* Discard plugin and graph */
188 bt_plugin_put_ref(utilsPlugin);
189 bt_graph_put_ref(graph);
190 bt_component_class_source_put_ref(srcCompCls);
191 bt_message_iterator_class_put_ref(msgIterCls);
192 }
193
194 void runInCompClsQuery(RunInCompClsQueryFunc func)
195 {
196 runIn(std::move(func), nullptr, nullptr);
197 }
198
199 void runInCompClsInit(RunInCompClsInitFunc func)
200 {
201 runIn(nullptr, std::move(func), nullptr);
202 }
203
204 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func)
205 {
206 runIn(nullptr, nullptr, std::move(func));
207 }
This page took 0.042892 seconds and 4 git commands to generate.