1 package org.apache.jcs.access;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.InputStreamReader;
24 import java.util.Iterator;
25 import java.util.Random;
26 import java.util.StringTokenizer;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.apache.jcs.JCS;
32 import org.apache.jcs.engine.ElementAttributes;
33 import org.apache.jcs.engine.behavior.IElementAttributes;
34 import org.apache.jcs.engine.control.CompositeCacheManager;
35 import org.apache.jcs.engine.control.event.ElementEventHandlerMockImpl;
36
37 /***
38 * Allows the user to run common cache commands from the command line for a test
39 * cache.
40 *
41 * This also provide basic methods for use in unit tests.
42 *
43 */
44 public class TestCacheAccess
45 {
46 private final static Log log = LogFactory.getLog( TestCacheAccess.class );
47
48 private JCS cache_control = null;
49
50 private static boolean isSysOut = false;
51
52 /***
53 * Construct and initialize the cachecontrol based on the config file.
54 *
55 */
56 public TestCacheAccess()
57 {
58 this( "testCache1" );
59 }
60
61 /***
62 * @param regionName the name of the region.
63 */
64 public TestCacheAccess( String regionName )
65 {
66 try
67 {
68 cache_control = JCS.getInstance( regionName );
69 }
70 catch ( Exception e )
71 {
72 log.error( "Problem getting cache instance", e );
73 p( e.toString() );
74 }
75 }
76
77 /***
78 * This is the main loop called by the main method.
79 */
80 public void runLoop()
81 {
82
83 try
84 {
85 try
86 {
87
88
89 boolean notDone = true;
90 String message = null;
91
92 BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
93
94 help();
95
96 while ( notDone )
97 {
98 p( "enter command:" );
99
100 message = br.readLine();
101
102 if ( message.startsWith( "help" ) )
103 {
104 help();
105 }
106 else if ( message.startsWith( "gc" ) )
107 {
108 System.gc();
109 }
110 else if ( message.startsWith( "getAttributeNames" ) )
111 {
112 long n_start = System.currentTimeMillis();
113 String groupName = null;
114 StringTokenizer toke = new StringTokenizer( message );
115 int tcnt = 0;
116 while ( toke.hasMoreElements() )
117 {
118 tcnt++;
119 String t = (String) toke.nextElement();
120 if ( tcnt == 2 )
121 {
122 groupName = t.trim();
123 }
124 }
125 getAttributeNames( groupName );
126 long n_end = System.currentTimeMillis();
127 p( "---got attrNames for " + groupName + " in " + String.valueOf( n_end - n_start )
128 + " millis ---" );
129 }
130 else if ( message.startsWith( "shutDown" ) )
131 {
132 CompositeCacheManager.getInstance().shutDown();
133
134 notDone = false;
135
136 return;
137 }
138 else
139
140
141
142 if ( message.startsWith( "getm" ) )
143 {
144
145 int num = 0;
146 boolean show = true;
147
148 StringTokenizer toke = new StringTokenizer( message );
149 int tcnt = 0;
150 while ( toke.hasMoreElements() )
151 {
152 tcnt++;
153 String t = (String) toke.nextElement();
154 if ( tcnt == 2 )
155 {
156 try
157 {
158 num = Integer.parseInt( t.trim() );
159 }
160 catch ( NumberFormatException nfe )
161 {
162 p( t + "not a number" );
163 }
164 }
165 else if ( tcnt == 3 )
166 {
167 show = new Boolean( t ).booleanValue();
168 }
169 }
170
171 if ( tcnt < 2 )
172 {
173 p( "usage: get numbertoget show values[true|false]" );
174 }
175 else
176 {
177 getMultiple( num, show );
178 }
179 }
180 else
181
182
183 if ( message.startsWith( "getg" ) )
184 {
185
186 String key = null;
187 String group = null;
188 boolean show = true;
189
190 StringTokenizer toke = new StringTokenizer( message );
191 int tcnt = 0;
192 while ( toke.hasMoreElements() )
193 {
194 tcnt++;
195 String t = (String) toke.nextElement();
196 if ( tcnt == 2 )
197 {
198 key = t.trim();
199 }
200 else if ( tcnt == 3 )
201 {
202 group = t.trim();
203 }
204 else if ( tcnt == 4 )
205 {
206 show = new Boolean( t ).booleanValue();
207 }
208 }
209
210 if ( tcnt < 2 )
211 {
212 p( "usage: get key show values[true|false]" );
213 }
214 else
215 {
216
217 long n_start = System.currentTimeMillis();
218 try
219 {
220 Object obj = cache_control.getFromGroup( key, group );
221 if ( show && obj != null )
222 {
223 p( obj.toString() );
224 }
225 }
226 catch ( Exception e )
227 {
228 log.error( e );
229 }
230 long n_end = System.currentTimeMillis();
231 p( "---got " + key + " from group " + group + " in " + String.valueOf( n_end - n_start )
232 + " millis ---" );
233 }
234 }
235 else
236
237
238 if ( message.startsWith( "getag" ) )
239 {
240
241
242 int num = 0;
243 String group = null;
244 boolean show = true;
245
246 StringTokenizer toke = new StringTokenizer( message );
247 int tcnt = 0;
248 while ( toke.hasMoreElements() )
249 {
250 tcnt++;
251 String t = (String) toke.nextElement();
252 if ( tcnt == 2 )
253 {
254 num = Integer.parseInt( t.trim() );
255 }
256 else if ( tcnt == 3 )
257 {
258 group = t.trim();
259 }
260 else if ( tcnt == 4 )
261 {
262 show = new Boolean( t ).booleanValue();
263 }
264 }
265
266 if ( tcnt < 2 )
267 {
268 p( "usage: get key show values[true|false]" );
269 }
270 else
271 {
272
273 long n_start = System.currentTimeMillis();
274 try
275 {
276 for ( int a = 0; a < num; a++ )
277 {
278 Object obj = cache_control.getFromGroup( "keygr" + a, group );
279 if ( show && obj != null )
280 {
281 p( obj.toString() );
282 }
283 }
284 }
285 catch ( Exception e )
286 {
287 log.error( e );
288 }
289 long n_end = System.currentTimeMillis();
290 p( "---got " + num + " from group " + group + " in " + String.valueOf( n_end - n_start )
291 + " millis ---" );
292 }
293 }
294 else
295
296
297 if ( message.startsWith( "get" ) )
298 {
299
300
301 String key = null;
302 boolean show = true;
303
304 StringTokenizer toke = new StringTokenizer( message );
305 int tcnt = 0;
306 while ( toke.hasMoreElements() )
307 {
308 tcnt++;
309 String t = (String) toke.nextElement();
310 if ( tcnt == 2 )
311 {
312 key = t.trim();
313 }
314 else if ( tcnt == 3 )
315 {
316 show = new Boolean( t ).booleanValue();
317 }
318 }
319
320 if ( tcnt < 2 )
321 {
322 p( "usage: get key show values[true|false]" );
323 }
324 else
325 {
326
327 long n_start = System.currentTimeMillis();
328 try
329 {
330 Object obj = cache_control.get( key );
331 if ( show && obj != null )
332 {
333 p( obj.toString() );
334 }
335 }
336 catch ( Exception e )
337 {
338 log.error( e );
339 }
340 long n_end = System.currentTimeMillis();
341 p( "---got " + key + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
342 }
343 }
344 else if ( message.startsWith( "putg" ) )
345 {
346
347 String group = null;
348 String key = null;
349 StringTokenizer toke = new StringTokenizer( message );
350 int tcnt = 0;
351 while ( toke.hasMoreElements() )
352 {
353 tcnt++;
354 String t = (String) toke.nextElement();
355 if ( tcnt == 2 )
356 {
357 key = t.trim();
358 }
359 else if ( tcnt == 3 )
360 {
361 group = t.trim();
362 }
363 }
364
365 if ( tcnt < 3 )
366 {
367 p( "usage: putg key group" );
368 }
369 else
370 {
371 long n_start = System.currentTimeMillis();
372 cache_control.putInGroup( key, group,
373 "data from putg ----asdfasfas-asfasfas-asfas in group " + group );
374 long n_end = System.currentTimeMillis();
375 p( "---put " + key + " in group " + group + " in " + String.valueOf( n_end - n_start )
376 + " millis ---" );
377 }
378 }
379 else
380
381
382 if ( message.startsWith( "putag" ) )
383 {
384
385 String group = null;
386 int num = 0;
387 StringTokenizer toke = new StringTokenizer( message );
388 int tcnt = 0;
389 while ( toke.hasMoreElements() )
390 {
391 tcnt++;
392 String t = (String) toke.nextElement();
393 if ( tcnt == 2 )
394 {
395 num = Integer.parseInt( t.trim() );
396 }
397 else if ( tcnt == 3 )
398 {
399 group = t.trim();
400 }
401 }
402
403 if ( tcnt < 3 )
404 {
405 p( "usage: putag num group" );
406 }
407 else
408 {
409 long n_start = System.currentTimeMillis();
410 for ( int a = 0; a < num; a++ )
411 {
412 cache_control.putInGroup( "keygr" + a, group, "data " + a
413 + " from putag ----asdfasfas-asfasfas-asfas in group " + group );
414 }
415 long n_end = System.currentTimeMillis();
416 p( "---put " + num + " in group " + group + " in " + String.valueOf( n_end - n_start )
417 + " millis ---" );
418 }
419 }
420 else
421
422
423 if ( message.startsWith( "putm" ) )
424 {
425 String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
426 int num = Integer.parseInt( numS.trim() );
427 if ( numS == null )
428 {
429 p( "usage: putm numbertoput" );
430 }
431 else
432 {
433 putMultiple( num );
434 }
435 }
436 else
437
438
439 if ( message.startsWith( "pute" ) )
440 {
441 String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
442 int num = Integer.parseInt( numS.trim() );
443 if ( numS == null )
444 {
445 p( "usage: putme numbertoput" );
446 }
447 else
448 {
449 long n_start = System.currentTimeMillis();
450 for ( int n = 0; n < num; n++ )
451 {
452 IElementAttributes attrp = cache_control.getDefaultElementAttributes();
453 ElementEventHandlerMockImpl hand = new ElementEventHandlerMockImpl();
454 attrp.addElementEventHandler( hand );
455 cache_control.put( "key" + n, "data" + n + " put from ta = junk", attrp );
456 }
457 long n_end = System.currentTimeMillis();
458 p( "---put " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
459 }
460 }
461 else if ( message.startsWith( "put" ) )
462 {
463
464 String key = null;
465 String val = null;
466 StringTokenizer toke = new StringTokenizer( message );
467 int tcnt = 0;
468 while ( toke.hasMoreElements() )
469 {
470 tcnt++;
471 String t = (String) toke.nextElement();
472 if ( tcnt == 2 )
473 {
474 key = t.trim();
475 }
476 else if ( tcnt == 3 )
477 {
478 val = t.trim();
479 }
480 }
481
482 if ( tcnt < 3 )
483 {
484 p( "usage: put key val" );
485 }
486 else
487 {
488
489 long n_start = System.currentTimeMillis();
490 cache_control.put( key, val );
491 long n_end = System.currentTimeMillis();
492 p( "---put " + key + " | " + val + " in " + String.valueOf( n_end - n_start )
493 + " millis ---" );
494 }
495 }
496
497 if ( message.startsWith( "removem" ) )
498 {
499 String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
500 int num = Integer.parseInt( numS.trim() );
501 if ( numS == null )
502 {
503 p( "usage: removem numbertoremove" );
504 }
505 else
506 {
507 removeMultiple( num );
508 }
509 }
510
511 else if ( message.startsWith( "removeall" ) )
512 {
513 cache_control.clear();
514 p( "removed all" );
515 }
516 else if ( message.startsWith( "remove" ) )
517 {
518 String key = message.substring( message.indexOf( " " ) + 1, message.length() );
519 cache_control.remove( key );
520 p( "removed " + key );
521 }
522 else if ( message.startsWith( "deattr" ) )
523 {
524 IElementAttributes ae = cache_control.getDefaultElementAttributes();
525 p( "Default IElementAttributes " + ae );
526 }
527 else if ( message.startsWith( "cloneattr" ) )
528 {
529 String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
530 int num = Integer.parseInt( numS.trim() );
531 if ( numS == null )
532 {
533 p( "usage: put numbertoput" );
534 }
535 else
536 {
537 IElementAttributes attrp = new ElementAttributes();
538 long n_start = System.currentTimeMillis();
539 for ( int n = 0; n < num; n++ )
540 {
541 attrp.copy();
542 }
543 long n_end = System.currentTimeMillis();
544 p( "---cloned attr " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
545 }
546 }
547 else if ( message.startsWith( "switch" ) )
548 {
549 String name = message.substring( message.indexOf( " " ) + 1, message.length() );
550
551 setRegion( name );
552 p( "switched to cache = " + name );
553 p( cache_control.toString() );
554 }
555 else if ( message.startsWith( "stats" ) )
556 {
557 p( cache_control.getStats() );
558 }
559 else if ( message.startsWith( "gc" ) )
560 {
561 System.gc();
562 p( "Called system.gc()" );
563 }
564 else if ( message.startsWith( "random" ) )
565 if ( message.startsWith( "random" ) )
566 {
567 String rangeS = "";
568 String numOpsS = "";
569 boolean show = true;
570
571 StringTokenizer toke = new StringTokenizer( message );
572 int tcnt = 0;
573 while ( toke.hasMoreElements() )
574 {
575 tcnt++;
576 String t = (String) toke.nextElement();
577 if ( tcnt == 2 )
578 {
579 rangeS = t.trim();
580 }
581 else if ( tcnt == 3 )
582 {
583 numOpsS = t.trim();
584 }
585 else if ( tcnt == 4 )
586 {
587 show = new Boolean( t ).booleanValue();
588 }
589 }
590
591 String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
592
593 int range = 0;
594 int numOps = 0;
595 try
596 {
597 range = Integer.parseInt( rangeS.trim() );
598 numOps = Integer.parseInt( numOpsS.trim() );
599 }
600 catch ( Exception e )
601 {
602 p( "usage: random range numOps show" );
603 p( "ex. random 100 1000 false" );
604 }
605 if ( numS == null )
606 {
607 p( "usage: random range numOps show" );
608 p( "ex. random 100 1000 false" );
609 }
610 else
611 {
612 random( range, numOps, show );
613 }
614 }
615
616 }
617 }
618 catch ( Exception e )
619 {
620 p( e.toString() );
621 e.printStackTrace( System.out );
622 }
623
624 }
625 catch ( Exception e )
626 {
627 p( e.toString() );
628 e.printStackTrace( System.out );
629 }
630
631 }
632
633 /***
634 * Test harness.
635 *
636 * @param args
637 * The command line arguments
638 */
639 public static void main( String[] args )
640 {
641 isSysOut = true;
642 String ccfFileName = args[0];
643 if ( ccfFileName != null )
644 {
645 JCS.setConfigFilename( ccfFileName );
646 }
647 TestCacheAccess tca = new TestCacheAccess( "testCache1" );
648 tca.runLoop();
649 }
650
651
652
653
654 /***
655 * Gets multiple items from the cache with keys of the form key1, key2, key3
656 * up to key[num].
657 *
658 * @param num
659 * int
660 */
661 public void getMultiple( int num )
662 {
663 getMultiple( num, false );
664 }
665
666 /***
667 * @param num
668 * @param show
669 */
670 public void getMultiple( int num, boolean show )
671 {
672 long n_start = System.currentTimeMillis();
673 for ( int n = 0; n < num; n++ )
674 {
675 try
676 {
677 Object obj = cache_control.get( "key" + n );
678 if ( show && obj != null )
679 {
680 p( obj.toString() );
681 }
682 }
683 catch ( Exception e )
684 {
685 log.error( e );
686 }
687 }
688 long n_end = System.currentTimeMillis();
689 p( "---got " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
690 }
691
692 /***
693 * Puts multiple items into the cache.
694 *
695 * @param num
696 * int
697 */
698 public void putMultiple( int num )
699 {
700 try
701 {
702 long n_start = System.currentTimeMillis();
703 for ( int n = 0; n < num; n++ )
704 {
705 cache_control.put( "key" + n, "data" + n + " put from ta = junk" );
706 }
707 long n_end = System.currentTimeMillis();
708 p( "---put " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
709 }
710 catch ( Exception e )
711 {
712 log.error( e );
713 }
714 }
715
716 /***
717 * Removes multiple items from the cache.
718 *
719 * @param num
720 * int
721 */
722 public void removeMultiple( int num )
723 {
724 try
725 {
726 long n_start = System.currentTimeMillis();
727 for ( int n = 0; n < num; n++ )
728 {
729 cache_control.remove( "key" + n );
730 }
731 long n_end = System.currentTimeMillis();
732 p( "---removed " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
733 }
734 catch ( Exception e )
735 {
736 log.error( e );
737 }
738 }
739
740 /***
741 * The random method performs numOps number of operations. The operations
742 * will be a mix of puts, gets, and removes. The key range will be from 0 to
743 * range.
744 *
745 * @param range
746 * int The end of the key range.
747 * @param numOps
748 * int The number of operations to perform
749 */
750 public void random( int range, int numOps )
751 {
752 random( range, numOps, false );
753 }
754
755 /***
756 * @param range
757 * @param numOps
758 * @param show
759 */
760 public void random( int range, int numOps, boolean show )
761 {
762 try
763 {
764 for ( int i = 0; i < numOps; i++ )
765 {
766 Random ran = new Random( i );
767 int n = ran.nextInt( 4 );
768 int kn = ran.nextInt( range );
769 String key = "key" + kn;
770 if ( n == 1 )
771 {
772 cache_control.put( key, "data" + i + " junk asdfffffffadfasdfasf " + kn + ":" + n );
773 if ( show )
774 {
775 p( "put " + key );
776 }
777 }
778 else if ( n == 2 )
779 {
780 cache_control.remove( key );
781 if ( show )
782 {
783 p( "removed " + key );
784 }
785 }
786 else
787 {
788
789 Object obj = cache_control.get( key );
790 if ( show && obj != null )
791 {
792 p( obj.toString() );
793 }
794 }
795
796 if ( i % 10000 == 0 )
797 {
798 p( cache_control.getStats() );
799 }
800
801 }
802 p( "Finished random cycle of " + numOps );
803 }
804 catch ( Exception e )
805 {
806 p( e.toString() );
807 e.printStackTrace( System.out );
808 }
809 }
810
811 /***
812 * Sets the region to be used by test methods.
813 *
814 * @param name
815 * String -- Name of region
816 */
817 public void setRegion( String name )
818 {
819 try
820 {
821 cache_control = JCS.getInstance( name );
822 }
823 catch ( Exception e )
824 {
825 p( e.toString() );
826 e.printStackTrace( System.out );
827 }
828
829 }
830
831
832 /***
833 * The tester will print to the console if isSysOut is true, else it will
834 * log. It is false by default. When run via the main method, isSysOut will
835 * be set to true
836 *
837 * @param s
838 * String to print or log
839 */
840 public static void p( String s )
841 {
842 if ( isSysOut )
843 {
844 System.out.println( s );
845 }
846 else
847 {
848 if ( log.isDebugEnabled() )
849 {
850 log.debug( s );
851 }
852 }
853 }
854
855 /***
856 * Displays usage information for command line testing.
857 */
858 public static void help()
859 {
860 p( "\n\n\n\n" );
861 p( "type 'shutDown' to shutdown the cache" );
862 p( "type 'getm num show[false|true]' to get num automatically from a region" );
863 p( "type 'putm num' to put num automatically to a region" );
864 p( "type 'removeall' to remove all items in a region" );
865 p( "type 'remove key' to remove" );
866 p( "type 'removem num' to remove a number automatically" );
867 p( "type 'get key show' to get" );
868 p( "type 'getg key group show' to get" );
869 p( "type 'getag num group show' to get automatically from a group" );
870 p( "type 'getAttributeNames group' to get a list og the group elements" );
871 p( "type 'putg key group val' to put" );
872 p( "type 'putag num group' to put automatically from a group" );
873 p( "type 'put key val' to put" );
874 p( "type 'stats' to get stats" );
875 p( "type 'deattr' to get the default element attributes" );
876 p( "type 'cloneattr num' to clone attr" );
877 p( "type 'random range numOps' to put, get, and remove randomly" );
878 p( "type 'switch name' to switch to this region name" );
879 p( "type 'gc' to call System.gc()" );
880 p( "type 'help' for commands" );
881
882 }
883
884 /***
885 * Gets the attributeNames attribute of the TestCacheAccess class
886 *
887 * @param groupName
888 */
889 public void getAttributeNames( String groupName )
890 {
891 Iterator iter = cache_control.getGroupKeys( groupName ).iterator();
892
893 while ( iter.hasNext() )
894 {
895 p( "=" + (String) iter.next() );
896 }
897 }
898
899 }