diff --git a/src/csharp/Grpc.Core.Testing/.gitignore b/src/csharp/Grpc.Core.Testing/.gitignore
new file mode 100644
index 00000000000..1746e3269ed
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/.gitignore
@@ -0,0 +1,2 @@
+bin
+obj
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
new file mode 100644
index 00000000000..9b0b3abf107
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
@@ -0,0 +1,68 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {3AB047CA-6CF9-435D-AA61-2D86C6FA2457}
+ Library
+ Properties
+ Grpc.Core.Testing
+ Grpc.Core.Testing
+ v4.5
+ 512
+ bin\$(Configuration)\Grpc.Core.Testing.Xml
+
+
+ true
+ full
+ false
+ bin\Debug\
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+ ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll
+
+
+
+
+ Version.cs
+
+
+
+
+
+
+
+
+
+
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}
+ Grpc.Core
+
+
+
+
+
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json
new file mode 100644
index 00000000000..c2f5bcb1637
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.project.json
@@ -0,0 +1,8 @@
+{
+ "frameworks": {
+ "net45": { }
+ },
+ "runtimes": {
+ "win": { }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj
new file mode 100644
index 00000000000..c9723870033
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.xproj
@@ -0,0 +1,18 @@
+
+
+
+ 14.0.25123
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 2b372155-80ba-4cf9-82d6-4b938e8ec3a0
+ Grpc.Core.Testing
+ ..\artifacts\obj\$(MSBuildProjectName)
+ .\bin\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Testing/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Testing/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..d3ca0c4d0ec
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Core.Testing")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/csharp/Grpc.Core.Testing/Settings.StyleCop b/src/csharp/Grpc.Core.Testing/Settings.StyleCop
new file mode 100644
index 00000000000..2942add9623
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/Settings.StyleCop
@@ -0,0 +1,10 @@
+
+
+ Health.cs
+
+
+ False
+
+
+
+
diff --git a/src/csharp/Grpc.Core.Testing/TestCalls.cs b/src/csharp/Grpc.Core.Testing/TestCalls.cs
new file mode 100644
index 00000000000..d8c36f22f32
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/TestCalls.cs
@@ -0,0 +1,91 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Grpc.Core.Testing
+{
+ ///
+ /// Test doubles for client-side call objects.
+ ///
+ public static class TestCalls
+ {
+ ///
+ /// Creates a test double for AsyncUnaryCall. Only for testing.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ ///
+ public static AsyncUnaryCall AsyncUnaryCall (
+ Task responseAsync, Task responseHeadersAsync, Func getStatusFunc,
+ Func getTrailersFunc, Action disposeAction)
+ {
+ return new AsyncUnaryCall(responseAsync, responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction);
+ }
+
+ ///
+ /// Creates a test double for AsyncClientStreamingCall. Only for testing.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ ///
+ public static AsyncClientStreamingCall AsyncClientStreamingCall(
+ IClientStreamWriter requestStream, Task responseAsync,
+ Task responseHeadersAsync, Func getStatusFunc,
+ Func getTrailersFunc, Action disposeAction)
+ {
+ return new AsyncClientStreamingCall(requestStream, responseAsync, responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction);
+ }
+
+ ///
+ /// Creates a test double for AsyncServerStreamingCall. Only for testing.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ ///
+ public static AsyncServerStreamingCall AsyncServerStreamingCall(
+ IAsyncStreamReader responseStream, Task responseHeadersAsync,
+ Func getStatusFunc, Func getTrailersFunc, Action disposeAction)
+ {
+ return new AsyncServerStreamingCall(responseStream, responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction);
+ }
+
+ ///
+ /// Creates a test double for AsyncDuplexStreamingCall. Only for testing.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ ///
+ public static AsyncDuplexStreamingCall AsyncDuplexStreamingCall(
+ IClientStreamWriter requestStream, IAsyncStreamReader responseStream,
+ Task responseHeadersAsync, Func getStatusFunc,
+ Func getTrailersFunc, Action disposeAction)
+ {
+ return new AsyncDuplexStreamingCall(requestStream, responseStream, responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Testing/packages.config b/src/csharp/Grpc.Core.Testing/packages.config
new file mode 100644
index 00000000000..53cfad52f0b
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Testing/project.json b/src/csharp/Grpc.Core.Testing/project.json
new file mode 100644
index 00000000000..02be9578126
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/project.json
@@ -0,0 +1,39 @@
+{
+ "version": "1.2.0-dev",
+ "title": "gRPC C# Core Testing",
+ "authors": [ "Google Inc." ],
+ "copyright": "Copyright 2017, Google Inc.",
+ "packOptions": {
+ "summary": "Testing support for gRPC C#",
+ "description": "Useful when testing code that uses gRPC.",
+ "owners": [ "grpc-packages" ],
+ "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
+ "projectUrl": "https://github.com/grpc/grpc",
+ "requireLicenseAcceptance": false,
+ "tags": [ "gRPC test testing" ]
+ },
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ }
+ },
+ "dependencies": {
+ "Grpc.Core": "1.2.0-dev"
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ }
+ },
+ "netstandard1.5": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
index 99158fbc8b9..77ac347c7da 100644
--- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
@@ -49,6 +49,11 @@ using System.Runtime.CompilerServices;
"0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
"27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
+[assembly: InternalsVisibleTo("Grpc.Core.Testing,PublicKey=" +
+ "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" +
+ "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
+ "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
+ "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
[assembly: InternalsVisibleTo("Grpc.IntegrationTesting,PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" +
"0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
@@ -56,5 +61,6 @@ using System.Runtime.CompilerServices;
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
#else
[assembly: InternalsVisibleTo("Grpc.Core.Tests")]
+[assembly: InternalsVisibleTo("Grpc.Core.Testing")]
[assembly: InternalsVisibleTo("Grpc.IntegrationTesting")]
#endif
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 179e7313809..84ba46047f7 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -40,6 +40,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection", "Grpc.Ref
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.csproj", "{B88F91D6-436D-4C78-8B99-47800FA8DE03}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Core.Testing", "Grpc.Core.Testing\Grpc.Core.Testing.csproj", "{3AB047CA-6CF9-435D-AA61-2D86C6FA2457}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -110,6 +112,10 @@ Global
{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3AB047CA-6CF9-435D-AA61-2D86C6FA2457}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 3b9306b18ea..b99fdcbdfde 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -59,6 +59,7 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* pr
%DOTNET% restore . || goto :error
%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Core.Testing\project.json --output ..\..\artifacts || goto :error
%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index dcb4fe31046..442e3acad28 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -61,6 +61,7 @@ cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=macos/artifacts/
dotnet restore .
dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
+dotnet pack --configuration Release Grpc.Core.Testing/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
diff --git a/templates/src/csharp/Grpc.Core.Testing/project.json.template b/templates/src/csharp/Grpc.Core.Testing/project.json.template
new file mode 100644
index 00000000000..7aff9911455
--- /dev/null
+++ b/templates/src/csharp/Grpc.Core.Testing/project.json.template
@@ -0,0 +1,41 @@
+%YAML 1.2
+--- |
+ {
+ "version": "${settings.csharp_version}",
+ "title": "gRPC C# Core Testing",
+ "authors": [ "Google Inc." ],
+ "copyright": "Copyright 2017, Google Inc.",
+ "packOptions": {
+ "summary": "Testing support for gRPC C#",
+ "description": "Useful when testing code that uses gRPC.",
+ "owners": [ "grpc-packages" ],
+ "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
+ "projectUrl": "https://github.com/grpc/grpc",
+ "requireLicenseAcceptance": false,
+ "tags": [ "gRPC test testing" ]
+ },
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ }
+ },
+ "dependencies": {
+ "Grpc.Core": "${settings.csharp_version}"
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ }
+ },
+ "netstandard1.5": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ }
+ }
diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template
index 562b7704ab8..2f91d485ec4 100755
--- a/templates/src/csharp/build_packages_dotnetcli.bat.template
+++ b/templates/src/csharp/build_packages_dotnetcli.bat.template
@@ -61,6 +61,7 @@
%%DOTNET% restore . || goto :error
%%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
+ %%DOTNET% pack --configuration Release Grpc.Core.Testing\project.json --output ..\..\artifacts || goto :error
%%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
%%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
%%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
diff --git a/templates/src/csharp/build_packages_dotnetcli.sh.template b/templates/src/csharp/build_packages_dotnetcli.sh.template
index 91c6fb6928b..c5364377b99 100755
--- a/templates/src/csharp/build_packages_dotnetcli.sh.template
+++ b/templates/src/csharp/build_packages_dotnetcli.sh.template
@@ -63,6 +63,7 @@
dotnet restore .
dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
+ dotnet pack --configuration Release Grpc.Core.Testing/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts