]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testEvent.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / tests / testEvent.cc
1 /*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "base/AsyncCallQueue.h"
11 #include "event.h"
12 #include "MemBuf.h"
13 #include "tests/testEvent.h"
14 #include "unitTestMain.h"
15
16 CPPUNIT_TEST_SUITE_REGISTRATION( testEvent );
17
18 /* init legacy static-initialized modules */
19
20 void
21 testEvent::setUp()
22 {
23 Mem::Init();
24 }
25
26 /*
27 * Test creating a Scheduler
28 */
29 void
30 testEvent::testCreate()
31 {
32 EventScheduler scheduler = EventScheduler();
33 }
34
35 /// Helper for tests - an event which records the number of calls it received
36 class CalledEvent
37 {
38 public:
39 static void Handler(void *data) {
40 static_cast<CalledEvent *>(data)->calls++;
41 }
42
43 int calls = 0;
44 };
45
46 /* submit two callbacks, and cancel one, then dispatch and only the other should run.
47 */
48 void
49 testEvent::testCancel()
50 {
51 EventScheduler scheduler;
52 CalledEvent event;
53 CalledEvent event_to_cancel;
54 scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false);
55 scheduler.schedule("test event2", CalledEvent::Handler, &event_to_cancel, 0, 0, false);
56 scheduler.cancel(CalledEvent::Handler, &event_to_cancel);
57 scheduler.checkEvents(0);
58 AsyncCallQueue::Instance().fire();
59 CPPUNIT_ASSERT_EQUAL(1, event.calls);
60 CPPUNIT_ASSERT_EQUAL(0, event_to_cancel.calls);
61 }
62
63 // submit two callbacks, and then dump the queue.
64 void
65 testEvent::testDump()
66 {
67 EventScheduler scheduler;
68 CalledEvent event;
69 CalledEvent event2;
70 const char *expected = "Last event to run: last event\n"
71 "\n"
72 "Operation \tNext Execution \tWeight\tCallback Valid?\n"
73 "test event \t0.000 sec\t 0\t N/A\n"
74 "test event2 \t0.000 sec\t 0\t N/A\n";
75 MemBuf expect;
76 expect.init();
77 expect.append(expected, strlen(expected));
78
79 scheduler.schedule("last event", CalledEvent::Handler, &event, 0, 0, false);
80
81 /* schedule and dispatch to set the last run event */
82 scheduler.checkEvents(0);
83 AsyncCallQueue::Instance().fire();
84 scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false);
85 scheduler.schedule("test event2", CalledEvent::Handler, &event2, 0, 0, false);
86
87 MemBuf result;
88 result.init();
89 scheduler.dump(&result);
90
91 /* loop over the strings, showing exactly where they differ (if at all) */
92 printf("Actual Text:\n");
93 /* TODO: these should really be just [] lookups, but String doesn't have those here yet. */
94 for (size_t i = 0; i < size_t(result.contentSize()); ++i) {
95 CPPUNIT_ASSERT(expect.content()[i]);
96 CPPUNIT_ASSERT(result.content()[i]);
97
98 /* slight hack to make special chars visible */
99 switch (result.content()[i]) {
100 case '\t':
101 printf("\\t");
102 break;
103 default:
104 printf("%c", result.content()[i]);
105 }
106 /* make this an int comparison, so that we can see the ASCII code at failure */
107 CPPUNIT_ASSERT_EQUAL(int(expect.content()[i]), int(result.content()[i]));
108 }
109 printf("\n");
110 CPPUNIT_ASSERT_EQUAL(expect.contentSize(), result.contentSize());
111 CPPUNIT_ASSERT(strcmp(expect.content(), result.content()) == 0);
112 }
113
114 /* submit two callbacks, and find the right one.
115 */
116 void
117 testEvent::testFind()
118 {
119 EventScheduler scheduler;
120 CalledEvent event;
121 CalledEvent event_to_find;
122 scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false);
123 scheduler.schedule("test event2", CalledEvent::Handler, &event_to_find, 0, 0, false);
124 CPPUNIT_ASSERT_EQUAL(true, scheduler.find(CalledEvent::Handler, &event_to_find));
125 }
126
127 /* do a trivial test of invoking callbacks */
128 void
129 testEvent::testCheckEvents()
130 {
131 EventScheduler scheduler;
132 CalledEvent event;
133 /* with no events, its an idle engine */
134 CPPUNIT_ASSERT_EQUAL(int(AsyncEngine::EVENT_IDLE), scheduler.checkEvents(0));
135 /* event running now gets will get sent to the dispatcher and the
136 * engine becomes idle.
137 */
138 scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false);
139 CPPUNIT_ASSERT_EQUAL(int(AsyncEngine::EVENT_IDLE), scheduler.checkEvents(0));
140 AsyncCallQueue::Instance().fire();
141 /* event running later results in a delay of the time till it runs */
142 scheduler.schedule("test event", CalledEvent::Handler, &event, 2, 0, false);
143 CPPUNIT_ASSERT_EQUAL(2000, scheduler.checkEvents(0));
144 AsyncCallQueue::Instance().fire();
145 CPPUNIT_ASSERT_EQUAL(1, event.calls);
146 }
147
148 /* for convenience we have a singleton scheduler */
149 void
150 testEvent::testSingleton()
151 {
152 EventScheduler *scheduler = dynamic_cast<EventScheduler *>(EventScheduler::GetInstance());
153 CPPUNIT_ASSERT(nullptr != scheduler);
154 }
155