tests/lib: C++ify run-in and condition trigger code
[babeltrace.git] / tests / lib / conds / utils.hpp
index 53676d8c01e09828b9c57e3b019ef4deffa339f0..0fd4fa0adb2de2b96d395d40cb8c3aa20f8cdfda 100644 (file)
 #ifndef TESTS_LIB_CONDS_UTILS_H
 #define TESTS_LIB_CONDS_UTILS_H
 
+#include <functional>
+#include <string>
+#include <utility>
+
 #include <babeltrace2/babeltrace.h>
 
-#include "cpp-common/bt2/self-component-port.hpp"
+#include "cpp-common/bt2s/optional.hpp"
 #include "cpp-common/bt2s/span.hpp"
 
-enum cond_trigger_func_type
-{
-    COND_TRIGGER_FUNC_TYPE_BASIC,
-    COND_TRIGGER_FUNC_TYPE_RUN_IN_COMP_CLS_INIT,
-};
+#include "../utils/run-in.hpp"
 
-enum cond_trigger_type
+/*
+ * Abstract condition trigger class.
+ *
+ * A derived class must provide operator()() which triggers a condition
+ * of which the specific type (precondition or postcondition) and ID are
+ * provided at construction time.
+ */
+class CondTrigger
 {
-    COND_TRIGGER_TYPE_PRE,
-    COND_TRIGGER_TYPE_POST,
-};
+public:
+    /*
+     * Condition type.
+     */
+    enum class Type
+    {
+        PRE,
+        POST,
+    };
 
-typedef void (*cond_trigger_basic_func)(void);
-typedef void (*cond_trigger_run_in_comp_cls_init_func)(bt2::SelfComponent);
+protected:
+    /*
+     * Builds a condition trigger having the type `type`, the condition
+     * ID `condId` (_without_ any `pre:` or `post:` prefix), and the
+     * optional name suffix `nameSuffix`.
+     *
+     * The concatenation of `condId` and, if it's set, `-` and
+     * `*nameSuffix`, forms the name of the condition trigger. Get the
+     * name of the created condition trigger with name().
+     */
+    explicit CondTrigger(Type type, const std::string& condId,
+                         const bt2s::optional<std::string>& nameSuffix) noexcept;
 
-struct cond_trigger
-{
-    enum cond_trigger_type type;
-    enum cond_trigger_func_type func_type;
-    const char *cond_id;
-    const char *suffix;
-    union
+public:
+    virtual ~CondTrigger() = default;
+    virtual void operator()() noexcept = 0;
+
+    Type type() const noexcept
+    {
+        return _mType;
+    }
+
+    /*
+     * Condition ID, including any `pre:` or `post:` prefix.
+     */
+    const std::string& condId() const noexcept
     {
-        cond_trigger_basic_func basic;
-        cond_trigger_run_in_comp_cls_init_func run_in_comp_cls_init;
-    } func;
+        return _mCondId;
+    }
+
+    const std::string& name() const noexcept
+    {
+        return _mName;
+    }
+
+private:
+    Type _mType;
+    std::string _mCondId;
+    std::string _mName;
 };
 
-#define COND_TRIGGER_PRE_BASIC(_cond_id, _suffix, _func)                                           \
-    {                                                                                              \
-        .type = COND_TRIGGER_TYPE_PRE, .func_type = COND_TRIGGER_FUNC_TYPE_BASIC,                  \
-        .cond_id = _cond_id, .suffix = _suffix, .func = {                                          \
-            .basic = _func,                                                                        \
-        }                                                                                          \
+/*
+ * Simple condition trigger.
+ *
+ * Implements a condition trigger where a function provided at
+ * construction time triggers a condition.
+ */
+class SimpleCondTrigger : public CondTrigger
+{
+public:
+    explicit SimpleCondTrigger(std::function<void()> func, Type type, const std::string& condId,
+                               const bt2s::optional<std::string>& nameSuffix = bt2s::nullopt);
+
+    void operator()() noexcept override
+    {
+        _mFunc();
     }
 
-#define COND_TRIGGER_POST_BASIC(_cond_id, _suffix, _func)                                          \
-    {                                                                                              \
-        .type = COND_TRIGGER_TYPE_POST, .func_type = COND_TRIGGER_FUNC_TYPE_BASIC,                 \
-        .cond_id = _cond_id, .suffix = _suffix, .func = {                                          \
-            .basic = _func,                                                                        \
-        }                                                                                          \
+private:
+    std::function<void()> _mFunc;
+};
+
+/*
+ * Run-in condition trigger.
+ *
+ * Implements a condition trigger of which the triggering function
+ * happens in a graph or component class query context using the
+ * runIn() API.
+ */
+template <typename RunInT>
+class RunInCondTrigger : public CondTrigger
+{
+public:
+    explicit RunInCondTrigger(RunInT runIn, const Type type, const std::string& condId,
+                              const bt2s::optional<std::string>& nameSuffix = bt2s::nullopt) :
+        CondTrigger {type, condId, nameSuffix},
+        _mRunIn {std::move(runIn)}
+    {
     }
 
-#define COND_TRIGGER_PRE_RUN_IN_COMP_CLS_INIT(_cond_id, _suffix, _func)                            \
-    {                                                                                              \
-        .type = COND_TRIGGER_TYPE_PRE, .func_type = COND_TRIGGER_FUNC_TYPE_RUN_IN_COMP_CLS_INIT,   \
-        .cond_id = _cond_id, .suffix = _suffix, .func = {                                          \
-            .run_in_comp_cls_init = _func,                                                         \
-        }                                                                                          \
+    explicit RunInCondTrigger(const Type type, const std::string& condId,
+                              const bt2s::optional<std::string>& nameSuffix = bt2s::nullopt) :
+        RunInCondTrigger {RunInT {}, type, condId, nameSuffix}
+    {
     }
 
-#define COND_TRIGGER_POST_RUN_IN_COMP_CLS_INIT(_cond_id, _suffix, _func)                           \
-    {                                                                                              \
-        .type = COND_TRIGGER_TYPE_POST, .func_type = COND_TRIGGER_FUNC_TYPE_RUN_IN_COMP_CLS_INIT,  \
-        .cond_id = _cond_id, .suffix = _suffix, .func = {                                          \
-            .run_in_comp_cls_init = _func,                                                         \
-        }                                                                                          \
+    void operator()() noexcept override
+    {
+        runIn(_mRunIn);
     }
 
-void condMain(int argc, const char **argv, bt2s::span<const cond_trigger> triggers) noexcept;
+private:
+    RunInT _mRunIn;
+};
+
+/*
+ * List of condition triggers.
+ */
+using CondTriggers = bt2s::span<CondTrigger * const>;
+
+/*
+ * The entry point of a condition trigger program.
+ *
+ * Call this from your own main() with your list of condition triggers
+ * `triggers`.
+ *
+ * Each condition trigger of `triggers` must have a unique name, as
+ * returned by CondTrigger::name().
+ *
+ * This function uses `argc` and `argv` to respond to one of the
+ * following commands:
+ *
+ * `list`:
+ *     Prints a list of condition triggers as a JSON array of objects.
+ *
+ *     Each JSON object has:
+ *
+ *     `cond-id`:
+ *         The condition ID of the trigger, as returned by
+ *         CondTrigger:condId().
+ *
+ *     `name`:
+ *         The condition ID name, as returned by CondTrigger::name().
+ *
+ * `run`:
+ *     Runs the triggering function of the condition trigger at the
+ *     index specified by the next command-line argument.
+ *
+ *     For example,
+ *
+ *         $ my-cond-trigger-program run 45
+ *
+ *     would run the function of the condition trigger `triggers[45]`.
+ *
+ *     The program is expected to abort through a libbabeltrace2
+ *     condition failure.
+ */
+void condMain(int argc, const char **argv, CondTriggers triggers) noexcept;
 
 #endif /* TESTS_LIB_CONDS_UTILS_H */
This page took 0.025076 seconds and 4 git commands to generate.