/** * Copyright (c) 2008 Greg Whalin * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the BSD license * * This library is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. * * You should have received a copy of the BSD License along with this * library. * * @author Kevin Burton * @author greg whalin <greg@meetup.com> */ package com.meetup.memcached.test; import com.meetup.memcached.*; import java.util.*; import java.io.Serializable; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.BasicConfigurator; public class UnitTests { // logger private static Logger log = Logger.getLogger( UnitTests.class.getName() ); public static MemcachedClient mc = null; public static void test1() { mc.set( "foo", Boolean.TRUE ); Boolean b = (Boolean)mc.get( "foo" ); assert b.booleanValue(); log.error( "+ store/retrieve Boolean type test passed" ); } public static void test2() { mc.set( "foo", new Integer( Integer.MAX_VALUE ) ); Integer i = (Integer)mc.get( "foo" ); assert i.intValue() == Integer.MAX_VALUE; log.error( "+ store/retrieve Integer type test passed" ); } public static void test3() { String input = "test of string encoding"; mc.set( "foo", input ); String s = (String)mc.get( "foo" ); assert s.equals( input ); log.error( "+ store/retrieve String type test passed" ); } public static void test4() { mc.set( "foo", new Character( 'z' ) ); Character c = (Character)mc.get( "foo" ); assert c.charValue() == 'z'; log.error( "+ store/retrieve Character type test passed" ); } public static void test5() { mc.set( "foo", new Byte( (byte)127 ) ); Byte b = (Byte)mc.get( "foo" ); assert b.byteValue() == 127; log.error( "+ store/retrieve Byte type test passed" ); } public static void test6() { mc.set( "foo", new StringBuffer( "hello" ) ); StringBuffer o = (StringBuffer)mc.get( "foo" ); assert o.toString().equals( "hello" ); log.error( "+ store/retrieve StringBuffer type test passed" ); } public static void test7() { mc.set( "foo", new Short( (short)100 ) ); Short o = (Short)mc.get( "foo" ); assert o.shortValue() == 100; log.error( "+ store/retrieve Short type test passed" ); } public static void test8() { mc.set( "foo", new Long( Long.MAX_VALUE ) ); Long o = (Long)mc.get( "foo" ); assert o.longValue() == Long.MAX_VALUE; log.error( "+ store/retrieve Long type test passed" ); } public static void test9() { mc.set( "foo", new Double( 1.1 ) ); Double o = (Double)mc.get( "foo" ); assert o.doubleValue() == 1.1; log.error( "+ store/retrieve Double type test passed" ); } public static void test10() { mc.set( "foo", new Float( 1.1f ) ); Float o = (Float)mc.get( "foo" ); assert o.floatValue() == 1.1f; log.error( "+ store/retrieve Float type test passed" ); } public static void test11() { mc.set( "foo", new Integer( 100 ), new Date( System.currentTimeMillis() )); try { Thread.sleep( 1000 ); } catch ( Exception ex ) { } assert mc.get( "foo" ) == null; log.error( "+ store/retrieve w/ expiration test passed" ); } public static void test12() { long i = 0; mc.storeCounter("foo", i); mc.incr("foo"); // foo now == 1 mc.incr("foo", (long)5); // foo now == 6 long j = mc.decr("foo", (long)2); // foo now == 4 assert j == 4; assert j == mc.getCounter( "foo" ); log.error( "+ incr/decr test passed" ); } public static void test13() { Date d1 = new Date(); mc.set("foo", d1); Date d2 = (Date) mc.get("foo"); assert d1.equals( d2 ); log.error( "+ store/retrieve Date type test passed" ); } public static void test14() { assert !mc.keyExists( "foobar123" ); mc.set( "foobar123", new Integer( 100000) ); assert mc.keyExists( "foobar123" ); log.error( "+ store/retrieve test passed" ); assert !mc.keyExists( "counterTest123" ); mc.storeCounter( "counterTest123", 0 ); assert mc.keyExists( "counterTest123" ); log.error( "+ counter store test passed" ); } public static void test15() { Map stats = mc.statsItems(); assert stats != null; stats = mc.statsSlabs(); assert stats != null; log.error( "+ stats test passed" ); } public static void test16() { assert !mc.set( "foo", null ); log.error( "+ invalid data store [null] test passed" ); } public static void test17() { mc.set( "foo bar", Boolean.TRUE ); Boolean b = (Boolean)mc.get( "foo bar" ); assert b.booleanValue(); log.error( "+ store/retrieve Boolean type test passed" ); } public static void test18() { long i = 0; mc.addOrIncr( "foo" ); // foo now == 0 mc.incr( "foo" ); // foo now == 1 mc.incr( "foo", (long)5 ); // foo now == 6 mc.addOrIncr( "foo" ); // foo now 7 long j = mc.decr( "foo", (long)3 ); // foo now == 4 assert j == 4; assert j == mc.getCounter( "foo" ); log.error( "+ incr/decr test passed" ); } public static void test19() { int max = 100; String[] keys = new String[ max ]; for ( int i=0; i<max; i++ ) { keys[i] = Integer.toString(i); mc.set( keys[i], "value"+i ); } Map<String,Object> results = mc.getMulti( keys ); for ( int i=0; i<max; i++ ) { assert results.get( keys[i]).equals( "value"+i ); } log.error( "+ getMulti test passed" ); } public static void test20( int max, int skip, int start ) { log.warn( String.format( "test 20 starting with start=%5d skip=%5d max=%7d", start, skip, max ) ); int numEntries = max/skip+1; String[] keys = new String[ numEntries ]; byte[][] vals = new byte[ numEntries ][]; int size = start; for ( int i=0; i<numEntries; i++ ) { keys[i] = Integer.toString( size ); vals[i] = new byte[size + 1]; for ( int j=0; j<size + 1; j++ ) vals[i][j] = (byte)j; mc.set( keys[i], vals[i] ); size += skip; } Map<String,Object> results = mc.getMulti( keys ); for ( int i=0; i<numEntries; i++ ) assert Arrays.equals( (byte[])results.get( keys[i]), vals[i] ); log.warn( String.format( "test 20 finished with start=%5d skip=%5d max=%7d", start, skip, max ) ); } public static void test21() { mc.set( "foo", new StringBuilder( "hello" ) ); StringBuilder o = (StringBuilder)mc.get( "foo" ); assert o.toString().equals( "hello" ); log.error( "+ store/retrieve StringBuilder type test passed" ); } public static void test22() { byte[] b = new byte[10]; for ( int i = 0; i < 10; i++ ) b[i] = (byte)i; mc.set( "foo", b ); assert Arrays.equals( (byte[])mc.get( "foo" ), b ); log.error( "+ store/retrieve byte[] type test passed" ); } public static void test23() { TestClass tc = new TestClass( "foo", "bar", new Integer( 32 ) ); mc.set( "foo", tc ); assert tc.equals( (TestClass)mc.get( "foo" ) ); log.error( "+ store/retrieve serialized object test passed" ); } public static void test24() { String[] allKeys = { "key1", "key2", "key3", "key4", "key5", "key6", "key7" }; String[] setKeys = { "key1", "key3", "key5", "key7" }; for ( String key : setKeys ) { mc.set( key, key ); } Map<String,Object> results = mc.getMulti( allKeys ); assert allKeys.length == results.size(); for ( String key : setKeys ) { String val = (String)results.get( key ); assert key.equals( val ); } log.error( "+ getMulti w/ keys that don't exist test passed" ); } public static void runAlTests( MemcachedClient mc ) { test14(); for ( int t = 0; t < 2; t++ ) { mc.setCompressEnable( ( t&1 ) == 1 ); test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); test9(); test10(); test11(); test12(); test13(); test15(); test16(); test17(); test21(); test22(); test23(); test24(); for ( int i = 0; i < 3; i++ ) test19(); test20( 8191, 1, 0 ); test20( 8192, 1, 0 ); test20( 8193, 1, 0 ); test20( 16384, 100, 0 ); test20( 17000, 128, 0 ); test20( 128*1024, 1023, 0 ); test20( 128*1024, 1023, 1 ); test20( 128*1024, 1024, 0 ); test20( 128*1024, 1024, 1 ); test20( 128*1024, 1023, 0 ); test20( 128*1024, 1023, 1 ); test20( 128*1024, 1024, 0 ); test20( 128*1024, 1024, 1 ); test20( 900*1024, 32*1024, 0 ); test20( 900*1024, 32*1024, 1 ); } } /** * This runs through some simple tests of the MemcacheClient. * * Command line args: * args[0] = number of threads to spawn * args[1] = number of runs per thread * args[2] = size of object to store * * @param args the command line arguments */ public static void main(String[] args) { BasicConfigurator.configure(); org.apache.log4j.Logger.getRootLogger().setLevel( Level.WARN ); if ( !UnitTests.class.desiredAssertionStatus() ) { System.err.println( "WARNING: assertions are disabled!" ); try { Thread.sleep( 3000 ); } catch ( InterruptedException e ) {} } String[] serverlist = { "192.168.1.50:1620", "192.168.1.50:1621", "192.168.1.50:1622", "192.168.1.50:1623", "192.168.1.50:1624", "192.168.1.50:1625", "192.168.1.50:1626", "192.168.1.50:1627", "192.168.1.50:1628", "192.168.1.50:1629" }; Integer[] weights = { 1, 1, 1, 1, 10, 5, 1, 1, 1, 3 }; if ( args.length > 0 ) serverlist = args; // initialize the pool for memcache servers SockIOPool pool = SockIOPool.getInstance( "test" ); pool.setServers( serverlist ); pool.setWeights( weights ); pool.setMaxConn( 250 ); pool.setNagle( false ); pool.setHashingAlg( SockIOPool.CONSISTENT_HASH ); pool.initialize(); mc = new MemcachedClient( "test" ); runAlTests( mc ); } /** * Class for testing serializing of objects. * * @author $Author: $ * @version $Revision: $ $Date: $ */ public static final class TestClass implements Serializable { private String field1; private String field2; private Integer field3; public TestClass( String field1, String field2, Integer field3 ) { this.field1 = field1; this.field2 = field2; this.field3 = field3; } public String getField1() { return this.field1; } public String getField2() { return this.field2; } public Integer getField3() { return this.field3; } public boolean equals( Object o ) { if ( this == o ) return true; if ( !( o instanceof TestClass ) ) return false; TestClass obj = (TestClass)o; return ( ( this.field1 == obj.getField1() || ( this.field1 != null && this.field1.equals( obj.getField1() ) ) ) && ( this.field2 == obj.getField2() || ( this.field2 != null && this.field2.equals( obj.getField2() ) ) ) && ( this.field3 == obj.getField3() || ( this.field3 != null && this.field3.equals( obj.getField3() ) ) ) ); } } }