userver: userver/testsuite/testpoint.hpp Source File
Loading...
Searching...
No Matches
testpoint.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/testsuite/testpoint.hpp
4/// @brief @copybrief TESTPOINT
5
6#include <string>
7
8#include <userver/engine/task/task_processor_fwd.hpp>
9#include <userver/formats/json/serialize.hpp>
10#include <userver/formats/json/value.hpp>
11#include <userver/utils/function_ref.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace testsuite {
16
17/// @brief Returns true if testpoints are available in runtime.
18bool AreTestpointsAvailable() noexcept;
19
20using TestpointCallback = utils::function_ref<void(const formats::json::Value&)>;
21
22} // namespace testsuite
23
24namespace testsuite::impl {
25
26bool IsTestpointEnabled(std::string_view name) noexcept;
27
28void ExecuteTestpointCoro(std::string_view name, const formats::json::Value& json, TestpointCallback callback);
29
30void ExecuteTestpointBlocking(
31 std::string_view name,
32 const formats::json::Value& json,
33 TestpointCallback callback,
34 engine::TaskProcessor& task_processor
35);
36
37void DoNothing(const formats::json::Value&) noexcept;
38
39} // namespace testsuite::impl
40
41USERVER_NAMESPACE_END
42
43/// @brief Send testpoint notification and receive data. Works only if
44/// testpoint support is enabled (e.g. in components::TestsControl),
45/// otherwise does nothing.
46///
47/// Example usage:
48/// @snippet samples/testsuite-support/src/testpoint.cpp Sample TESTPOINT_CALLBACK usage cpp
49/// @snippet samples/testsuite-support/tests/test_testpoint.py Sample TESTPOINT_CALLBACK usage python
50///
51/// Throws nothing if server::handlers::TestsControl is not
52/// loaded or it is disabled in static config via `load-enabled: false`.
53///
54/// @hideinitializer
55// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
56#define TESTPOINT_CALLBACK(name, json, callback)
57 do {
58 if (__builtin_expect(!USERVER_NAMESPACE::testsuite::AreTestpointsAvailable(), true)) break;
59
60 /* cold testing path: */
61 const auto& userver_impl_tp_name = name;
62 if (!USERVER_NAMESPACE::testsuite::impl::IsTestpointEnabled(userver_impl_tp_name)) break;
63
64 USERVER_NAMESPACE::testsuite::impl::ExecuteTestpointCoro(userver_impl_tp_name, json, callback);
65 } while (false)
66
67/// @brief Send testpoint notification. Works only if testpoint support is
68/// enabled (e.g. in components::TestsControl), otherwise does nothing.
69///
70/// Example usage:
71/// @snippet samples/testsuite-support/src/testpoint.cpp Testpoint - TESTPOINT()
72/// @snippet samples/testsuite-support/tests/test_testpoint.py Testpoint - fixture
73///
74/// Throws nothing if server::handlers::TestsControl is not
75/// loaded or it is disabled in static config via `load-enabled: false`.
76///
77/// @hideinitializer
78// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
79#define TESTPOINT(name, json) TESTPOINT_CALLBACK(name, json, USERVER_NAMESPACE::testsuite::impl::DoNothing)
80
81/// @brief Same as `TESTPOINT_CALLBACK` but must be called outside of
82/// coroutine (e.g. from std::thread routine).
83///
84/// Throws nothing if server::handlers::TestsControl is not
85/// loaded or it is disabled in static config via `load-enabled: false`.
86///
87/// @hideinitializer
88// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
89#define TESTPOINT_CALLBACK_NONCORO(name, json, task_processor, callback)
90 do {
91 if (__builtin_expect(!USERVER_NAMESPACE::testsuite::AreTestpointsAvailable(), true)) break;
92
93 /* cold testing path: */
94 const auto& userver_impl_tp_name = name;
95 if (!USERVER_NAMESPACE::testsuite::impl::IsTestpointEnabled(userver_impl_tp_name)) break;
96
97 USERVER_NAMESPACE::testsuite::impl::ExecuteTestpointBlocking(
98 userver_impl_tp_name,
99 json,
100 callback,
101 task_processor
102 );
103 } while (false)
104
105/// @brief Same as `TESTPOINT` but must be called outside of
106/// coroutine (e.g. from std::thread routine).
107///
108/// Throws nothing if server::handlers::TestsControl is not
109/// loaded or it is disabled in static config via `load-enabled: false`.
110///
111/// @hideinitializer
112// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
113#define TESTPOINT_NONCORO(name, json, task_processor)
114 TESTPOINT_CALLBACK_NONCORO(name, json, task_processor, USERVER_NAMESPACE::testsuite::impl::DoNothing)