Improve unit test infrastructure - allow control of write()
[oweals/dinit.git] / src / tests / test-includes / dinit.h
1 #ifndef DINIT_H_INCLUDED
2 #define DINIT_H_INCLUDED 1
3
4 // dummy dinit.h
5
6 #include <unordered_set>
7 #include <map>
8 #include <string>
9 #include <cassert>
10
11 #include "dasynq.h"
12
13 using clock_type = dasynq::clock_type;
14 using rearm = dasynq::rearm;
15 using time_val = dasynq::time_val;
16
17 namespace bp_sys {
18     extern pid_t last_forked_pid;
19 }
20
21 // This is a mock for a Dasynq-based event loop
22 class eventloop_t
23 {
24     time_val current_time {0, 0};
25
26     public:
27     void get_time(time_val &tv, dasynq::clock_type clock) noexcept
28     {
29         tv = current_time;
30     }
31
32     // Advance the simulated current time by the given amount, and call timer callbacks.
33     void advance_time(time_val amount)
34     {
35         current_time += amount;
36         auto active_copy = active_timers;
37         for (timer * t : active_copy) {
38             if (t->expiry_time >= current_time) {
39                 t->stop_timer(*this);
40                 rearm r = t->expired(*this, 1);
41                 assert(r == rearm::NOOP); // others not handled
42             }
43         }
44     }
45
46     void send_fd_event(int fd, int events)
47     {
48         auto i = regd_fd_watchers.find(fd);
49         if (i != regd_fd_watchers.end()) {
50             fd_watcher *watcher = i->second;
51             dasynq::rearm r = watcher->fd_event(*this, fd, events);
52             if (r == dasynq::rearm::REMOVE) {
53                 watcher->deregister(*this);
54             }
55         }
56     }
57
58     class child_proc_watcher
59     {
60         public:
61         pid_t fork(eventloop_t &loop, bool reserved_child_watcher, int priority = dasynq::DEFAULT_PRIORITY)
62         {
63             bp_sys::last_forked_pid++;
64             return bp_sys::last_forked_pid;
65         }
66
67         void add_reserved(eventloop_t &eloop, pid_t child, int prio = dasynq::DEFAULT_PRIORITY) noexcept
68         {
69
70         }
71
72         void stop_watch(eventloop_t &eloop) noexcept
73         {
74
75         }
76
77         void deregister(eventloop_t &loop, pid_t pid) noexcept
78         {
79
80         }
81
82         void unreserve(eventloop_t &loop) noexcept
83         {
84
85         }
86     };
87
88     template <typename Derived> class child_proc_watcher_impl : public child_proc_watcher
89     {
90
91     };
92
93     class fd_watcher
94     {
95         int watched_fd;
96
97         public:
98         void add_watch(eventloop_t &loop, int fd, int events, bool enable = true)
99         {
100             if (loop.regd_fd_watchers.find(fd) != loop.regd_fd_watchers.end()
101                     || loop.regd_bidi_watchers.find(fd) != loop.regd_bidi_watchers.end()) {
102                 throw std::string("must not add_watch when already active");
103             }
104             watched_fd = fd;
105             loop.regd_fd_watchers[fd] = this;
106         }
107
108         int get_watched_fd() noexcept
109         {
110             return watched_fd;
111         }
112
113         void set_enabled(eventloop_t &loop, bool enable) noexcept
114         {
115
116         }
117
118         void deregister(eventloop_t &loop) noexcept
119         {
120             loop.regd_fd_watchers.erase(watched_fd);
121             watched_fd = -1;
122             watch_removed();
123         }
124
125         virtual rearm fd_event(eventloop_t & loop, int fd, int flags) = 0;
126
127         virtual void watch_removed() noexcept { }
128     };
129
130     template <typename Derived> class fd_watcher_impl : public fd_watcher
131     {
132
133     };
134
135     class bidi_fd_watcher
136     {
137         int watched_fd = -1;
138
139         public:
140         void set_watches(eventloop_t &eloop, int newFlags) noexcept
141         {
142
143         }
144
145         void add_watch(eventloop_t &eloop, int fd, int flags, int inprio = dasynq::DEFAULT_PRIORITY,
146                         int outprio = dasynq::DEFAULT_PRIORITY)
147         {
148                 if (eloop.regd_bidi_watchers.find(fd) != eloop.regd_bidi_watchers.end()) {
149                         throw std::string("must not add_watch when already active");
150                 }
151                 eloop.regd_bidi_watchers[fd] = this;
152                 watched_fd = fd;
153         }
154
155         int get_watched_fd() noexcept
156         {
157                 return watched_fd;
158         }
159
160         void deregister(eventloop_t &eloop) noexcept
161         {
162                 eloop.regd_bidi_watchers.erase(watched_fd);
163                 watched_fd = -1;
164         }
165
166         // In the real implementation these are not virtual, but it is easier for testing if they are:
167         virtual rearm read_ready(eventloop_t &loop, int fd) noexcept = 0;
168         virtual rearm write_ready(eventloop_t &loop, int fd) noexcept = 0;
169     };
170
171     template <typename Derived> class bidi_fd_watcher_impl : public bidi_fd_watcher
172         {
173
174         };
175
176     class timer
177     {
178         friend class eventloop_t;
179
180         private:
181         time_val expiry_time;
182
183         protected:
184         virtual rearm expired(eventloop_t &loop, int expiry_count)
185         {
186             return rearm::NOOP;
187         }
188
189         public:
190         void add_timer(eventloop_t &loop)
191         {
192
193         }
194
195         void arm_timer_rel(eventloop_t &loop, time_val timeout) noexcept
196         {
197             expiry_time = loop.current_time + timeout;
198             loop.active_timers.insert(this);
199         }
200
201         void stop_timer(eventloop_t &loop) noexcept
202         {
203             loop.active_timers.erase(this);
204         }
205
206         void deregister(eventloop_t &loop) noexcept
207         {
208
209         }
210     };
211
212     template <typename Derived> class timer_impl : public timer
213     {
214         protected:
215         virtual rearm expired(eventloop_t &loop, int expiry_count) override
216         {
217             return static_cast<Derived *>(this)->timer_expiry(loop, expiry_count);
218         }
219     };
220
221     std::unordered_set<timer *> active_timers;
222         std::map<int, bidi_fd_watcher *> regd_bidi_watchers;
223         std::map<int, fd_watcher *> regd_fd_watchers;
224 };
225
226 inline void rootfs_is_rw() noexcept
227 {
228 }
229
230 inline void setup_external_log() noexcept
231 {
232 }
233
234 inline void read_env_file(const char *env_file_path)
235 {
236 }
237
238 extern eventloop_t event_loop;
239
240 #endif