abseil-cpp/absl/random/mocking_bit_gen.h
Go to the documentation of this file.
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // -----------------------------------------------------------------------------
16 // mocking_bit_gen.h
17 // -----------------------------------------------------------------------------
18 //
19 // This file includes an `absl::MockingBitGen` class to use as a mock within the
20 // Googletest testing framework. Such a mock is useful to provide deterministic
21 // values as return values within (otherwise random) Abseil distribution
22 // functions. Such determinism within a mock is useful within testing frameworks
23 // to test otherwise indeterminate APIs.
24 //
25 // More information about the Googletest testing framework is available at
26 // https://github.com/google/googletest
27 
28 #ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_
29 #define ABSL_RANDOM_MOCKING_BIT_GEN_H_
30 
31 #include <iterator>
32 #include <limits>
33 #include <memory>
34 #include <tuple>
35 #include <type_traits>
36 #include <utility>
37 
38 #include "gmock/gmock.h"
39 #include "gtest/gtest.h"
40 #include "absl/base/internal/fast_type_id.h"
41 #include "absl/container/flat_hash_map.h"
42 #include "absl/meta/type_traits.h"
43 #include "absl/random/distributions.h"
44 #include "absl/random/internal/distribution_caller.h"
45 #include "absl/random/random.h"
46 #include "absl/strings/str_cat.h"
47 #include "absl/strings/str_join.h"
48 #include "absl/types/span.h"
49 #include "absl/types/variant.h"
50 #include "absl/utility/utility.h"
51 
52 namespace absl {
54 
55 namespace random_internal {
56 template <typename>
57 struct DistributionCaller;
58 class MockHelpers;
59 
60 } // namespace random_internal
61 class BitGenRef;
62 
63 // MockingBitGen
64 //
65 // `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class
66 // which can act in place of an `absl::BitGen` URBG within tests using the
67 // Googletest testing framework.
68 //
69 // Usage:
70 //
71 // Use an `absl::MockingBitGen` along with a mock distribution object (within
72 // mock_distributions.h) inside Googletest constructs such as ON_CALL(),
73 // EXPECT_TRUE(), etc. to produce deterministic results conforming to the
74 // distribution's API contract.
75 //
76 // Example:
77 //
78 // // Mock a call to an `absl::Bernoulli` distribution using Googletest
79 // absl::MockingBitGen bitgen;
80 //
81 // ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5))
82 // .WillByDefault(testing::Return(true));
83 // EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5));
84 //
85 // // Mock a call to an `absl::Uniform` distribution within Googletest
86 // absl::MockingBitGen bitgen;
87 //
88 // ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_))
89 // .WillByDefault([] (int low, int high) {
90 // return low + (high - low) / 2;
91 // });
92 //
93 // EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5);
94 // EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35);
95 //
96 // At this time, only mock distributions supplied within the Abseil random
97 // library are officially supported.
98 //
99 // EXPECT_CALL and ON_CALL need to be made within the same DLL component as
100 // the call to absl::Uniform and related methods, otherwise mocking will fail
101 // since the underlying implementation creates a type-specific pointer which
102 // will be distinct across different DLL boundaries.
103 //
105  public:
106  MockingBitGen() = default;
107  ~MockingBitGen() = default;
108 
109  // URBG interface
111 
112  static constexpr result_type(min)() { return (absl::BitGen::min)(); }
113  static constexpr result_type(max)() { return (absl::BitGen::max)(); }
114  result_type operator()() { return gen_(); }
115 
116  private:
117  // GetMockFnType returns the testing::MockFunction for a result and tuple.
118  // This method only exists for type deduction and is otherwise unimplemented.
119  template <typename ResultT, typename... Args>
120  static auto GetMockFnType(ResultT, std::tuple<Args...>)
121  -> ::testing::MockFunction<ResultT(Args...)>;
122 
123  // MockFnCaller is a helper method for use with absl::apply to
124  // apply an ArgTupleT to a compatible MockFunction.
125  // NOTE: MockFnCaller is essentially equivalent to the lambda:
126  // [fn](auto... args) { return fn->Call(std::move(args)...)}
127  // however that fails to build on some supported platforms.
128  template <typename MockFnType, typename ResultT, typename Tuple>
129  struct MockFnCaller;
130 
131  // specialization for std::tuple.
132  template <typename MockFnType, typename ResultT, typename... Args>
133  struct MockFnCaller<MockFnType, ResultT, std::tuple<Args...>> {
134  MockFnType* fn;
135  inline ResultT operator()(Args... args) {
136  return fn->Call(std::move(args)...);
137  }
138  };
139 
140  // FunctionHolder owns a particular ::testing::MockFunction associated with
141  // a mocked type signature, and implement the type-erased Apply call, which
142  // applies type-erased arguments to the mock.
144  public:
145  virtual ~FunctionHolder() = default;
146 
147  // Call is a dispatch function which converts the
148  // generic type-erased parameters into a specific mock invocation call.
149  virtual void Apply(/*ArgTupleT*/ void* args_tuple,
150  /*ResultT*/ void* result) = 0;
151  };
152 
153  template <typename MockFnType, typename ResultT, typename ArgTupleT>
154  class FunctionHolderImpl final : public FunctionHolder {
155  public:
156  void Apply(void* args_tuple, void* result) override {
157  // Requires tuple_args to point to a ArgTupleT, which is a
158  // std::tuple<Args...> used to invoke the mock function. Requires result
159  // to point to a ResultT, which is the result of the call.
160  *static_cast<ResultT*>(result) =
162  *static_cast<ArgTupleT*>(args_tuple));
163  }
164 
165  MockFnType mock_fn_;
166  };
167 
168  // MockingBitGen::RegisterMock
169  //
170  // RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension
171  // point for extending the MockingBitGen framework. It provides a mechanism to
172  // install a mock expectation for a function like ResultT(Args...) keyed by
173  // type_idex onto the MockingBitGen context. The key is that the type_index
174  // used to register must match the type index used to call the mock.
175  //
176  // The returned MockFunction<...> type can be used to setup additional
177  // distribution parameters of the expectation.
178  template <typename ResultT, typename ArgTupleT, typename SelfT>
180  -> decltype(GetMockFnType(std::declval<ResultT>(),
181  std::declval<ArgTupleT>()))& {
182  using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(),
183  std::declval<ArgTupleT>()));
184 
185  using WrappedFnType = absl::conditional_t<
186  std::is_same<SelfT, ::testing::NiceMock<absl::MockingBitGen>>::value,
189  std::is_same<SelfT,
193  std::is_same<SelfT,
195  ::testing::StrictMock<MockFnType>, MockFnType>>>;
196 
198  auto& mock = mocks_[type];
199  if (!mock) {
200  mock = absl::make_unique<ImplT>();
201  }
202  return static_cast<ImplT*>(mock.get())->mock_fn_;
203  }
204 
205  // MockingBitGen::InvokeMock
206  //
207  // InvokeMock(FastTypeIdType, args, result) is the entrypoint for invoking
208  // mocks registered on MockingBitGen.
209  //
210  // When no mocks are registered on the provided FastTypeIdType, returns false.
211  // Otherwise attempts to invoke the mock function ResultT(Args...) that
212  // was previously registered via the type_index.
213  // Requires tuple_args to point to a ArgTupleT, which is a std::tuple<Args...>
214  // used to invoke the mock function.
215  // Requires result to point to a ResultT, which is the result of the call.
216  inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple,
217  void* result) {
218  // Trigger a mock, if there exists one that matches `param`.
219  auto it = mocks_.find(type);
220  if (it == mocks_.end()) return false;
221  it->second->Apply(args_tuple, result);
222  return true;
223  }
224 
226  std::unique_ptr<FunctionHolder>>
229 
230  template <typename>
231  friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock
232  friend class ::absl::BitGenRef; // for InvokeMock
233  friend class ::absl::random_internal::MockHelpers; // for RegisterMock,
234  // InvokeMock
235 };
236 
238 } // namespace absl
239 
240 #endif // ABSL_RANDOM_MOCKING_BIT_GEN_H_
testing::StrictMock
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-nice-strict.h:148
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
absl::MockingBitGen::MockFnCaller< MockFnType, ResultT, std::tuple< Args... > >::fn
MockFnType * fn
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:134
regen-readme.it
it
Definition: regen-readme.py:15
absl::MockingBitGen::InvokeMock
bool InvokeMock(base_internal::FastTypeIdType type, void *args_tuple, void *result)
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:216
absl::MockingBitGen::FunctionHolderImpl
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:154
absl::MockingBitGen::RegisterMock
auto RegisterMock(SelfT &, base_internal::FastTypeIdType type) -> decltype(GetMockFnType(std::declval< ResultT >(), std::declval< ArgTupleT >()))&
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:179
absl::MockingBitGen::MockFnCaller
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:129
absl::MockingBitGen
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:104
absl::conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition: abseil-cpp/absl/meta/type_traits.h:634
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::MockingBitGen::FunctionHolder::Apply
virtual void Apply(void *args_tuple, void *result)=0
testing::NiceMock
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-nice-strict.h:72
absl::MockingBitGen::~MockingBitGen
~MockingBitGen()=default
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >::result_type
typename random_internal::randen_engine< uint64_t > ::result_type result_type
Definition: abseil-cpp/absl/random/internal/nonsecure_base.h:98
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
hpack_encoder_fixtures::Args
Args({0, 16384})
generate-asm-lcov.fn
fn
Definition: generate-asm-lcov.py:146
absl::MockingBitGen::MockFnCaller< MockFnType, ResultT, std::tuple< Args... > >::operator()
ResultT operator()(Args... args)
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:135
absl::MockingBitGen::min
static constexpr result_type() min()
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:112
absl::MockingBitGen::max
static constexpr result_type() max()
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:113
absl::base_internal::FastTypeIdType
const void * FastTypeIdType
Definition: abseil-cpp/absl/base/internal/fast_type_id.h:39
absl::MockingBitGen::FunctionHolderImpl::mock_fn_
MockFnType mock_fn_
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:165
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >::max
static constexpr result_type() max()
Definition: abseil-cpp/absl/random/internal/nonsecure_base.h:123
absl::MockingBitGen::FunctionHolder
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:143
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >::min
static constexpr result_type() min()
Definition: abseil-cpp/absl/random/internal/nonsecure_base.h:120
value
const char * value
Definition: hpack_parser_table.cc:165
testing::NaggyMock
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-nice-strict.h:110
absl::MockingBitGen::mocks_
absl::flat_hash_map< base_internal::FastTypeIdType, std::unique_ptr< FunctionHolder > > mocks_
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:227
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >
absl::MockingBitGen::operator()
result_type operator()()
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:114
absl::flat_hash_map
Definition: abseil-cpp/absl/container/flat_hash_map.h:113
testing::MockFunction
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:11854
absl::MockingBitGen::FunctionHolderImpl::Apply
void Apply(void *args_tuple, void *result) override
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:156
absl::MockingBitGen::GetMockFnType
static auto GetMockFnType(ResultT, std::tuple< Args... >) -> ::testing::MockFunction< ResultT(Args...)>
absl::MockingBitGen::gen_
absl::BitGen gen_
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:228
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::MockingBitGen::MockingBitGen
MockingBitGen()=default
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
absl::MockingBitGen::FunctionHolder::~FunctionHolder
virtual ~FunctionHolder()=default
absl::MockingBitGen::result_type
absl::BitGen::result_type result_type
Definition: abseil-cpp/absl/random/mocking_bit_gen.h:110
absl::apply
auto apply(Functor &&functor, Tuple &&t) -> decltype(utility_internal::apply_helper(absl::forward< Functor >(functor), absl::forward< Tuple >(t), absl::make_index_sequence< std::tuple_size< typename std::remove_reference< Tuple >::type >::value >
Definition: abseil-cpp/absl/utility/utility.h:289


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:30