]>
Commit | Line | Data |
---|---|---|
4e0938ef | 1 | /* |
1f7b830e | 2 | * Copyright (C) 1996-2025 The Squid Software Foundation and contributors |
4e0938ef AJ |
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 | ||
582c2af2 | 9 | #include "squid.h" |
26e65059 | 10 | #include "anyp/Uri.h" |
62ee09ca | 11 | #include "CacheManager.h" |
ae022809 | 12 | #include "compat/cppunit.h" |
602d9612 | 13 | #include "mgr/Action.h" |
99572608 | 14 | #include "mgr/Registration.h" |
b707cdeb | 15 | #include "Store.h" |
7f861c77 | 16 | #include "unitTestMain.h" |
62ee09ca | 17 | |
3d41e53a | 18 | #include <cppunit/TestAssert.h> |
ae022809 FC |
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 | ||
ae022809 FC |
31 | protected: |
32 | void testCreate(); | |
33 | void testRegister(); | |
34 | void testParseUrl(); | |
35 | }; | |
62ee09ca | 36 | |
41e9c9f0 | 37 | CPPUNIT_TEST_SUITE_REGISTRATION( TestCacheManager ); |
62ee09ca | 38 | |
26e65059 AJ |
39 | /// Provides test code access to CacheManager internal symbols |
40 | class CacheManagerInternals : public CacheManager | |
41 | { | |
42 | public: | |
3c383cc3 AR |
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); | |
26e65059 AJ |
49 | }; |
50 | ||
3c383cc3 AR |
51 | void |
52 | CacheManagerInternals::testValidUrl(const AnyP::Uri &url) | |
53 | { | |
eb743f8b | 54 | CPPUNIT_ASSERT_NO_THROW(ParseUrl(url)); |
3c383cc3 AR |
55 | } |
56 | ||
57 | void | |
58 | CacheManagerInternals::testInvalidUrl(const AnyP::Uri &url, const char *const problem) | |
59 | { | |
eb743f8b | 60 | CPPUNIT_ASSERT_THROW_MESSAGE(problem, ParseUrl(url), TextException); |
3c383cc3 AR |
61 | } |
62 | ||
53a5a6de AR |
63 | /// customizes our test setup |
64 | class MyTestProgram: public TestProgram | |
65 | { | |
66 | public: | |
67 | /* TestProgram API */ | |
68 | void startup() override; | |
69 | }; | |
62ee09ca | 70 | |
53a5a6de AR |
71 | void |
72 | MyTestProgram::startup() | |
62ee09ca | 73 | { |
16555581 | 74 | Mem::Init(); |
26e65059 | 75 | AnyP::UriScheme::Init(); |
16555581 | 76 | } |
62ee09ca | 77 | |
78 | /* | |
79 | * Test creating a CacheManager | |
80 | */ | |
81 | void | |
41e9c9f0 | 82 | TestCacheManager::testCreate() |
62ee09ca | 83 | { |
b707cdeb | 84 | CacheManager::GetInstance(); //it's a singleton.. |
62ee09ca | 85 | } |
86 | ||
87 | /* an action to register */ | |
88 | static void | |
89 | dummy_action(StoreEntry * sentry) | |
b707cdeb FC |
90 | { |
91 | sentry->flags=1; | |
92 | } | |
62ee09ca | 93 | |
94 | /* | |
95 | * registering an action makes it findable. | |
96 | */ | |
97 | void | |
41e9c9f0 | 98 | TestCacheManager::testRegister() |
62ee09ca | 99 | { |
b707cdeb | 100 | CacheManager *manager=CacheManager::GetInstance(); |
aee3523a | 101 | CPPUNIT_ASSERT(manager != nullptr); |
b707cdeb | 102 | |
99572608 | 103 | Mgr::RegisterAction("sample", "my sample", &dummy_action, Mgr::Protected::no, Mgr::Atomic::no, Mgr::Format::informal); |
8822ebee | 104 | Mgr::Action::Pointer action = manager->createNamedAction("sample"); |
aee3523a | 105 | CPPUNIT_ASSERT(action != nullptr); |
b707cdeb | 106 | |
8822ebee | 107 | const Mgr::ActionProfile::Pointer profile = action->command().profile; |
aee3523a AR |
108 | CPPUNIT_ASSERT(profile != nullptr); |
109 | CPPUNIT_ASSERT(profile->creator != nullptr); | |
8822ebee AR |
110 | CPPUNIT_ASSERT_EQUAL(false, profile->isPwReq); |
111 | CPPUNIT_ASSERT_EQUAL(false, profile->isAtomic); | |
99572608 FC |
112 | CPPUNIT_ASSERT_EQUAL(Mgr::Format::informal, profile->format); |
113 | CPPUNIT_ASSERT_EQUAL(Mgr::Format::informal, action->format()); | |
8822ebee | 114 | CPPUNIT_ASSERT_EQUAL(String("sample"), String(action->name())); |
b707cdeb FC |
115 | |
116 | StoreEntry *sentry=new StoreEntry(); | |
99572608 | 117 | sentry->createMemObject(); |
b707cdeb | 118 | sentry->flags=0x25; //arbitrary test value |
8822ebee | 119 | action->run(sentry, false); |
b707cdeb | 120 | CPPUNIT_ASSERT_EQUAL(1,(int)sentry->flags); |
62ee09ca | 121 | } |
f53969cc | 122 | |
26e65059 | 123 | void |
41e9c9f0 | 124 | TestCacheManager::testParseUrl() |
26e65059 AJ |
125 | { |
126 | auto *mgr = static_cast<CacheManagerInternals *>(CacheManager::GetInstance()); | |
127 | CPPUNIT_ASSERT(mgr != nullptr); | |
128 | ||
129 | std::vector<AnyP::ProtocolType> validSchemes = { | |
26e65059 AJ |
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 | ||
26e65059 AJ |
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 | ||
3c383cc3 AR |
199 | const auto &prefix = CacheManager::WellKnownUrlPathPrefix(); |
200 | ||
201 | assert(prefix.length()); | |
202 | const auto insufficientPrefix = prefix.substr(0, prefix.length()-1); | |
203 | ||
26e65059 AJ |
204 | for (const auto &scheme : validSchemes) { |
205 | mgrUrl.setScheme(scheme); | |
206 | ||
3c383cc3 AR |
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"); | |
26e65059 AJ |
221 | } |
222 | } | |
3c383cc3 AR |
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 | } | |
26e65059 | 239 | |
3c383cc3 AR |
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); | |
26e65059 AJ |
251 | } |
252 | } | |
253 | } | |
254 | } | |
255 | } | |
53521734 | 256 | |
53a5a6de AR |
257 | int |
258 | main(int argc, char *argv[]) | |
259 | { | |
260 | return MyTestProgram().run(argc, argv); | |
261 | } | |
262 |