/proc/self/cwd/test/mocks/thread_local/mocks.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <cstdint> |
4 | | |
5 | | #include "envoy/thread_local/thread_local.h" |
6 | | |
7 | | #include "test/mocks/event/mocks.h" |
8 | | |
9 | | #include "gmock/gmock.h" |
10 | | |
11 | | namespace Envoy { |
12 | | namespace ThreadLocal { |
13 | | |
14 | | class MockInstance : public Instance { |
15 | | public: |
16 | | MockInstance(); |
17 | | ~MockInstance() override; |
18 | | |
19 | | MOCK_METHOD(void, runOnAllThreads, (std::function<void()> cb)); |
20 | | MOCK_METHOD(void, runOnAllThreads, |
21 | | (std::function<void()> cb, std::function<void()> main_callback)); |
22 | | |
23 | | // Server::ThreadLocal |
24 | | MOCK_METHOD(SlotPtr, allocateSlot, ()); |
25 | | MOCK_METHOD(void, registerThread, (Event::Dispatcher & dispatcher, bool main_thread)); |
26 | 0 | void shutdownGlobalThreading() override { shutdown_ = true; } |
27 | | MOCK_METHOD(void, shutdownThread, ()); |
28 | | MOCK_METHOD(Event::Dispatcher&, dispatcher, ()); |
29 | 0 | bool isShutdown() const override { return shutdown_; } |
30 | | |
31 | 65.4k | SlotPtr allocateSlotMock() { return SlotPtr{new SlotImpl(*this, current_slot_++)}; } |
32 | 2.19k | void runOnAllThreads1(std::function<void()> cb) { cb(); } |
33 | 80 | void runOnAllThreads2(std::function<void()> cb, std::function<void()> main_callback) { |
34 | 80 | cb(); |
35 | 80 | main_callback(); |
36 | 80 | } |
37 | | |
38 | 0 | void setDispatcher(Event::Dispatcher* dispatcher) { dispatcher_ptr_ = dispatcher; } |
39 | | |
40 | 68.8k | void shutdownThread_() { |
41 | 68.8k | shutdown_ = true; |
42 | | // Reverse order which is same as the production code. |
43 | 134k | for (auto it = data_.rbegin(); it != data_.rend(); ++it) { |
44 | 65.4k | it->reset(); |
45 | 65.4k | } |
46 | 68.8k | data_.clear(); |
47 | 68.8k | } |
48 | | |
49 | | struct SlotImpl : public Slot { |
50 | 65.4k | SlotImpl(MockInstance& parent, uint32_t index) : parent_(parent), index_(index) { |
51 | 65.4k | parent_.data_.resize(index_ + 1); |
52 | 65.4k | parent_.deferred_data_.resize(index_ + 1); |
53 | 65.4k | } |
54 | | |
55 | 65.4k | ~SlotImpl() override { |
56 | | // Do not actually clear slot data during shutdown. This mimics the production code. |
57 | | // The defer_delete mimics the slot being deleted on the main thread but the update not yet |
58 | | // getting to a worker. |
59 | 65.4k | if (!parent_.shutdown_ && !parent_.defer_delete_) { |
60 | 65.4k | EXPECT_LT(index_, parent_.data_.size()); |
61 | 65.4k | parent_.data_[index_].reset(); |
62 | 65.4k | } |
63 | 65.4k | } |
64 | | |
65 | | // ThreadLocal::Slot |
66 | 500k | ThreadLocalObjectSharedPtr get() override { |
67 | 500k | EXPECT_TRUE(was_set_); |
68 | 500k | return parent_.data_[index_]; |
69 | 500k | } |
70 | 0 | bool currentThreadRegistered() override { return parent_.registered_; } |
71 | 2.19k | void runOnAllThreads(const UpdateCb& cb) override { |
72 | 2.19k | EXPECT_TRUE(was_set_); |
73 | 2.19k | parent_.runOnAllThreads([cb, this]() { cb(parent_.data_[index_]); }); |
74 | 2.19k | } |
75 | 80 | void runOnAllThreads(const UpdateCb& cb, const std::function<void()>& main_callback) override { |
76 | 80 | EXPECT_TRUE(was_set_); |
77 | 80 | parent_.runOnAllThreads([cb, this]() { cb(parent_.data_[index_]); }, main_callback); |
78 | 80 | } |
79 | 0 | bool isShutdown() const override { return parent_.shutdown_; } |
80 | | |
81 | 122k | void set(InitializeCb cb) override { |
82 | 122k | was_set_ = true; |
83 | 122k | if (parent_.defer_data_) { |
84 | 0 | parent_.deferred_data_[index_] = cb; |
85 | 122k | } else { |
86 | 122k | parent_.data_[index_] = cb(*parent_.dispatcher_ptr_); |
87 | 122k | } |
88 | 122k | } |
89 | | |
90 | | MockInstance& parent_; |
91 | | const uint32_t index_; |
92 | | bool was_set_{}; // set() must be called before other functions. |
93 | | }; |
94 | | |
95 | 0 | void call() { |
96 | 0 | for (unsigned i = 0; i < deferred_data_.size(); i++) { |
97 | 0 | data_[i] = deferred_data_[i](*dispatcher_ptr_); |
98 | 0 | } |
99 | 0 | deferred_data_.clear(); |
100 | 0 | } |
101 | | |
102 | | uint32_t current_slot_{}; |
103 | | testing::NiceMock<Event::MockDispatcher> dispatcher_; |
104 | | Event::Dispatcher* dispatcher_ptr_ = &dispatcher_; |
105 | | std::vector<ThreadLocalObjectSharedPtr> data_; |
106 | | std::vector<Slot::InitializeCb> deferred_data_; |
107 | | bool defer_data_{}; |
108 | | bool shutdown_{}; |
109 | | bool registered_{true}; |
110 | | bool defer_delete_{}; |
111 | | }; |
112 | | |
113 | | } // namespace ThreadLocal |
114 | | } // namespace Envoy |