Coverage Report

Created: 2023-11-12 09:30

/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
71.0k
  SlotPtr allocateSlotMock() { return SlotPtr{new SlotImpl(*this, current_slot_++)}; }
32
6.88k
  void runOnAllThreads1(std::function<void()> cb) { cb(); }
33
429
  void runOnAllThreads2(std::function<void()> cb, std::function<void()> main_callback) {
34
429
    cb();
35
429
    main_callback();
36
429
  }
37
38
0
  void setDispatcher(Event::Dispatcher* dispatcher) { dispatcher_ptr_ = dispatcher; }
39
40
73.4k
  void shutdownThread_() {
41
73.4k
    shutdown_ = true;
42
    // Reverse order which is same as the production code.
43
144k
    for (auto it = data_.rbegin(); it != data_.rend(); ++it) {
44
71.0k
      it->reset();
45
71.0k
    }
46
73.4k
    data_.clear();
47
73.4k
  }
48
49
  struct SlotImpl : public Slot {
50
71.0k
    SlotImpl(MockInstance& parent, uint32_t index) : parent_(parent), index_(index) {
51
71.0k
      parent_.data_.resize(index_ + 1);
52
71.0k
      parent_.deferred_data_.resize(index_ + 1);
53
71.0k
    }
54
55
71.0k
    ~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
71.0k
      if (!parent_.shutdown_ && !parent_.defer_delete_) {
60
71.0k
        EXPECT_LT(index_, parent_.data_.size());
61
71.0k
        parent_.data_[index_].reset();
62
71.0k
      }
63
71.0k
    }
64
65
    // ThreadLocal::Slot
66
273k
    ThreadLocalObjectSharedPtr get() override {
67
273k
      EXPECT_TRUE(was_set_);
68
273k
      return parent_.data_[index_];
69
273k
    }
70
0
    bool currentThreadRegistered() override { return parent_.registered_; }
71
6.88k
    void runOnAllThreads(const UpdateCb& cb) override {
72
6.88k
      EXPECT_TRUE(was_set_);
73
6.88k
      parent_.runOnAllThreads([cb, this]() { cb(parent_.data_[index_]); });
74
6.88k
    }
75
429
    void runOnAllThreads(const UpdateCb& cb, const std::function<void()>& main_callback) override {
76
429
      EXPECT_TRUE(was_set_);
77
429
      parent_.runOnAllThreads([cb, this]() { cb(parent_.data_[index_]); },
78
429
                              std::move(main_callback));
79
429
    }
80
0
    bool isShutdown() const override { return parent_.shutdown_; }
81
82
132k
    void set(InitializeCb cb) override {
83
132k
      was_set_ = true;
84
132k
      if (parent_.defer_data_) {
85
0
        parent_.deferred_data_[index_] = cb;
86
132k
      } else {
87
132k
        parent_.data_[index_] = cb(*parent_.dispatcher_ptr_);
88
132k
      }
89
132k
    }
90
91
    MockInstance& parent_;
92
    const uint32_t index_;
93
    bool was_set_{}; // set() must be called before other functions.
94
  };
95
96
0
  void call() {
97
0
    for (unsigned i = 0; i < deferred_data_.size(); i++) {
98
0
      data_[i] = deferred_data_[i](*dispatcher_ptr_);
99
0
    }
100
0
    deferred_data_.clear();
101
0
  }
102
103
  uint32_t current_slot_{};
104
  testing::NiceMock<Event::MockDispatcher> dispatcher_;
105
  Event::Dispatcher* dispatcher_ptr_ = &dispatcher_;
106
  std::vector<ThreadLocalObjectSharedPtr> data_;
107
  std::vector<Slot::InitializeCb> deferred_data_;
108
  bool defer_data_{};
109
  bool shutdown_{};
110
  bool registered_{true};
111
  bool defer_delete_{};
112
};
113
114
} // namespace ThreadLocal
115
} // namespace Envoy