1
2
3
4
5
6
7 package com.octo.captcha.service;
8
9 import com.octo.captcha.Captcha;
10 import com.octo.captcha.engine.MockCaptchaEngine;
11 import com.octo.captcha.service.captchastore.CaptchaStore;
12 import com.octo.captcha.service.captchastore.MapCaptchaStore;
13
14 import java.util.Locale;
15
16 public class RunableAbstractManageableCaptchaServiceTest extends RunableAbstractCaptchaServiceTest {
17 public static int MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS = 3;
18 public static int CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION = 2 * SIZE;
19 public static int MAX_CAPTCHA_STORE_SIZE = 3 * SIZE;
20
21
22 protected void setUp() throws Exception {
23 super.setUp();
24
25 this.service = new MockedManageableCaptchaService(new MapCaptchaStore(), new MockCaptchaEngine(),
26 MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS,
27 MAX_CAPTCHA_STORE_SIZE, CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION);
28 }
29
30
31 protected ManageableCaptchaService getMService() {
32 return (ManageableCaptchaService) service;
33 }
34
35 public void testIsCaptchaStoreFull() {
36
37 AbstractManageableCaptchaService mockedService = new MockedManageableCaptchaService(
38 new MapCaptchaStore(), new MockCaptchaEngine(),
39 MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS, 0, 0);
40
41 assertFalse(mockedService.isCaptchaStoreFull());
42 }
43
44
45 public void testAbstractManageableCaptchaService() throws Exception {
46 try {
47 new MockedManageableCaptchaService(new MapCaptchaStore(), new MockCaptchaEngine(), 0, 10, 100);
48 fail("should have thrown an exception");
49 } catch (Exception e) {
50 assertTrue("IllegalArgumentException attended", e instanceof IllegalArgumentException);
51 }
52 }
53
54 public void testGetCaptchaEngineClass() throws Exception {
55 assertEquals("Sould be the mockEngine...", MockCaptchaEngine.class.getName(),
56 getMService().getCaptchaEngineClass());
57 }
58
59 public void testSetCaptchaEngineClass() throws Exception {
60 try {
61 getMService().setCaptchaEngineClass("unknown");
62 fail("shoul have thown an exception");
63 } catch (IllegalArgumentException e) {
64 assertEquals("Sould still be the mockEngine...",
65 MockCaptchaEngine.class.getName(),
66 getMService().getCaptchaEngineClass());
67 }
68
69 try {
70 getMService().setCaptchaEngineClass("java.lang.String");
71 fail("shoul have thown an exception");
72 } catch (IllegalArgumentException e) {
73 assertEquals("Sould still be the mockEngine...",
74 MockCaptchaEngine.class.getName(),
75 getMService().getCaptchaEngineClass());
76 }
77
78 assertEquals("Sould still be the mockEngine...", MockCaptchaEngine.class.getName(),
79 getMService().getCaptchaEngineClass());
80
81 try {
82 getMService().setCaptchaEngineClass(SecondMockCaptchaEngine.class.getName());
83 assertEquals("Sould be the SecondmockEngine...", SecondMockCaptchaEngine.class.getName(),
84 getMService().getCaptchaEngineClass());
85 } catch (IllegalArgumentException e) {
86 fail("should be ok " + e);
87 assertEquals("Sould be the mockEngine...",
88 MockCaptchaEngine.class.getName(),
89 getMService().getCaptchaEngineClass());
90 }
91 }
92
93 public void testEmptyCaptchaStore() throws Exception {
94 for (int i = 0; i < SIZE; i++) {
95 String id = String.valueOf(myRandom.nextInt());
96 service.generateAndStoreCaptcha(Locale.getDefault(), id);
97 }
98 getMService().emptyCaptchaStore();
99 assertTrue("it shoud be emtpy", getMService().getCaptchaStoreSize() == 0);
100 }
101
102 public void testGarbageCollectCaptchaStore() throws Exception {
103 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
104 String id = String.valueOf(myRandom.nextInt());
105 service.generateAndStoreCaptcha(Locale.getDefault(), id);
106 }
107
108 getMService().garbageCollectCaptchaStore();
109 assertTrue("store size should be the same(this test may fail if time to load the store is > min guaranted...)",
110 getMService().getCaptchaStoreSize() == CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION);
111
112 Thread.sleep(MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS * 1000 + 100);
113 getMService().garbageCollectCaptchaStore();
114 assertTrue("store should be empty",
115 getMService().getCaptchaStoreSize() == 0);
116 }
117
118 public void testGetCaptchaStoreMaxSize() throws Exception {
119 assertEquals("initial size", MAX_CAPTCHA_STORE_SIZE, getMService().getCaptchaStoreMaxSize());
120 }
121
122 public void testSetCaptchaStoreMaxSize() throws Exception {
123 try {
124 getMService().setCaptchaStoreMaxSize(CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION - 1);
125 fail("should have thrown an exception");
126 } catch (Exception e) {
127 assertTrue("IllegalArgumentException attended", e instanceof IllegalArgumentException);
128 }
129 getMService().setCaptchaStoreMaxSize(CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION);
130 assertEquals("modified size",
131 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION, getMService().getCaptchaStoreMaxSize());
132 }
133
134 public void testSetCaptchaStoreSizeBeforeGarbageCollection() throws Exception {
135 try {
136 getMService().setCaptchaStoreSizeBeforeGarbageCollection(MAX_CAPTCHA_STORE_SIZE + 1);
137 fail("should have thrown an exception");
138 } catch (Exception e) {
139 assertTrue("IllegalArgumentException attended", e instanceof IllegalArgumentException);
140 }
141 getMService().setCaptchaStoreSizeBeforeGarbageCollection(MAX_CAPTCHA_STORE_SIZE);
142 assertEquals("modified size",
143 MAX_CAPTCHA_STORE_SIZE, getMService().getCaptchaStoreSizeBeforeGarbageCollection());
144 }
145
146 public void testGetCaptchaStoreSizeBeforeGarbageCollection() throws Exception {
147 assertEquals("initial value", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
148 getMService().getCaptchaStoreSizeBeforeGarbageCollection());
149 }
150
151 public void testGetNumberOfGarbageCollectedCaptcha() throws Exception {
152 assertEquals("inital value", 0, getMService().getNumberOfGarbageCollectedCaptcha());
153 loadAndWait();
154 getMService().garbageCollectCaptchaStore();
155 assertEquals("all should have been collected",
156 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
157 getMService().getNumberOfGarbageCollectedCaptcha());
158
159 loadAndWait();
160 getMService().emptyCaptchaStore();
161 getMService().garbageCollectCaptchaStore();
162 assertEquals("none have been collected",
163 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
164 getMService().getNumberOfGarbageCollectedCaptcha());
165
166 loadAndWait();
167 getMService().validateResponseForID(String.valueOf(0), "true");
168 getMService().garbageCollectCaptchaStore();
169 assertEquals("all but one should have been collected",
170 2 * CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION - 1,
171 getMService().getNumberOfGarbageCollectedCaptcha());
172 }
173
174
175 public void testGetNumberOfGarbageCollectableCaptchas() throws Exception {
176 assertEquals("inital value", 0, getMService().getNumberOfGarbageCollectableCaptchas());
177 loadAndWait();
178
179 assertEquals("all should be collectable",
180 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
181 getMService().getNumberOfGarbageCollectableCaptchas());
182 getMService().garbageCollectCaptchaStore();
183
184
185 assertEquals("none should be collectable", 0, getMService().getNumberOfGarbageCollectableCaptchas());
186 loadAndWait();
187 assertEquals("all should be collectable",
188 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
189 getMService().getNumberOfGarbageCollectableCaptchas());
190 getMService().emptyCaptchaStore();
191 assertEquals("none should be collectable", 0, getMService().getNumberOfGarbageCollectableCaptchas());
192
193 loadAndWait();
194 getMService().validateResponseForID(String.valueOf(0), "true");
195 assertEquals("all but one should be collectable",
196 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION - 1,
197 getMService().getNumberOfGarbageCollectableCaptchas());
198
199 getMService().getChallengeForID("newCaptcha");
200 assertEquals("all but one should be collectable",
201 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION - 1,
202 getMService().getNumberOfGarbageCollectableCaptchas());
203
204 Thread.sleep(MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS * 1000 + 100);
205 assertEquals("all should be collectable",
206 CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
207 getMService().getNumberOfGarbageCollectableCaptchas());
208
209 }
210
211 public void testGetCaptchaStoreSize() throws Exception {
212 assertEquals("initial size", 0, getMService().getCaptchaStoreSize());
213 for (int i = 0; i < SIZE; i++) {
214 String id = String.valueOf(i);
215 service.generateAndStoreCaptcha(Locale.getDefault(), id);
216 assertEquals("size", i + 1, getMService().getCaptchaStoreSize());
217 }
218 getMService().validateResponseForID(String.valueOf(0), "true");
219 assertEquals("size", SIZE - 1,
220 getMService().getCaptchaStoreSize());
221 getMService().getChallengeForID("newCaptcha");
222 assertEquals("size", SIZE
223 , getMService().getCaptchaStoreSize());
224 getMService().getChallengeForID("newCaptcha");
225 assertEquals("size", SIZE
226 , getMService().getCaptchaStoreSize());
227 getMService().getQuestionForID("newCaptcha");
228 assertEquals("size", SIZE
229 , getMService().getCaptchaStoreSize());
230 getMService().getQuestionForID("newCaptcha", Locale.getDefault());
231 assertEquals("size", SIZE
232 , getMService().getCaptchaStoreSize());
233 getMService().getChallengeForID("newCaptcha", Locale.getDefault());
234 assertEquals("size", SIZE
235 , getMService().getCaptchaStoreSize());
236
237 }
238
239 public void testGetNumberOfUncorrectResponses() throws Exception {
240 assertEquals("initial size", 0, getMService().getNumberOfUncorrectResponses());
241
242 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
243 String id = String.valueOf(i);
244 service.generateAndStoreCaptcha(Locale.getDefault(), id);
245 service.validateResponseForID(id, "false");
246 assertEquals("size", i + 1, getMService().getNumberOfUncorrectResponses());
247 }
248
249 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
250 String id = String.valueOf(i);
251 service.generateAndStoreCaptcha(Locale.getDefault(), id);
252 service.validateResponseForID(id, "true");
253 assertEquals("should not have been incremented", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
254 getMService().getNumberOfUncorrectResponses());
255 }
256
257 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
258 String id = String.valueOf(i);
259 service.generateAndStoreCaptcha(Locale.getDefault(), id);
260 try {
261 service.validateResponseForID("unknown", "false");
262 fail("should have thrown an exception");
263 } catch (CaptchaServiceException e) {
264 assertNotNull(e.getMessage());
265 }
266 assertEquals("should not have been incremented", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
267 getMService().getNumberOfUncorrectResponses());
268 }
269
270
271 }
272
273 public void testGetNumberOfCorrectResponses() throws Exception {
274 assertEquals("initial size", 0, getMService().getNumberOfCorrectResponses());
275
276 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
277 String id = String.valueOf(i);
278 service.generateAndStoreCaptcha(Locale.getDefault(), id);
279 service.validateResponseForID(id, "true");
280 assertEquals("size", i + 1, getMService().getNumberOfCorrectResponses());
281 }
282
283 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
284 String id = String.valueOf(i);
285 service.generateAndStoreCaptcha(Locale.getDefault(), id);
286 service.validateResponseForID(id, "false");
287 assertEquals("should not have been incremented", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
288 getMService().getNumberOfCorrectResponses());
289 }
290
291 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
292 String id = String.valueOf(i);
293 service.generateAndStoreCaptcha(Locale.getDefault(), id);
294 try {
295 service.validateResponseForID("unknown", "false");
296 fail("should have thrown an exception");
297 } catch (CaptchaServiceException e) {
298 assertNotNull(e.getMessage());
299 }
300 assertEquals("should not have been incremented", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
301 getMService().getNumberOfCorrectResponses());
302 }
303 }
304
305 public void testGetNumberOfGeneratedCaptchas() throws Exception {
306 assertEquals("initial size", 0, getMService().getNumberOfGeneratedCaptchas());
307
308 for (int i = 0; i < SIZE; i++) {
309 String id = String.valueOf(i);
310 service.getChallengeForID(id);
311 assertEquals("size", 4 * i + 1, getMService().getNumberOfGeneratedCaptchas());
312 service.getChallengeForID(id);
313 assertEquals("size", 4 * i + 2, getMService().getNumberOfGeneratedCaptchas());
314 service.getQuestionForID(id);
315 assertEquals("size", 4 * i + 2, getMService().getNumberOfGeneratedCaptchas());
316 service.getQuestionForID(id);
317 assertEquals("size", 4 * i + 2, getMService().getNumberOfGeneratedCaptchas());
318 service.getChallengeForID(id);
319 assertEquals("size", 4 * i + 3, getMService().getNumberOfGeneratedCaptchas());
320 service.getChallengeForID(id);
321 assertEquals("size", 4 * i + 4, getMService().getNumberOfGeneratedCaptchas());
322 }
323 long generatedBefore = getMService().getNumberOfGeneratedCaptchas();
324 getMService().emptyCaptchaStore();
325 for (int i = 0; i < SIZE; i++) {
326 String id = String.valueOf(i);
327 service.getQuestionForID(id);
328 assertEquals("size", 3 * i + 1 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
329 service.getChallengeForID(id);
330 assertEquals("size", 3 * i + 1 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
331 service.getQuestionForID(id);
332 assertEquals("size", 3 * i + 1 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
333 service.getQuestionForID(id);
334 assertEquals("size", 3 * i + 1 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
335 service.getChallengeForID(id);
336 assertEquals("size", 3 * i + 2 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
337 service.getChallengeForID(id);
338 assertEquals("size", 3 * i + 3 + generatedBefore, getMService().getNumberOfGeneratedCaptchas());
339 }
340
341
342 }
343
344 public void testSetMinGuarantedStorageDelayInSeconds() throws Exception {
345 assertEquals("initial", MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS, getMService().getMinGuarantedStorageDelayInSeconds());
346 getMService().setMinGuarantedStorageDelayInSeconds(80);
347 assertEquals("changed", 80, getMService().getMinGuarantedStorageDelayInSeconds());
348
349 getMService().setMinGuarantedStorageDelayInSeconds(100);
350 fullLoad();
351
352 assertEquals("none should be collected", 0, getMService().getNumberOfGarbageCollectedCaptcha());
353
354 }
355
356 public void testGetMinGuarantedStorageDelayInSeconds() throws Exception {
357 assertEquals("initial", MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS, getMService().getMinGuarantedStorageDelayInSeconds());
358 }
359
360
361 public void testAutomaticGarbaging() throws Exception {
362 loadAndWait();
363 assertEquals("none should have been collected yet", 0, getMService().getNumberOfGarbageCollectedCaptcha());
364 getMService().getChallengeForID("new");
365 assertEquals("all should have been collected", CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION,
366 getMService().getNumberOfGarbageCollectedCaptcha());
367 getMService().emptyCaptchaStore();
368 assertEquals("we should not been able to garbage collect",
369 0,
370 getMService().getNumberOfGarbageCollectableCaptchas());
371 getMService().setMinGuarantedStorageDelayInSeconds(5);
372 assertEquals("we should not been able to garbage collect",
373 0,
374 getMService().getNumberOfGarbageCollectableCaptchas());
375
376 fullLoad();
377
378
379 assertEquals("to be valid we should not been able to garbage collect",
380 0,
381 getMService().getNumberOfGarbageCollectableCaptchas());
382 assertEquals("store size should be full",
383 MAX_CAPTCHA_STORE_SIZE,
384 getMService().getCaptchaStoreSize());
385 Thread.sleep(5 * 1000 + 100);
386 assertEquals("all should be collectable",
387 MAX_CAPTCHA_STORE_SIZE,
388 getMService().getNumberOfGarbageCollectableCaptchas());
389
390
391 }
392
393
394 public void testMaxStoreSizeConstraint() throws Exception {
395
396 fullLoad();
397 for (int i = 0; i < 100; i++) {
398 try {
399 getMService().getChallengeForID("new" + String.valueOf(i));
400 fail("should have thrown a captcha store full exception");
401 } catch (CaptchaServiceException e) {
402 assertEquals("store should be of max size", MAX_CAPTCHA_STORE_SIZE, getMService().getCaptchaStoreSize());
403 }
404 }
405
406 Thread.sleep(1000);
407 getMService().setMinGuarantedStorageDelayInSeconds(1);
408 Thread.sleep(1000);
409 try {
410 fullLoad();
411
412 } catch (CaptchaServiceException e) {
413 fail("should not have thrown a captcha store full exception");
414 }
415
416 }
417
418 private void fullLoad() {
419 int i = 0;
420 try {
421 for (i = 0; i < MAX_CAPTCHA_STORE_SIZE; i++) {
422 String id = String.valueOf(i);
423 service.generateAndStoreCaptcha(Locale.getDefault(), id);
424 }
425 } catch (CaptchaServiceException e) {
426 System.out.println("i = " + i);
427 e.printStackTrace();
428 throw e;
429 }
430 }
431
432 private void loadAndWait() throws InterruptedException {
433 for (int i = 0; i < CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION; i++) {
434 String id = String.valueOf(i);
435 service.generateAndStoreCaptcha(Locale.getDefault(), id);
436 }
437 Thread.sleep(MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS * 1000 + 100);
438 }
439
440
441 protected class MockedManageableCaptchaService extends AbstractManageableCaptchaService {
442
443 protected MockedManageableCaptchaService(CaptchaStore captchaStore, com.octo.captcha.engine.CaptchaEngine captchaEngine,
444 int minGuarantedStorageDelayInSeconds,
445 int maxCaptchaStoreSize,
446 int captchaStoreLoadBeforeGarbageCollection) {
447 super(captchaStore, captchaEngine, minGuarantedStorageDelayInSeconds, maxCaptchaStoreSize,
448 captchaStoreLoadBeforeGarbageCollection);
449 }
450
451 /***
452 * This method must be implemented by sublcasses and : Retrieve the challenge from the captcha Make and return a
453 * clone of the challenge Return the clone It has be design in order to let the service dipose the challenge of
454 * the captcha after rendering. It should be implemented for all captcha type (@see ImageCaptchaService
455 * implementations for exemple)
456 *
457 * @return a Challenge Clone
458 */
459 protected Object getChallengeClone(Captcha captcha) {
460 return new String(captcha.getChallenge().toString()) + MockedCaptchaService.CLONE_CHALLENGE;
461 }
462
463 }
464
465
466 }