Coverage Report

Created: 2024-09-19 09:45

/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