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/value.hpp>
10#include <userver/utils/function_ref.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace testsuite {
15
16/// @brief Returns true if testpoints are available in runtime.
17bool AreTestpointsAvailable() noexcept;
18
20 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,
29 const formats::json::Value& json,
30 TestpointCallback callback);
31
32void ExecuteTestpointBlocking(std::string_view name,
33 const formats::json::Value& json,
34 TestpointCallback callback,
35 engine::TaskProcessor& task_processor);
36
37void DoNothing(const formats::json::Value&) noexcept;
38
39} // namespace testsuite::impl
40
41USERVER_NAMESPACE_END
42
43// clang-format off
44
45/// @brief Send testpoint notification and receive data. Works only if
46/// testpoint support is enabled (e.g. in components::TestsControl),
47/// otherwise does nothing.
48///
49/// Example usage:
50/// @snippet samples/testsuite-support/src/testpoint.cpp Sample TESTPOINT_CALLBACK usage cpp
51/// @snippet samples/testsuite-support/tests/test_testpoint.py Sample TESTPOINT_CALLBACK usage python
52///
53/// Throws nothing if server::handlers::TestsControl is not
54/// loaded or it is disabled in static config via `load-enabled: false`.
55///
56/// @hideinitializer
57
58// clang-format on
59// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
60#define TESTPOINT_CALLBACK(name, json, callback)
61 do {
62 if (__builtin_expect(
63 !USERVER_NAMESPACE::testsuite::AreTestpointsAvailable(), true))
64 break;
65
66 /* cold testing path: */
67 const auto& userver_impl_tp_name = name;
68 if (!USERVER_NAMESPACE::testsuite::impl::IsTestpointEnabled(
69 userver_impl_tp_name))
70 break;
71
72 USERVER_NAMESPACE::testsuite::impl::ExecuteTestpointCoro(
73 userver_impl_tp_name, json, callback);
74 } while (false)
75
76// clang-format off
77
78/// @brief Send testpoint notification. Works only if testpoint support is
79/// enabled (e.g. in components::TestsControl), otherwise does nothing.
80///
81/// Example usage:
82/// @snippet samples/testsuite-support/src/testpoint.cpp Testpoint - TESTPOINT()
83/// @snippet samples/testsuite-support/tests/test_testpoint.py Testpoint - fixture
84///
85/// Throws nothing if server::handlers::TestsControl is not
86/// loaded or it is disabled in static config via `load-enabled: false`.
87///
88/// @hideinitializer
89
90// clang-format on
91// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
92#define TESTPOINT(name, json)
93 TESTPOINT_CALLBACK(name, json, USERVER_NAMESPACE::testsuite::impl::DoNothing)
94
95/// @brief Same as `TESTPOINT_CALLBACK` but must be called outside of
96/// coroutine (e.g. from std::thread routine).
97///
98/// Throws nothing if server::handlers::TestsControl is not
99/// loaded or it is disabled in static config via `load-enabled: false`.
100///
101/// @hideinitializer
102// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
103#define TESTPOINT_CALLBACK_NONCORO(name, json, task_processor, callback)
104 do {
105 if (__builtin_expect(
106 !USERVER_NAMESPACE::testsuite::AreTestpointsAvailable(), true))
107 break;
108
109 /* cold testing path: */
110 const auto& userver_impl_tp_name = name;
111 if (!USERVER_NAMESPACE::testsuite::impl::IsTestpointEnabled(
112 userver_impl_tp_name))
113 break;
114
115 USERVER_NAMESPACE::testsuite::impl::ExecuteTestpointBlocking(
116 userver_impl_tp_name, json, callback, task_processor);
117 } while (false)
118
119/// @brief Same as `TESTPOINT` but must be called outside of
120/// coroutine (e.g. from std::thread routine).
121///
122/// Throws nothing if server::handlers::TestsControl is not
123/// loaded or it is disabled in static config via `load-enabled: false`.
124///
125/// @hideinitializer
126// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
127#define TESTPOINT_NONCORO(name, json, task_processor)
128 TESTPOINT_CALLBACK_NONCORO(name, json, task_processor,
129 USERVER_NAMESPACE::testsuite::impl::DoNothing)