Thrift test code

Summary: Did I promise you this or what?! Interoperable test servers and clients in both C++ and Java that you can use to check that they all work, all perform well, and that they all actually talk to each other!

Problem: How we gon' test this Thrift bizniss?

Solution: Write some test scenarios in each language.

Reviewed By: aditya

Test Plan: This IS the test plan.

Notes: These tools are actually pretty easy to use, so long as you remember to type 'ant' in the java directory instead of 'make'.





git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664716 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/cpp/Makefile b/test/cpp/Makefile
index 6afb30b..21c09ec 100644
--- a/test/cpp/Makefile
+++ b/test/cpp/Makefile
@@ -7,28 +7,29 @@
 target: all
 
 # Tools
-THRIFT = /usr/local/bin/thrift
+THRIFT = thrift
 CC     = g++
 LD     = g++
 
 # Compiler flags
 LIBS  = ../../lib/cpp/server/TSimpleServer.cc \
 	../../lib/cpp/protocol/TBinaryProtocol.cc \
+	../../lib/cpp/transport/TBufferedTransport.cc \
 	../../lib/cpp/transport/TServerSocket.cc \
 	../../lib/cpp/transport/TSocket.cc
-CFL   = -Wall -g -I../../lib/cpp $(LIBS)
-CFL   = -Wall -g -lthrift -I../../lib/cpp
+CFL   = -Wall -O3 -Igen-cpp -I../../lib/cpp $(LIBS)
+CFL   = -Wall -O3 -Igen-cpp -I../../lib/cpp -lthrift
 
 all: server client
 
 stubs: ../ThriftTest.thrift
-	$(THRIFT) ../ThriftTest.thrift
+	$(THRIFT) -cpp ../ThriftTest.thrift
 
 server: stubs
-	g++ -o TestServer $(CFL) TestServer.cc gen-cpp/ThriftTest.cc
+	g++ -o TestServer $(CFL) src/TestServer.cc gen-cpp/ThriftTest.cc
 
 client: stubs
-	g++ -o TestClient $(CFL) TestClient.cc gen-cpp/ThriftTest.cc
+	g++ -o TestClient $(CFL) src/TestClient.cc gen-cpp/ThriftTest.cc
 
 clean:
 	rm -fr TestServer TestClient gen-cpp
diff --git a/test/cpp/TestClient.cc b/test/cpp/src/TestClient.cc
similarity index 90%
rename from test/cpp/TestClient.cc
rename to test/cpp/src/TestClient.cc
index 6d2a68e..6bd06b9 100644
--- a/test/cpp/TestClient.cc
+++ b/test/cpp/src/TestClient.cc
@@ -1,11 +1,26 @@
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/time.h>
 #include "protocol/TBinaryProtocol.h"
-#include "client/TSimpleClient.h"
+#include "transport/TBufferedTransport.h"
 #include "transport/TSocket.h"
-#include "gen-cpp/ThriftTest.h"
+#include "ThriftTest.h"
 using namespace std;
 
+extern uint32_t g_socket_syscalls;
+
+// Current time, microseconds since the epoch
+uint64_t now()
+{
+  long long ret;
+  struct timeval tv;
+  
+  gettimeofday(&tv, NULL);
+  ret = tv.tv_sec;
+  ret = ret*1000*1000 + tv.tv_usec;
+  return ret;
+}
+
 int main(int argc, char** argv) {
   string host = "localhost";
   int port = 9090;
@@ -22,18 +37,25 @@
   }
 
   TSocket socket(host, port);
-  TSimpleClient simpleClient(&socket);
+  TBufferedTransport bufferedSocket(&socket, 2048);
   TBinaryProtocol binaryProtocol;
-  ThriftTestClient testClient(&simpleClient, &binaryProtocol);
+  ThriftTestClient testClient(&bufferedSocket, &binaryProtocol);
   
   int test = 0;
   for (test = 0; test < numTests; ++test) {
+
+    /**
+     * CONNECT TEST
+     */
     printf("Test #%d, connect %s:%d\n", test+1, host.c_str(), port);
-    bool success = simpleClient.open();
-    if (!success) {
-      printf("Connect failed, server down?\n");
+    try {
+      bufferedSocket.open();
+    } catch (TTransportException& ttx) {
+      printf("Connect failed: %s\n", ttx.getMessage().c_str());
       continue;
     }
+
+    uint64_t start = now();
     
     /**
      * VOID TEST
@@ -319,9 +341,13 @@
     }
     printf("}\n");
 
-    simpleClient.close();
+    uint64_t stop = now();
+    printf("Total time: %lu us\n", stop-start);
+
+    bufferedSocket.close();
   }
 
+  printf("\nSocket syscalls: %u", g_socket_syscalls);
   printf("\nAll tests done.\n");
   return 0;
 }
diff --git a/test/cpp/TestServer.cc b/test/cpp/src/TestServer.cc
similarity index 97%
rename from test/cpp/TestServer.cc
rename to test/cpp/src/TestServer.cc
index 8138166..206b6f5 100644
--- a/test/cpp/TestServer.cc
+++ b/test/cpp/src/TestServer.cc
@@ -2,7 +2,7 @@
 #include "protocol/TBinaryProtocol.h"
 #include "server/TSimpleServer.h"
 #include "transport/TServerSocket.h"
-#include "gen-cpp/ThriftTest.h"
+#include "ThriftTest.h"
 using namespace std;
 
 class TestServer : public ThriftTestServerIf {
@@ -117,12 +117,12 @@
     return thing;
   }
 
-  Numberz testEnum(Numberz thing = 0) {
+  Numberz testEnum(Numberz thing) {
     printf("testEnum(%d)\n", thing);
     return thing;
   }
 
-  UserId testTypedef(UserId thing = 0) {
+  UserId testTypedef(UserId thing) {
     printf("testTypedef(%lu)\n", thing);
     return thing;
   }
diff --git a/test/java/TestClient b/test/java/TestClient
new file mode 100755
index 0000000..ba7d81f
--- /dev/null
+++ b/test/java/TestClient
@@ -0,0 +1,2 @@
+#!/bin/bash -v
+java -cp thrifttest.jar:/usr/local/lib/libthrift.jar com.facebook.thrift.test.TestClient $1 $2 $3
diff --git a/test/java/TestServer b/test/java/TestServer
new file mode 100755
index 0000000..7c272c1
--- /dev/null
+++ b/test/java/TestServer
@@ -0,0 +1,2 @@
+#!/bin/bash -v
+java -server -cp thrifttest.jar:/usr/local/lib/libthrift.jar com.facebook.thrift.test.TestServer $1
diff --git a/test/java/build.xml b/test/java/build.xml
new file mode 100644
index 0000000..80a73d7
--- /dev/null
+++ b/test/java/build.xml
@@ -0,0 +1,36 @@
+<project name="thrifttest" default="test" basedir=".">
+
+  <description>Thrift Test Build File</description>
+
+  <property name="src" location="src" />
+  <property name="gen" location="gen-java" />
+  <property name="build" location="build" />
+  <property name="cpath" location="/usr/local/lib/libthrift.jar" />
+
+  <target name="init">
+    <tstamp />
+    <mkdir dir="${build}"/>
+  </target>
+
+  <target name="generate">
+    <exec executable="thrift">
+      <arg line="-java ../ThriftTest.thrift" />
+    </exec>
+  </target>
+
+  <target name="compile" depends="init,generate">
+    <javac srcdir="${gen}" destdir="${build}" classpath="${cpath}" />
+    <javac srcdir="${src}" destdir="${build}" classpath="${cpath}:${gen}" />
+  </target>
+
+  <target name="test" depends="compile">
+    <jar jarfile="thrifttest.jar" basedir="${build}"/>
+  </target>
+
+  <target name="clean">
+    <delete dir="gen-java" />
+    <delete dir="${build}" />
+    <delete file="thrifttest.jar" />
+  </target>
+
+</project>
diff --git a/test/java/src/TestClient.java b/test/java/src/TestClient.java
new file mode 100644
index 0000000..70cf826
--- /dev/null
+++ b/test/java/src/TestClient.java
@@ -0,0 +1,351 @@
+package com.facebook.thrift.test;
+
+import ThriftTest.*;
+import com.facebook.thrift.types.*;
+import com.facebook.thrift.transport.TSocket;
+import com.facebook.thrift.transport.TTransportException;
+import com.facebook.thrift.protocol.TBinaryProtocol;
+import com.facebook.thrift.protocol.TString;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ArrayList;
+
+/**
+ * Test Java client for thrift. Essentially just a copy of the C++ version,
+ * this makes a variety of requests to enable testing for both performance and
+ * correctness of the output.
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+public class TestClient {
+  public static void main(String [] args) {
+    try {
+      String host = "localhost";
+      int port = 9090;
+      int numTests = 1;
+      
+      if (args.length > 0) {
+        host = args[0];
+      }
+      if (args.length > 1) {
+        port = Integer.valueOf(args[1]);
+      }
+      if (args.length > 2) {
+        numTests = Integer.valueOf(args[2]);
+      }
+      
+      TSocket tSocket =
+        new TSocket(host, port);
+      TBinaryProtocol binaryProtocol =
+        new TBinaryProtocol();
+      ThriftTestClient testClient =
+        new ThriftTestClient(tSocket, binaryProtocol);
+
+      for (int test = 0; test < numTests; ++test) {
+
+        /**
+         * CONNECT TEST
+         */
+        System.out.println("Test #" + (test+1) + ", " +
+                           "connect " + host + ":" + port);
+        try {
+          tSocket.open();
+        } catch (TTransportException ttx) {
+          System.out.println("Connect failed: " + ttx.getMessage());
+          continue;
+        }
+
+        long start = System.currentTimeMillis();
+    
+        /**
+         * VOID TEST
+         */
+        System.out.print("testVoid()");
+        testClient.testVoid();
+        System.out.print(" = void\n");
+
+        /**
+         * STRING TEST
+         */
+        System.out.print("testString(\"Test\")");
+        TString s = testClient.testString(new TString("Test"));
+        System.out.print(" = \"" + s.value + "\"\n");
+   
+        /**
+         * BYTE TEST
+         */
+        System.out.print("testByte(1)");
+        UInt8 u8 = testClient.testByte(new UInt8((short)1));
+        System.out.print(" = " + u8.get() + "\n");
+
+        /**
+         * U32 TEST
+         */
+        System.out.print("testU32(1)");
+        UInt32 u32 = testClient.testU32(new UInt32(1));
+        System.out.print(" = " + u32.get() + "\n");
+    
+        /**
+         * I32 TEST
+         */
+        System.out.print("testI32(-1)");
+        Int32 i32 = testClient.testI32(new Int32(-1));
+        System.out.print(" = " + i32.get() + "\n");
+
+        /**
+         * U64 TEST
+         */
+        System.out.print("testU64(34359738368)");
+        UInt64 u64 = testClient.testU64(new UInt64(34359738368L));
+        System.out.print(" = " + u64.toLong() + "\n");
+
+        /**
+         * I64 TEST
+         */
+        System.out.print("testI64(-34359738368)");
+        Int64 i64 = testClient.testI64(new Int64(-34359738368L));
+        System.out.print(" = " + i64.get() + "\n");
+
+        /**
+         * STRUCT TEST
+         */
+        System.out.print("testStruct({\"Zero\", 1, 2, -3, 4, -5})");
+        Xtruct out = new Xtruct();
+        out.string_thing.value = "Zero";
+        out.byte_thing.set((short)1);
+        out.u32_thing.set(2);
+        out.i32_thing.set(-3);
+        out.u64_thing.set(4);
+        out.i64_thing.set(-5);
+        Xtruct in = testClient.testStruct(out);
+        System.out.print(" = {" +
+                         "\"" + in.string_thing.value + "\", " +
+                         in.byte_thing.get() + ", " +
+                         in.u32_thing.get() + ", " +
+                         in.i32_thing.get() + ", " +
+                         in.u64_thing.toLong() + ", " +
+                         in.i64_thing.get() + "}\n");
+
+        /**
+         * NESTED STRUCT TEST
+         */
+        System.out.print("testNest({1, {\"Zero\", 1, 2, -3, 4, -5}), 5}");
+        Xtruct2 out2 = new Xtruct2();
+        out2.byte_thing.set((short)1);
+        out2.struct_thing = out;
+        out2.i32_thing.set(5);
+        Xtruct2 in2 = testClient.testNest(out2);
+        in = in2.struct_thing;
+        System.out.print(" = {" +
+                         in2.byte_thing.get() + ", {" +
+                         "\"" + in.string_thing.value + "\", " +
+                         in.byte_thing.get() + ", " +
+                         in.u32_thing.get() + ", " +
+                         in.i32_thing.get() + ", " +
+                         in.u64_thing.toLong() + ", " +
+                         in.i64_thing.get() + "}, " +
+                         in2.i32_thing.get() + "}\n");
+
+        /**
+         * MAP TEST
+         */
+        HashMap<Int32,Int32> mapout = new HashMap<Int32,Int32>();
+        for (int i = 0; i < 5; ++i) {
+          mapout.put(new Int32(i), new Int32(i-10));
+        }
+        System.out.print("testMap({");
+        boolean first = true;
+        for (Int32 key : mapout.keySet()) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(key.get() + " => " + mapout.get(key).get());
+        }
+        System.out.print("})");
+        HashMap<Int32,Int32> mapin = testClient.testMap(mapout);
+        System.out.print(" = {");
+        first = true;
+        for (Int32 key : mapin.keySet()) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(key.get() + " => " + mapout.get(key).get());
+        }
+        System.out.print("}\n");
+
+        /**
+         * SET TEST
+         */
+        HashSet<Int32> setout = new HashSet<Int32>();
+        for (int i = -2; i < 3; ++i) {
+          setout.add(new Int32(i));
+        }
+        System.out.print("testSet({");
+        first = true;
+        for (Int32 elem : setout) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(elem.get());
+        }
+        System.out.print("})");
+        HashSet<Int32> setin = testClient.testSet(setout);
+        System.out.print(" = {");
+        first = true;
+        for (Int32 elem : setin) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(elem.get());
+        }
+        System.out.print("}\n");
+
+        /**
+         * LIST TEST
+         */
+        ArrayList<Int32> listout = new ArrayList<Int32>();
+        for (int i = -2; i < 3; ++i) {
+          listout.add(new Int32(i));
+        }
+        System.out.print("testList({");
+        first = true;
+        for (Int32 elem : listout) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(elem.get());
+        }
+        System.out.print("})");
+        ArrayList<Int32> listin = testClient.testList(listout);
+        System.out.print(" = {");
+        first = true;
+        for (Int32 elem : listin) {
+          if (first) {
+            first = false;
+          } else {
+            System.out.print(", ");
+          }
+          System.out.print(elem.get());
+        }
+        System.out.print("}\n");
+
+        /**
+         * ENUM TEST
+         */
+        System.out.print("testEnum(ONE)");
+        Int32 ret = testClient.testEnum(Numberz.ONE);
+        System.out.print(" = " + ret.get() + "\n");
+
+        System.out.print("testEnum(TWO)");
+        ret = testClient.testEnum(Numberz.TWO);
+        System.out.print(" = " + ret.get() + "\n");
+
+        System.out.print("testEnum(THREE)");
+        ret = testClient.testEnum(Numberz.THREE);
+        System.out.print(" = " + ret.get() + "\n");
+
+        System.out.print("testEnum(FIVE)");
+        ret = testClient.testEnum(Numberz.FIVE);
+        System.out.print(" = " + ret.get() + "\n");
+
+        System.out.print("testEnum(EIGHT)");
+        ret = testClient.testEnum(Numberz.EIGHT);
+        System.out.print(" = " + ret.get() + "\n");
+
+        /**
+         * TYPEDEF TEST
+         */
+        System.out.print("testTypedef(309858235082523)");
+        UInt64 uid = testClient.testTypedef(new UInt64(309858235082523L));
+        System.out.print(" = " + uid.toLong() + "\n");
+
+        /**
+         * NESTED MAP TEST
+         */
+        System.out.print("testMapMap(1)");
+        HashMap<Int32,HashMap<Int32,Int32>> mm =
+          testClient.testMapMap(new Int32(1));
+        System.out.print(" = {");
+        for (Int32 key : mm.keySet()) {
+          System.out.print(key.get() + " => {");
+          HashMap<Int32,Int32> m2 = mm.get(key);
+          for (Int32 k2 : m2.keySet()) {
+            System.out.print(k2.get() + " => " + m2.get(k2).get() + ", ");
+          }
+          System.out.print("}, ");
+        }
+        System.out.print("}\n");
+
+        /**
+         * INSANITY TEST
+         */
+        Insanity insane = new Insanity();
+        insane.userMap.put(Numberz.FIVE, new UInt64(5000));
+        Xtruct truck = new Xtruct();
+        truck.string_thing.value = "Truck";
+        truck.byte_thing.set((short)8);
+        truck.u32_thing.set(8);
+        truck.i32_thing.set(8);
+        truck.u64_thing.set(8);
+        truck.i64_thing.set(8);
+        insane.xtructs.add(truck);
+        System.out.print("testInsanity()");
+        HashMap<UInt64,HashMap<Int32,Insanity>> whoa =
+          testClient.testInsanity(insane);
+        System.out.print(" = {");
+        for (UInt64 key : whoa.keySet()) {
+          HashMap<Int32,Insanity> val = whoa.get(key);
+          System.out.print(key.toLong() + " => {");
+
+          for (Int32 k2 : val.keySet()) {
+            Insanity v2 = val.get(k2);
+            System.out.print(k2.get() + " => {");
+            HashMap<Int32, UInt64> userMap = v2.userMap;
+            System.out.print("{");
+            for (Int32 k3 : userMap.keySet()) {
+              System.out.print(k3.get() + " => " +
+                               userMap.get(k3).toLong() + ", ");
+            }
+            System.out.print("}, ");
+
+            ArrayList<Xtruct> xtructs = v2.xtructs;
+            System.out.print("{");
+            for (Xtruct x : xtructs) {
+              System.out.print("{" +
+                               "\"" + x.string_thing.value + "\", " +
+                               x.byte_thing.get() + ", " +
+                               x.u32_thing.get() + ", "+
+                               x.i32_thing.get() + ", "+
+                               x.u64_thing.toLong() + ", "+
+                               x.i64_thing.get() + "}, ");
+            }
+            System.out.print("}");
+
+            System.out.print("}, ");
+          }
+          System.out.print("}, ");
+        }
+        System.out.print("}\n");
+
+        long stop = System.currentTimeMillis();
+        System.out.println("Total time: " + (stop-start) + "ms");
+
+        tSocket.close();
+      }
+      
+    } catch (Exception x) {
+      x.printStackTrace();
+    }
+  }
+}
diff --git a/test/java/src/TestServer.java b/test/java/src/TestServer.java
new file mode 100644
index 0000000..c5edca4
--- /dev/null
+++ b/test/java/src/TestServer.java
@@ -0,0 +1,230 @@
+package com.facebook.thrift.test;
+
+import com.facebook.thrift.types.*;
+import com.facebook.thrift.protocol.TBinaryProtocol;
+import com.facebook.thrift.protocol.TProtocol;
+import com.facebook.thrift.protocol.TString;
+import com.facebook.thrift.server.TServer;
+import com.facebook.thrift.server.TSimpleServer;
+import com.facebook.thrift.transport.TServerSocket;
+import com.facebook.thrift.transport.TServerTransport;
+
+import ThriftTest.*;
+
+import java.net.ServerSocket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class TestServer extends ThriftTestServerIf {
+  public TestServer(TProtocol prot) {
+    super(prot);
+  }
+  
+  public void testVoid() {
+    System.out.print("testVoid()\n");
+  }
+
+  public TString testString(TString thing) {
+    System.out.print("testString(\"" + thing.value + "\")\n");
+    return thing;
+  }
+
+  public UInt8 testByte(UInt8 thing) {
+    System.out.print("testByte(" + thing.get() + ")\n");
+    return thing;
+  }
+
+  public UInt32 testU32(UInt32 thing) {
+    System.out.print("testU32(" + thing.get() + ")\n");
+    return thing;
+  }
+
+  public Int32 testI32(Int32 thing) {
+    System.out.print("testI32(" + thing.get() + ")\n");
+    return thing;
+  }
+
+  public UInt64 testU64(UInt64 thing) {
+    System.out.print("testU64(" + thing.toLong() + ")\n");
+    return thing;
+  }
+
+  public Int64 testI64(Int64 thing) {
+    System.out.print("testI64(" + thing.get() + ")\n");
+    return thing;
+  }
+  
+  public Xtruct testStruct(Xtruct thing) {
+    System.out.print("testStruct({" +
+                     "\"" + thing.string_thing.value + "\", " +
+                     thing.byte_thing.get() + ", " +
+                     thing.u32_thing.get() + ", " +
+                     thing.i32_thing.get() + ", " +
+                     thing.u64_thing.toLong() + ", " +
+                     thing.i64_thing.get() + "})\n");
+    return thing;
+  }
+  
+  public Xtruct2 testNest(Xtruct2 nest) {
+    Xtruct thing = nest.struct_thing;
+    System.out.print("testNest({" +
+                     nest.byte_thing.get() + ", {" +
+                     "\"" + thing.string_thing.value + "\", " +
+                     thing.byte_thing.get() + ", " +
+                     thing.u32_thing.get() + ", " +
+                     thing.i32_thing.get() + ", " +
+                     thing.u64_thing.toLong() + ", " +
+                     thing.i64_thing.get() + "}, " +
+                     nest.i32_thing.get() + "})\n");
+    return nest;
+  }
+  
+  public HashMap<Int32,Int32> testMap(HashMap<Int32,Int32> thing) {
+    System.out.print("testMap({");
+    boolean first = true;
+    for (Int32 key : thing.keySet()) {
+      if (first) {
+        first = false;
+      } else {
+        System.out.print(", ");
+      }
+      System.out.print(key.get() + " => " + thing.get(key).get());
+    }
+    System.out.print("})\n");
+    return thing;
+  }
+
+  public HashSet<Int32> testSet(HashSet<Int32> thing) {
+    System.out.print("testSet({");
+    boolean first = true;
+    for (Int32 elem : thing) {
+      if (first) {
+        first = false;
+      } else {
+        System.out.print(", ");
+      }
+      System.out.print(elem.get());
+    }
+    System.out.print("})\n");
+    return thing;
+  }
+
+  public ArrayList<Int32> testList(ArrayList<Int32> thing) {
+    System.out.print("testList({");
+    boolean first = true;
+    for (Int32 elem : thing) {
+      if (first) {
+        first = false;
+      } else {
+        System.out.print(", ");
+      }
+      System.out.print(elem.get());
+    }
+    System.out.print("})\n");
+    return thing;
+  }
+
+  public Int32 testEnum(Int32 thing) {
+    System.out.print("testEnum(" + thing.get() + ")\n");
+    return thing;
+  }
+
+  public UInt64 testTypedef(UInt64 thing) {
+    System.out.print("testTypedef(" + thing.toLong() + ")\n");
+    return thing;
+  }
+
+  public HashMap<Int32,HashMap<Int32,Int32>> testMapMap(Int32 hello) {
+    System.out.print("testMapMap(" + hello.get() + ")\n");
+    HashMap<Int32,HashMap<Int32,Int32>> mapmap =
+      new HashMap<Int32,HashMap<Int32,Int32>>();
+
+    HashMap<Int32,Int32> pos = new HashMap<Int32,Int32>();
+    HashMap<Int32,Int32> neg = new HashMap<Int32,Int32>();
+    for (int i = 1; i < 5; i++) {
+      pos.put(new Int32(i), new Int32(i));
+      neg.put(new Int32(-i), new Int32(-i));
+    }
+
+    mapmap.put(new Int32(4), pos);
+    mapmap.put(new Int32(-4), neg);
+
+    return mapmap;
+  }
+
+  public HashMap<UInt64, HashMap<Int32,Insanity>> testInsanity(Insanity argument) {
+    System.out.print("testInsanity()\n");
+    
+    Xtruct hello = new Xtruct();
+    hello.string_thing.value = "Hello2";
+    hello.byte_thing.set((short)2);
+    hello.u32_thing.set(2);
+    hello.i32_thing.set(2);
+    hello.u64_thing.set(2);
+    hello.i64_thing.set(2);
+
+    Xtruct goodbye = new Xtruct();
+    goodbye.string_thing.value = "Goodbye4";
+    goodbye.byte_thing.set((short)4);
+    goodbye.u32_thing.set(4);
+    goodbye.i32_thing.set(4);
+    goodbye.u64_thing.set(4);
+    goodbye.i64_thing.set(4);
+
+    Insanity crazy = new Insanity();
+    crazy.userMap.put(Numberz.EIGHT, new UInt64(8));
+    crazy.xtructs.add(goodbye);
+
+    Insanity looney = new Insanity();
+    crazy.userMap.put(Numberz.FIVE, new UInt64(5));
+    crazy.xtructs.add(hello);
+
+    HashMap<Int32,Insanity> first_map = new HashMap<Int32, Insanity>();
+    HashMap<Int32,Insanity> second_map = new HashMap<Int32, Insanity>();;
+
+    first_map.put(Numberz.TWO, crazy);
+    first_map.put(Numberz.THREE, crazy);
+
+    second_map.put(Numberz.SIX, looney);
+
+    HashMap<UInt64,HashMap<Int32,Insanity>> insane =
+      new HashMap<UInt64, HashMap<Int32,Insanity>>();
+    insane.put(new UInt64(1), first_map);
+    insane.put(new UInt64(2), second_map);
+
+    return insane;
+  }
+
+  public static void main(String [] args) {
+    try {
+      int port = 9090;
+      if (args.length > 1) {
+        port = Integer.valueOf(args[0]);
+      }
+      
+      // Processor
+      TBinaryProtocol binaryProtocol = new TBinaryProtocol();
+      TestServer testServer = new TestServer(binaryProtocol);
+
+      // Options
+      TServer.Options serverOptions = new TServer.Options();
+
+      // Transport
+      ServerSocket serverSocket = new ServerSocket(port);
+      TServerSocket tServerSocket = new TServerSocket(serverSocket);
+
+      // Server
+      TSimpleServer simpleServer = new TSimpleServer(testServer,
+                                                     serverOptions,
+                                                     tServerSocket);
+
+      // Run it
+      System.out.println("Starting the server on port " + port + "...");
+      simpleServer.run();
+    } catch (Exception x) {
+      x.printStackTrace();
+    }
+    System.out.println("done.");
+  }
+}