]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testCacheManager.cc
d62043803fb9bcbb407da223397274e609d162ba
[thirdparty/squid.git] / src / tests / testCacheManager.cc
1 /*
2 * Copyright (C) 1996-2025 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 "anyp/Uri.h"
11 #include "CacheManager.h"
12 #include "compat/cppunit.h"
13 #include "mgr/Action.h"
14 #include "mgr/Registration.h"
15 #include "Store.h"
16 #include "unitTestMain.h"
17
18 #include <cppunit/TestAssert.h>
19 /*
20 * test the CacheManager implementation
21 */
22
23 class TestCacheManager : public CPPUNIT_NS::TestFixture
24 {
25 CPPUNIT_TEST_SUITE(TestCacheManager);
26 CPPUNIT_TEST(testCreate);
27 CPPUNIT_TEST(testRegister);
28 CPPUNIT_TEST(testParseUrl);
29 CPPUNIT_TEST_SUITE_END();
30
31 protected:
32 void testCreate();
33 void testRegister();
34 void testParseUrl();
35 };
36
37 CPPUNIT_TEST_SUITE_REGISTRATION( TestCacheManager );
38
39 /// Provides test code access to CacheManager internal symbols
40 class CacheManagerInternals : public CacheManager
41 {
42 public:
43 /// checks CacheManager parsing of the given valid URL
44 void testValidUrl(const AnyP::Uri &);
45
46 /// checks CacheManager parsing of the given invalid URL
47 /// \param problem a bad part of the URL or its description
48 void testInvalidUrl(const AnyP::Uri &, const char *problem);
49 };
50
51 void
52 CacheManagerInternals::testValidUrl(const AnyP::Uri &url)
53 {
54 CPPUNIT_ASSERT_NO_THROW(ParseUrl(url));
55 }
56
57 void
58 CacheManagerInternals::testInvalidUrl(const AnyP::Uri &url, const char *const problem)
59 {
60 CPPUNIT_ASSERT_THROW_MESSAGE(problem, ParseUrl(url), TextException);
61 }
62
63 /// customizes our test setup
64 class MyTestProgram: public TestProgram
65 {
66 public:
67 /* TestProgram API */
68 void startup() override;
69 };
70
71 void
72 MyTestProgram::startup()
73 {
74 Mem::Init();
75 AnyP::UriScheme::Init();
76 }
77
78 /*
79 * Test creating a CacheManager
80 */
81 void
82 TestCacheManager::testCreate()
83 {
84 CacheManager::GetInstance(); //it's a singleton..
85 }
86
87 /* an action to register */
88 static void
89 dummy_action(StoreEntry * sentry)
90 {
91 sentry->flags=1;
92 }
93
94 /*
95 * registering an action makes it findable.
96 */
97 void
98 TestCacheManager::testRegister()
99 {
100 CacheManager *manager=CacheManager::GetInstance();
101 CPPUNIT_ASSERT(manager != nullptr);
102
103 Mgr::RegisterAction("sample", "my sample", &dummy_action, Mgr::Protected::no, Mgr::Atomic::no, Mgr::Format::informal);
104 Mgr::Action::Pointer action = manager->createNamedAction("sample");
105 CPPUNIT_ASSERT(action != nullptr);
106
107 const Mgr::ActionProfile::Pointer profile = action->command().profile;
108 CPPUNIT_ASSERT(profile != nullptr);
109 CPPUNIT_ASSERT(profile->creator != nullptr);
110 CPPUNIT_ASSERT_EQUAL(false, profile->isPwReq);
111 CPPUNIT_ASSERT_EQUAL(false, profile->isAtomic);
112 CPPUNIT_ASSERT_EQUAL(Mgr::Format::informal, profile->format);
113 CPPUNIT_ASSERT_EQUAL(Mgr::Format::informal, action->format());
114 CPPUNIT_ASSERT_EQUAL(String("sample"), String(action->name()));
115
116 StoreEntry *sentry=new StoreEntry();
117 sentry->createMemObject();
118 sentry->flags=0x25; //arbitrary test value
119 action->run(sentry, false);
120 CPPUNIT_ASSERT_EQUAL(1,(int)sentry->flags);
121 }
122
123 void
124 TestCacheManager::testParseUrl()
125 {
126 auto *mgr = static_cast<CacheManagerInternals *>(CacheManager::GetInstance());
127 CPPUNIT_ASSERT(mgr != nullptr);
128
129 std::vector<AnyP::ProtocolType> validSchemes = {
130 AnyP::PROTO_HTTP,
131 AnyP::PROTO_HTTPS,
132 AnyP::PROTO_FTP
133 };
134
135 AnyP::Uri mgrUrl;
136 mgrUrl.host("localhost");
137 mgrUrl.port(3128);
138
139 const std::vector<const char *> validActions = {
140 "",
141 "menu"
142 };
143
144 const std::vector<const char *> invalidActions = {
145 "INVALID" // any unregistered name
146 };
147
148 const std::vector<const char *> validParams = {
149 "",
150 "?",
151 "?&",
152 "?&&&&&&&&&&&&",
153 "?foo=bar",
154 "?0123456789=bar",
155 "?foo=bar&",
156 "?foo=bar&&&&",
157 "?&foo=bar",
158 "?&&&&foo=bar",
159 "?&foo=bar&",
160 "?&&&&foo=bar&&&&",
161 "?foo=?_weird?~`:[]stuff&bar=okay&&&&&&",
162 "?intlist=1",
163 "?intlist=1,2,3,4,5",
164 "?string=1a",
165 "?string=1,2,3,4,z",
166 "?string=1,2,3,4,[0]",
167 "?intlist=1,2,3,4,5&string=1,2,3,4,y"
168 };
169
170 const std::vector<const char *> invalidParams = {
171 "?/",
172 "?foo",
173 "?/foo",
174 "?foo/",
175 "?foo=",
176 "?foo=&",
177 "?=foo",
178 "? foo=bar",
179 "? &",
180 "?& ",
181 "?=&",
182 "?&=",
183 "? &&&",
184 "?& &&",
185 "?&& &",
186 "?=&&&",
187 "?&=&&",
188 "?&&=&"
189 };
190
191 const std::vector<const char *> validFragments = {
192 "",
193 "#",
194 "##",
195 "#?a=b",
196 "#fragment"
197 };
198
199 const auto &prefix = CacheManager::WellKnownUrlPathPrefix();
200
201 assert(prefix.length());
202 const auto insufficientPrefix = prefix.substr(0, prefix.length()-1);
203
204 for (const auto &scheme : validSchemes) {
205 mgrUrl.setScheme(scheme);
206
207 // Check that the parser rejects URLs that lack the full prefix prefix.
208 // These negative tests log "Squid BUG: assurance failed" ERRORs because
209 // they violate CacheManager::ParseUrl()'s ForSomeCacheManager()
210 // precondition.
211 for (const auto *action : validActions) {
212 for (const auto *param : validParams) {
213 for (const auto *frag : validFragments) {
214 SBuf bits;
215 bits.append(insufficientPrefix);
216 bits.append(action);
217 bits.append(param);
218 bits.append(frag);
219 mgrUrl.path(bits);
220 mgr->testInvalidUrl(mgrUrl, "insufficient prefix");
221 }
222 }
223 }
224
225 // Check that the parser accepts valid URLs.
226 for (const auto action: validActions) {
227 for (const auto param: validParams) {
228 for (const auto frag: validFragments) {
229 SBuf bits;
230 bits.append(prefix);
231 bits.append(action);
232 bits.append(param);
233 bits.append(frag);
234 mgrUrl.path(bits);
235 mgr->testValidUrl(mgrUrl);
236 }
237 }
238 }
239
240 // Check that the parser rejects URLs with invalid parameters.
241 for (const auto action: validActions) {
242 for (const auto invalidParam: invalidParams) {
243 for (const auto frag: validFragments) {
244 SBuf bits;
245 bits.append(prefix);
246 bits.append(action);
247 bits.append(invalidParam);
248 bits.append(frag);
249 mgrUrl.path(bits);
250 mgr->testInvalidUrl(mgrUrl, invalidParam);
251 }
252 }
253 }
254 }
255 }
256
257 int
258 main(int argc, char *argv[])
259 {
260 return MyTestProgram().run(argc, argv);
261 }
262