1//
2// Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BOOST_MYSQL_TEST_UNIT_INCLUDE_TEST_UNIT_MOCK_EXECUTION_PROCESSOR_HPP
9#define BOOST_MYSQL_TEST_UNIT_INCLUDE_TEST_UNIT_MOCK_EXECUTION_PROCESSOR_HPP
10
11#include <boost/mysql/diagnostics.hpp>
12#include <boost/mysql/error_code.hpp>
13#include <boost/mysql/field_view.hpp>
14#include <boost/mysql/metadata.hpp>
15#include <boost/mysql/string_view.hpp>
16
17#include <boost/mysql/detail/access.hpp>
18#include <boost/mysql/detail/execution_processor/execution_processor.hpp>
19
20#include <boost/mysql/impl/internal/protocol/protocol.hpp>
21
22#include <boost/config.hpp>
23#include <boost/test/unit_test.hpp>
24
25#include <cstddef>
26
27#include "test_unit/fail_count.hpp"
28
29namespace boost {
30namespace mysql {
31namespace test {
32
33class mock_execution_processor : public detail::execution_processor
34{
35 struct num_calls_t
36 {
37 std::size_t reset{};
38 std::size_t on_num_meta{};
39 std::size_t on_meta{};
40 std::size_t on_head_ok_packet{};
41 std::size_t on_row_batch_start{};
42 std::size_t on_row_batch_finish{};
43 std::size_t on_row{};
44 std::size_t on_row_ok_packet{};
45 };
46
47public:
48 // Validate the number of calls safely
49 class num_calls_validator
50 {
51 num_calls_t expected_{};
52 num_calls_t actual_{};
53
54 public:
55 num_calls_validator(num_calls_t actual) noexcept : actual_(actual) {}
56
57 BOOST_ATTRIBUTE_NODISCARD
58 num_calls_validator& reset(std::size_t v) noexcept
59 {
60 expected_.reset = v;
61 return *this;
62 }
63
64 BOOST_ATTRIBUTE_NODISCARD
65 num_calls_validator& on_num_meta(std::size_t v) noexcept
66 {
67 expected_.on_num_meta = v;
68 return *this;
69 }
70
71 BOOST_ATTRIBUTE_NODISCARD
72 num_calls_validator& on_meta(std::size_t v) noexcept
73 {
74 expected_.on_meta = v;
75 return *this;
76 }
77
78 BOOST_ATTRIBUTE_NODISCARD
79 num_calls_validator& on_head_ok_packet(std::size_t v) noexcept
80 {
81 expected_.on_head_ok_packet = v;
82 return *this;
83 }
84
85 BOOST_ATTRIBUTE_NODISCARD
86 num_calls_validator& on_row_batch_start(std::size_t v) noexcept
87 {
88 expected_.on_row_batch_start = v;
89 return *this;
90 }
91
92 BOOST_ATTRIBUTE_NODISCARD
93 num_calls_validator& on_row_batch_finish(std::size_t v) noexcept
94 {
95 expected_.on_row_batch_finish = v;
96 return *this;
97 }
98
99 BOOST_ATTRIBUTE_NODISCARD
100 num_calls_validator& on_row(std::size_t v) noexcept
101 {
102 expected_.on_row = v;
103 return *this;
104 }
105
106 BOOST_ATTRIBUTE_NODISCARD
107 num_calls_validator& on_row_ok_packet(std::size_t v) noexcept
108 {
109 expected_.on_row_ok_packet = v;
110 return *this;
111 }
112
113 void validate()
114 {
115 BOOST_TEST(expected_.reset == actual_.reset);
116 BOOST_TEST(expected_.on_num_meta == actual_.on_num_meta);
117 BOOST_TEST(expected_.on_meta == actual_.on_meta);
118 BOOST_TEST(expected_.on_head_ok_packet == actual_.on_head_ok_packet);
119 BOOST_TEST(expected_.on_row_batch_start == actual_.on_row_batch_start);
120 BOOST_TEST(expected_.on_row_batch_finish == actual_.on_row_batch_finish);
121 BOOST_TEST(expected_.on_row == actual_.on_row);
122 BOOST_TEST(expected_.on_row_ok_packet == actual_.on_row_ok_packet);
123 }
124 };
125
126 mock_execution_processor() = default;
127 std::uint64_t affected_rows() const noexcept { return ok_packet_.affected_rows; }
128 std::uint64_t last_insert_id() const noexcept { return ok_packet_.last_insert_id; }
129 string_view info() const noexcept { return ok_packet_.info; }
130 std::size_t num_meta() const noexcept { return num_meta_; }
131 const std::vector<metadata>& meta() const noexcept { return meta_; }
132 const std::vector<detail::output_ref>& refs() const noexcept { return refs_; }
133
134 BOOST_ATTRIBUTE_NODISCARD
135 num_calls_validator num_calls() noexcept { return num_calls_validator(num_calls_); }
136
137 void set_fail_count(fail_count fc, diagnostics diag = diagnostics())
138 {
139 fc_ = fc;
140 diag_ = std::move(diag);
141 }
142
143private:
144 // Data
145 num_calls_t num_calls_;
146 struct
147 {
148 std::uint64_t affected_rows{};
149 std::uint64_t last_insert_id{};
150 std::string info;
151 } ok_packet_{};
152 std::size_t num_meta_{};
153 std::vector<metadata> meta_;
154 std::vector<detail::output_ref> refs_;
155 fail_count fc_;
156 diagnostics diag_;
157
158 // Helpers
159 error_code maybe_fail(diagnostics& diag)
160 {
161 auto err = fc_.maybe_fail();
162 if (err)
163 {
164 diag = diag_;
165 }
166 return err;
167 }
168
169 void handle_ok(const detail::ok_view& pack)
170 {
171 ok_packet_.affected_rows = pack.affected_rows;
172 ok_packet_.last_insert_id = pack.last_insert_id;
173 ok_packet_.info = pack.info;
174 }
175
176protected:
177 void reset_impl() noexcept override { ++num_calls_.reset; }
178 error_code on_head_ok_packet_impl(const detail::ok_view& pack, diagnostics& diag) override
179 {
180 ++num_calls_.on_head_ok_packet;
181 handle_ok(pack);
182 return maybe_fail(diag);
183 }
184 void on_num_meta_impl(std::size_t num_meta) override
185 {
186 ++num_calls_.on_num_meta;
187 num_meta_ = num_meta;
188 }
189 error_code on_meta_impl(const detail::coldef_view& coldef, bool is_last, diagnostics& diag) override
190 {
191 ++num_calls_.on_meta;
192 meta_.push_back(x: detail::access::construct<metadata>(args: coldef, args: true));
193 return is_last ? maybe_fail(diag) : error_code();
194 }
195 void on_row_batch_start_impl() override { ++num_calls_.on_row_batch_start; }
196 void on_row_batch_finish_impl() override { ++num_calls_.on_row_batch_finish; }
197 error_code on_row_impl(span<const std::uint8_t>, const detail::output_ref& ref, std::vector<field_view>&)
198 override
199 {
200 ++num_calls_.on_row;
201 refs_.push_back(x: ref);
202 return fc_.maybe_fail();
203 }
204 error_code on_row_ok_packet_impl(const detail::ok_view& pack) override
205 {
206 ++num_calls_.on_row_ok_packet;
207 handle_ok(pack);
208 return fc_.maybe_fail();
209 }
210};
211
212} // namespace test
213} // namespace mysql
214} // namespace boost
215
216#endif
217

source code of boost/libs/mysql/test/unit/include/test_unit/mock_execution_processor.hpp