THRIFT-3906 Run C# tests with make check

This closes #1069
diff --git a/configure.ac b/configure.ac
index c72dd43..fb22699 100755
--- a/configure.ac
+++ b/configure.ac
@@ -721,7 +721,7 @@
   lib/c_glib/thrift_c_glib.pc
   lib/c_glib/test/Makefile
   lib/csharp/Makefile
-  lib/csharp/test/ThriftTest/Makefile
+  lib/csharp/test/Multiplex/Makefile
   lib/d/Makefile
   lib/d/test/Makefile
   lib/erl/Makefile
@@ -749,6 +749,7 @@
   test/features/Makefile
   test/c_glib/Makefile
   test/cpp/Makefile
+  test/csharp/Makefile
   test/erl/Makefile
   test/go/Makefile
   test/haxe/Makefile
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d8d9b47..f12e092 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -30,7 +30,6 @@
 
 if WITH_MONO
 SUBDIRS += csharp
-PRECROSS_TARGET += precross-csharp
 endif
 
 if WITH_JAVA
diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am
index 824a872..bf02c87 100644
--- a/lib/csharp/Makefile.am
+++ b/lib/csharp/Makefile.am
@@ -17,9 +17,9 @@
 # under the License.
 #
 
-SUBDIRS = . test/ThriftTest
+SUBDIRS = . test/Multiplex
 
-THRIFTCODE= \
+THRIFTCODE = \
             src/Collections/THashSet.cs \
             src/Collections/TCollections.cs \
             src/Properties/AssemblyInfo.cs \
@@ -74,31 +74,23 @@
             src/TApplicationException.cs
 
 if MONO_MCS
-CSC=mcs
+export CSC = mcs
 else
-CSC=gmcs
+export CSC = gmcs
 endif
 
 if NET_2_0
-MONO_DEFINES=/d:NET_2_0
+export CSC_DEFINES = -d:NET_2_0
 endif
 
 all-local: Thrift.dll
 
 Thrift.dll: $(THRIFTCODE)
-	$(CSC) $(THRIFTCODE) /out:Thrift.dll /target:library /reference:System.Web $(MONO_DEFINES)
+	$(CSC) $(CSC_DEFINES) -out:$@ -target:library -reference:System.Web $(THRIFTCODE)
 
 clean-local:
 	$(RM) Thrift.dll
 
-precross: all-local
-	$(MAKE) -C test/ThriftTest precross
-
-# run csharp tests?
-# check:
-# 	cd test/ThriftTest && ./maketest.sh
-# 	cd test/Multiplex && ./maketest.sh
-
 EXTRA_DIST = \
              $(THRIFTCODE) \
              ThriftMSBuildTask \
diff --git a/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs b/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
index ccfe21d..c810a08 100644
--- a/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
+++ b/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
@@ -26,17 +26,16 @@
 using Thrift;
 using Test.Multiplex;
 
-
 namespace Test.Multiplex.Client
 {
     public class TestClient
     {
-        private void Run()
+        static void Execute(int port)
         {
             try
             {
                 TTransport trans;
-                trans = new TSocket("localhost", 9090);
+                trans = new TSocket("localhost", port);
                 trans = new TFramedTransport(trans);
                 trans.Open();
 
@@ -44,44 +43,40 @@
 
                 TMultiplexedProtocol multiplex;
 
-                multiplex = new TMultiplexedProtocol( Protocol, Constants.NAME_BENCHMARKSERVICE);
-                BenchmarkService.Iface bench = new BenchmarkService.Client( multiplex);
+                multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_BENCHMARKSERVICE);
+                BenchmarkService.Iface bench = new BenchmarkService.Client(multiplex);
 
-                multiplex = new TMultiplexedProtocol( Protocol, Constants.NAME_AGGR);
-                Aggr.Iface aggr = new Aggr.Client( multiplex);
+                multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_AGGR);
+                Aggr.Iface aggr = new Aggr.Client(multiplex);
 
-                sbyte i;
-                for( i = 1; 10 >= i; ++i)
+                for (sbyte i = 1; 10 >= i; ++i)
                 {
-                    aggr.addValue( bench.fibonacci(i));
+                    aggr.addValue(bench.fibonacci(i));
                 }
 
-                foreach( int k in aggr.getValues())
+                foreach (int k in aggr.getValues())
                 {
-                    Console.Write(k.ToString()+" ");
+                    Console.Write(k.ToString() + " ");
                     Console.WriteLine("");
                 }
+                trans.Close();
             }
-            catch( Exception e)
+            catch (Exception e)
             {
-                Console.WriteLine( e.Message);
+                Console.WriteLine(e.Message);
             }
         }
 
-
-        public static void Execute()
-        {
-            TestClient client = new TestClient();
-            client.Run();
-        }
-
         static void Main(string[] args)
         {
-            Execute();
+            int port = 9090;
+            if (args.Length > 0)
+            {
+                port = ushort.Parse(args[0]);
+            }
+            Execute(port);
             Console.WriteLine("done.");
-            Console.ReadLine();
         }
-
     }
 }
 
diff --git a/lib/csharp/test/Multiplex/Makefile.am b/lib/csharp/test/Multiplex/Makefile.am
new file mode 100644
index 0000000..57253d6
--- /dev/null
+++ b/lib/csharp/test/Multiplex/Makefile.am
@@ -0,0 +1,52 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+GENERATED = \
+	gen-csharp/Aggr.cs \
+	gen-csharp/BenchmarkService.cs \
+	gen-csharp/Error.cs
+
+BUILT_SOURCES = $(GENERATED)
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+gen-csharp/Aggr.cs: $(top_srcdir)/contrib/async-test/aggr.thrift
+	$(THRIFT) --gen csharp $<
+
+gen-csharp/BenchmarkService.cs gen-csharp/Error.cs: $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift
+	$(THRIFT) --gen csharp $<
+
+ThriftImpl.dll: Multiplex.Test.Common.cs $(GENERATED) ../../Thrift.dll
+	$(CSC) $(CSC_DEFINES) -t:library -out:./ThriftImpl.dll -reference:../../Thrift.dll $(GENERATED) $<
+
+MultiplexClient.exe: Client/Multiplex.Test.Client.cs ThriftImpl.dll
+	$(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+MultiplexServer.exe: Server/Multiplex.Test.Server.cs ThriftImpl.dll
+	$(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+clean-local:
+	$(RM) -rf gen-csharp *.exe *.dll
+
+TESTPORT = 9501
+check-local: MultiplexServer.exe MultiplexClient.exe
+	echo $(TESTPORT)
+	MONO_PATH=../../ timeout 10 mono MultiplexServer.exe $(TESTPORT) &
+	sleep 1
+	MONO_PATH=../../ mono MultiplexClient.exe $(TESTPORT)
diff --git a/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs b/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
index 61c2d7c..9786189 100644
--- a/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
+++ b/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
@@ -30,30 +30,14 @@
 {
     public class TestServer
     {
-        public interface ITestHandler
-        {
-            void SetServer( TServer aServer);
-        }
-
-        protected class TestHandlerImpl : ITestHandler
-        {
-            private TServer Server;
-
-            public void SetServer( TServer aServer)
-            {
-                Server = aServer;
-            }
-        }
-
-
-        protected class BenchmarkServiceImpl : TestHandlerImpl, BenchmarkService.Iface
+        class BenchmarkServiceImpl : BenchmarkService.Iface
         {
             public int fibonacci(sbyte n)
             {
                 int prev, next, result;
                 prev   = 0;
                 result = 1;
-                while( n > 0)
+                while (n > 0)
                 {
                     next   = result + prev;
                     prev   = result;
@@ -64,14 +48,13 @@
             }
         }
 
-
-        protected class AggrServiceImpl : TestHandlerImpl,  Aggr.Iface
+        class AggrServiceImpl : Aggr.Iface
         {
             List<int> values = new List<int>();
 
             public void addValue(int value)
             {
-                values.Add( value);
+                values.Add(value);
             }
 
             public List<int> getValues()
@@ -80,52 +63,45 @@
             }
         }
 
-       static void Execute()
-       {
-           try
-           {
-               // create protocol factory, default to BinaryProtocol
-               TProtocolFactory ProtocolFactory = new TBinaryProtocol.Factory(true,true);
-               TServerTransport servertrans     = new TServerSocket( 9090, 0, false);
-               TTransportFactory TransportFactory = new TFramedTransport.Factory();
+        static void Execute(int port)
+        {
+            try
+            {
+                // create protocol factory, default to BinaryProtocol
+                TProtocolFactory ProtocolFactory = new TBinaryProtocol.Factory(true,true);
+                TServerTransport servertrans = new TServerSocket(port, 0, false);
+                TTransportFactory TransportFactory = new TFramedTransport.Factory();
 
-               BenchmarkService.Iface benchHandler = new BenchmarkServiceImpl();
-               TProcessor benchProcessor = new BenchmarkService.Processor( benchHandler);
+                BenchmarkService.Iface benchHandler = new BenchmarkServiceImpl();
+                TProcessor benchProcessor = new BenchmarkService.Processor(benchHandler);
 
-               Aggr.Iface aggrHandler = new AggrServiceImpl();
-               TProcessor aggrProcessor = new Aggr.Processor( aggrHandler);
+                Aggr.Iface aggrHandler = new AggrServiceImpl();
+                TProcessor aggrProcessor = new Aggr.Processor(aggrHandler);
 
-               TMultiplexedProcessor multiplex = new TMultiplexedProcessor();
-               multiplex.RegisterProcessor(Constants.NAME_BENCHMARKSERVICE, benchProcessor);
-               multiplex.RegisterProcessor(Constants.NAME_AGGR, aggrProcessor);
+                TMultiplexedProcessor multiplex = new TMultiplexedProcessor();
+                multiplex.RegisterProcessor(Constants.NAME_BENCHMARKSERVICE, benchProcessor);
+                multiplex.RegisterProcessor(Constants.NAME_AGGR, aggrProcessor);
 
-               TServer ServerEngine = new TSimpleServer( multiplex, servertrans, TransportFactory, ProtocolFactory);
+                TServer ServerEngine = new TSimpleServer(multiplex, servertrans, TransportFactory, ProtocolFactory);
 
-               (benchHandler as ITestHandler).SetServer( ServerEngine);
-               (aggrHandler as ITestHandler).SetServer( ServerEngine);
+                Console.WriteLine("Starting the server ...");
+                ServerEngine.Serve();
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+            }
+        }
 
-               Console.WriteLine("Starting the server ...");
-               ServerEngine.Serve();
-
-               (benchHandler as ITestHandler).SetServer(null);
-               (aggrHandler as ITestHandler).SetServer(null);
-
-           }
-           catch( Exception e)
-           {
-               Console.WriteLine( e.Message);
-           }
-           Console.WriteLine( "done.");
-       }
-
-
-       static void Main(string[] args)
-       {
-           Execute();
-       }
+        static void Main(string[] args)
+        {
+            int port = 9090;
+            if (args.Length > 0)
+            {
+                port = ushort.Parse(args[0]);
+            }
+            Execute(port);
+        }
     }
-
-
-
 }
 
diff --git a/lib/csharp/test/Multiplex/maketest.sh b/lib/csharp/test/Multiplex/maketest.sh
deleted file mode 100755
index 1f29ee2..0000000
--- a/lib/csharp/test/Multiplex/maketest.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-../../../../compiler/cpp/thrift --gen csharp  ../../../../contrib/async-test/aggr.thrift
-../../../../compiler/cpp/thrift --gen csharp  ../../../rb/benchmark/Benchmark.thrift
-gmcs /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/* /reference:../../Thrift.dll Multiplex.Test.Common.cs
-gmcs  /out:MultiplexClient.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll Client/Multiplex.Test.Client.cs
-gmcs  /out:MultiplexServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll Server/Multiplex.Test.Server.cs
-
-
-
-export MONO_PATH=../../
-
-timeout 120 ./MultiplexServer.exe &
-sleep 3;
-./MultiplexClient.exe
diff --git a/lib/csharp/test/ThriftTest/Makefile.am b/lib/csharp/test/ThriftTest/Makefile.am
deleted file mode 100644
index c0014e6..0000000
--- a/lib/csharp/test/ThriftTest/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-THRIFT = $(top_builddir)/compiler/cpp/thrift
-if MONO_MCS
-CSC=mcs
-else
-CSC=gmcs
-endif
-
-stubs: $(top_srcdir)/test/ThriftTest.thrift
-	$(THRIFT) --gen csharp -o . $(top_srcdir)/test/ThriftTest.thrift
-
-precross: TestClientServer.exe
-
-ThriftImpl.dll: stubs
-	$(CSC) /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/Thrift/Test/*.cs /reference:../../Thrift.dll
-
-TestClientServer.exe: TestClient.cs TestServer.cs Program.cs ThriftImpl.dll
-	$(CSC)  /out:TestClientServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll TestClient.cs TestServer.cs Program.cs
diff --git a/lib/csharp/test/ThriftTest/maketest.sh b/lib/csharp/test/ThriftTest/maketest.sh
deleted file mode 100755
index 210a523..0000000
--- a/lib/csharp/test/ThriftTest/maketest.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-../../../../compiler/cpp/thrift --gen csharp -o . ../../../../test/ThriftTest.thrift
-gmcs /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/* /reference:../../Thrift.dll
-gmcs  /out:TestClientServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll TestClient.cs TestServer.cs Program.cs
-
-export MONO_PATH=../../
-
-timeout 120 ./TestClientServer.exe server &
-sleep 1
-./TestClientServer.exe client
diff --git a/test/Makefile.am b/test/Makefile.am
index 1d52c59..fb39a12 100755
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -25,6 +25,11 @@
 PRECROSS_TARGET += precross-c_glib
 endif
 
+if WITH_MONO
+SUBDIRS += csharp
+PRECROSS_TARGET += precross-csharp
+endif
+
 if WITH_CPP
 SUBDIRS += cpp
 PRECROSS_TARGET += precross-cpp
diff --git a/test/csharp/Makefile.am b/test/csharp/Makefile.am
new file mode 100644
index 0000000..7aa332c
--- /dev/null
+++ b/test/csharp/Makefile.am
@@ -0,0 +1,87 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+GENERATED = \
+	gen-csharp/Thrift/Test/Bonk.cs \
+	gen-csharp/Thrift/Test/Bools.cs \
+	gen-csharp/Thrift/Test/BoolTest.cs \
+	gen-csharp/Thrift/Test/CrazyNesting.cs \
+	gen-csharp/Thrift/Test/EmptyStruct.cs \
+	gen-csharp/Thrift/Test/GuessProtocolStruct.cs \
+	gen-csharp/Thrift/Test/Insanity.cs \
+	gen-csharp/Thrift/Test/LargeDeltas.cs \
+	gen-csharp/Thrift/Test/ListBonks.cs \
+	gen-csharp/Thrift/Test/ListTypeVersioningV1.cs \
+	gen-csharp/Thrift/Test/ListTypeVersioningV2.cs \
+	gen-csharp/Thrift/Test/NestedListsBonk.cs \
+	gen-csharp/Thrift/Test/NestedListsI32x2.cs \
+	gen-csharp/Thrift/Test/NestedListsI32x3.cs \
+	gen-csharp/Thrift/Test/NestedMixedx2.cs \
+	gen-csharp/Thrift/Test/Numberz.cs \
+	gen-csharp/Thrift/Test/OneField.cs \
+	gen-csharp/Thrift/Test/SecondService.cs \
+	gen-csharp/Thrift/Test/StructA.cs \
+	gen-csharp/Thrift/Test/StructB.cs \
+	gen-csharp/Thrift/Test/ThriftTest.Constants.cs \
+	gen-csharp/Thrift/Test/ThriftTest.cs \
+	gen-csharp/Thrift/Test/VersioningTestV1.cs \
+	gen-csharp/Thrift/Test/VersioningTestV2.cs \
+	gen-csharp/Thrift/Test/Xception.cs \
+	gen-csharp/Thrift/Test/Xception2.cs \
+	gen-csharp/Thrift/Test/Xtruct.cs \
+	gen-csharp/Thrift/Test/Xtruct2.cs \
+	gen-csharp/Thrift/Test/Xtruct3.cs
+
+BUILT_SOURCES = $(GENERATED)
+
+if MONO_MCS
+CSC = mcs
+else
+CSC = gmcs
+endif
+
+if NET_2_0
+CSC_DEFINES = -d:NET_2_0
+endif
+
+LIBDIR = $(top_builddir)/lib/csharp
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+$(GENERATED): $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
+	$(THRIFT) --gen csharp -o . $<
+
+precross: TestClientServer.exe
+
+ThriftImpl.dll: $(GENERATED) $(LIBDIR)/Thrift.dll
+	$(CSC) $(CSC_DEFINES) -t:library -out:$@ -reference:$(LIBDIR)/Thrift.dll $(GENERATED)
+
+SRCS = TestClient.cs TestServer.cs Program.cs
+
+TestClientServer.exe: $(SRCS) ThriftImpl.dll
+	$(CSC) $(CSC_DEFINES) -out:$@ -reference:$(LIBDIR)/Thrift.dll -reference:ThriftImpl.dll $(SRCS)
+
+clean-local:
+	$(RM) -rf gen-csharp *.exe *.dll
+
+TESTPORT = 9500
+check-local: TestClientServer.exe
+	MONO_PATH=$(LIBDIR) timeout 10 mono TestClientServer.exe server --port=$(TESTPORT) &
+	sleep 1
+	MONO_PATH=$(LIBDIR) mono TestClientServer.exe client --port=$(TESTPORT)
diff --git a/lib/csharp/test/ThriftTest/Program.cs b/test/csharp/Program.cs
similarity index 100%
rename from lib/csharp/test/ThriftTest/Program.cs
rename to test/csharp/Program.cs
diff --git a/lib/csharp/test/ThriftTest/Properties/AssemblyInfo.cs b/test/csharp/Properties/AssemblyInfo.cs
similarity index 100%
rename from lib/csharp/test/ThriftTest/Properties/AssemblyInfo.cs
rename to test/csharp/Properties/AssemblyInfo.cs
diff --git a/lib/csharp/test/ThriftTest/TestClient.cs b/test/csharp/TestClient.cs
similarity index 98%
rename from lib/csharp/test/ThriftTest/TestClient.cs
rename to test/csharp/TestClient.cs
index cb73597..67673ec 100644
--- a/lib/csharp/test/ThriftTest/TestClient.cs
+++ b/test/csharp/TestClient.cs
@@ -59,7 +59,7 @@
                     {
                         if (encrypted)
                         {
-                            string certPath = "../../../../test/keys/client.p12";
+                            string certPath = "../keys/client.p12";
                             X509Certificate cert = new X509Certificate2(certPath, "thrift");
                             trans = new TTLSSocket(host, port, 0, cert, (o, c, chain, errors) => true, null, SslProtocols.Tls);
                         }
@@ -823,10 +823,13 @@
             }
 
             Console.Write("Test Calltime()");
-            var startt = DateTime.UtcNow;
-            for ( int k=0; k<1000; ++k )
+            var times = 50;
+            sw.Reset();
+            sw.Start();
+            for (int k = 0; k < times; ++k)
                 client.testVoid();
-            Console.WriteLine(" = " + (DateTime.UtcNow - startt).TotalSeconds.ToString() + " ms a testVoid() call" );
+            sw.Stop();
+            Console.WriteLine(" = {0} ms a testVoid() call", sw.ElapsedMilliseconds / times);
             return returnCode;
         }
     }
diff --git a/lib/csharp/test/ThriftTest/TestServer.cs b/test/csharp/TestServer.cs
similarity index 99%
rename from lib/csharp/test/ThriftTest/TestServer.cs
rename to test/csharp/TestServer.cs
index e51ae92..a9af715 100644
--- a/lib/csharp/test/ThriftTest/TestServer.cs
+++ b/test/csharp/TestServer.cs
@@ -468,7 +468,7 @@
                 {
                     if (useEncryption)
                     {
-                        string certPath = "../../../../test/keys/server.p12";
+                        string certPath = "../keys/server.p12";
                         trans = new TTLSServerSocket(port, 0, useBufferedSockets, new X509Certificate2(certPath, "thrift"), null, null, SslProtocols.Tls);
                     }
                     else
diff --git a/lib/csharp/test/ThriftTest/ThriftTest.csproj b/test/csharp/ThriftTest.csproj
similarity index 94%
rename from lib/csharp/test/ThriftTest/ThriftTest.csproj
rename to test/csharp/ThriftTest.csproj
index d671997..65c0daf 100644
--- a/lib/csharp/test/ThriftTest/ThriftTest.csproj
+++ b/test/csharp/ThriftTest.csproj
@@ -115,7 +115,7 @@
     </BootstrapperPackage>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\src\Thrift.csproj">
+    <ProjectReference Include="..\..\lib\csharp\Thrift.csproj">
       <Project>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</Project>
       <Name>Thrift</Name>
     </ProjectReference>
@@ -132,10 +132,10 @@
     <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
 del /f /q "$(ProjectDir)ThriftImpl.dll"
 SET OUTPUT_DIR=$(ProjectDir)
-SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\test\ThriftTest.thrift
+SET THRIFT_FILE=$(ProjectDir)\..\ThriftTest.thrift
 for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
 for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
-"$(ProjectDir)\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
-$(MSBuildToolsPath)\Csc.exe /t:library /out:"$(ProjectDir)ThriftImpl.dll" /recurse:"$(ProjectDir)gen-csharp"\* /reference:"$(ProjectDir)..\..\src\bin\Debug\Thrift.dll"</PreBuildEvent>
+"$(ProjectDir)\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+$(MSBuildToolsPath)\Csc.exe /t:library /out:"$(ProjectDir)ThriftImpl.dll" /recurse:"$(ProjectDir)gen-csharp"\* /reference:"$(ProjectDir)..\..\lib\csharp\bin\Debug\Thrift.dll"</PreBuildEvent>
   </PropertyGroup>
 </Project>
\ No newline at end of file
diff --git a/test/csharp/ThriftTest.sln b/test/csharp/ThriftTest.sln
new file mode 100644
index 0000000..1765a03
--- /dev/null
+++ b/test/csharp/ThriftTest.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftTest", "ThriftTest.csproj", "{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/test/tests.json b/test/tests.json
index 3938c57..0dbc8bf 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -331,7 +331,7 @@
   {
     "name": "csharp",
     "env": {
-      "MONO_PATH": "../.."
+      "MONO_PATH": "../../lib/csharp/"
     },
     "transports": [
       "buffered",
@@ -361,7 +361,7 @@
         "client"
       ]
     },
-    "workdir": "../lib/csharp/test/ThriftTest"
+    "workdir": "csharp"
   },
   {
     "name": "perl",