Skip to content
Snippets Groups Projects
Commit b26972fa authored by Jan Tattermusch's avatar Jan Tattermusch
Browse files

update the interop tests based on spec

parent 1beb0205
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath> <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference> </Reference>
<Reference Include="CommandLine">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
</Reference>
<Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL"> <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath> <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
......
...@@ -37,6 +37,7 @@ using System.Text.RegularExpressions; ...@@ -37,6 +37,7 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommandLine;
using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2;
using Google.Protobuf; using Google.Protobuf;
using Grpc.Auth; using Grpc.Auth;
...@@ -44,25 +45,54 @@ using Grpc.Core; ...@@ -44,25 +45,54 @@ using Grpc.Core;
using Grpc.Core.Utils; using Grpc.Core.Utils;
using Grpc.Testing; using Grpc.Testing;
using NUnit.Framework; using NUnit.Framework;
using CommandLine.Text;
using System.IO;
namespace Grpc.IntegrationTesting namespace Grpc.IntegrationTesting
{ {
public class InteropClient public class InteropClient
{ {
private const string ServiceAccountUser = "155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk@developer.gserviceaccount.com";
private const string ComputeEngineUser = "155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com";
private const string AuthScope = "https://www.googleapis.com/auth/xapi.zoo";
private const string AuthScopeResponse = "xapi.zoo";
private class ClientOptions private class ClientOptions
{ {
public bool help; [Option("server_host", DefaultValue = "127.0.0.1")]
public string serverHost = "127.0.0.1"; public string ServerHost { get; set; }
public string serverHostOverride = TestCredentials.DefaultHostOverride;
public int? serverPort; [Option("server_host_override", DefaultValue = TestCredentials.DefaultHostOverride)]
public string testCase = "large_unary"; public string ServerHostOverride { get; set; }
public bool useTls;
public bool useTestCa; [Option("server_port", Required = true)]
public int ServerPort { get; set; }
[Option("test_case", DefaultValue = "large_unary")]
public string TestCase { get; set; }
[Option("use_tls")]
public bool UseTls { get; set; }
[Option("use_test_ca")]
public bool UseTestCa { get; set; }
[Option("default_service_account", Required = false)]
public string DefaultServiceAccount { get; set; }
[Option("oauth_scope", Required = false)]
public string OAuthScope { get; set; }
[Option("service_account_key_file", Required = false)]
public string ServiceAccountKeyFile { get; set; }
[HelpOption]
public string GetUsage()
{
var help = new HelpText
{
Heading = "gRPC C# interop testing client",
AddDashesToOption = true
};
help.AddPreOptionsLine("Usage:");
help.AddOptions(this);
return help;
}
} }
ClientOptions options; ClientOptions options;
...@@ -74,26 +104,9 @@ namespace Grpc.IntegrationTesting ...@@ -74,26 +104,9 @@ namespace Grpc.IntegrationTesting
public static void Run(string[] args) public static void Run(string[] args)
{ {
Console.WriteLine("gRPC C# interop testing client"); var options = new ClientOptions();
ClientOptions options = ParseArguments(args); if (!Parser.Default.ParseArguments(args, options))
if (options.serverHost == null || !options.serverPort.HasValue || options.testCase == null)
{
Console.WriteLine("Missing required argument.");
Console.WriteLine();
options.help = true;
}
if (options.help)
{ {
Console.WriteLine("Usage:");
Console.WriteLine(" --server_host=HOSTNAME");
Console.WriteLine(" --server_host_override=HOSTNAME");
Console.WriteLine(" --server_port=PORT");
Console.WriteLine(" --test_case=TESTCASE");
Console.WriteLine(" --use_tls=BOOLEAN");
Console.WriteLine(" --use_test_ca=BOOLEAN");
Console.WriteLine();
Environment.Exit(1); Environment.Exit(1);
} }
...@@ -103,30 +116,27 @@ namespace Grpc.IntegrationTesting ...@@ -103,30 +116,27 @@ namespace Grpc.IntegrationTesting
private async Task Run() private async Task Run()
{ {
Credentials credentials = null; var credentials = options.UseTls ? TestCredentials.CreateTestClientCredentials(options.UseTestCa) : Credentials.Insecure;
if (options.useTls)
{
credentials = TestCredentials.CreateTestClientCredentials(options.useTestCa);
}
List<ChannelOption> channelOptions = null; List<ChannelOption> channelOptions = null;
if (!string.IsNullOrEmpty(options.serverHostOverride)) if (!string.IsNullOrEmpty(options.ServerHostOverride))
{ {
channelOptions = new List<ChannelOption> channelOptions = new List<ChannelOption>
{ {
new ChannelOption(ChannelOptions.SslTargetNameOverride, options.serverHostOverride) new ChannelOption(ChannelOptions.SslTargetNameOverride, options.ServerHostOverride)
}; };
} }
Console.WriteLine(options.ServerHost);
var channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelOptions); Console.WriteLine(options.ServerPort);
var channel = new Channel(options.ServerHost, options.ServerPort, credentials, channelOptions);
TestService.TestServiceClient client = new TestService.TestServiceClient(channel); TestService.TestServiceClient client = new TestService.TestServiceClient(channel);
await RunTestCaseAsync(options.testCase, client); await RunTestCaseAsync(client, options);
channel.ShutdownAsync().Wait(); channel.ShutdownAsync().Wait();
} }
private async Task RunTestCaseAsync(string testCase, TestService.TestServiceClient client) private async Task RunTestCaseAsync(TestService.TestServiceClient client, ClientOptions options)
{ {
switch (testCase) switch (options.TestCase)
{ {
case "empty_unary": case "empty_unary":
RunEmptyUnary(client); RunEmptyUnary(client);
...@@ -146,20 +156,17 @@ namespace Grpc.IntegrationTesting ...@@ -146,20 +156,17 @@ namespace Grpc.IntegrationTesting
case "empty_stream": case "empty_stream":
await RunEmptyStreamAsync(client); await RunEmptyStreamAsync(client);
break; break;
case "service_account_creds":
await RunServiceAccountCredsAsync(client);
break;
case "compute_engine_creds": case "compute_engine_creds":
await RunComputeEngineCredsAsync(client); await RunComputeEngineCredsAsync(client, options.DefaultServiceAccount, options.OAuthScope);
break; break;
case "jwt_token_creds": case "jwt_token_creds":
await RunJwtTokenCredsAsync(client); await RunJwtTokenCredsAsync(client, options.DefaultServiceAccount);
break; break;
case "oauth2_auth_token": case "oauth2_auth_token":
await RunOAuth2AuthTokenAsync(client); await RunOAuth2AuthTokenAsync(client, options.DefaultServiceAccount, options.OAuthScope);
break; break;
case "per_rpc_creds": case "per_rpc_creds":
await RunPerRpcCredsAsync(client); await RunPerRpcCredsAsync(client, options.DefaultServiceAccount);
break; break;
case "cancel_after_begin": case "cancel_after_begin":
await RunCancelAfterBeginAsync(client); await RunCancelAfterBeginAsync(client);
...@@ -174,7 +181,7 @@ namespace Grpc.IntegrationTesting ...@@ -174,7 +181,7 @@ namespace Grpc.IntegrationTesting
RunBenchmarkEmptyUnary(client); RunBenchmarkEmptyUnary(client);
break; break;
default: default:
throw new ArgumentException("Unknown test case " + testCase); throw new ArgumentException("Unknown test case " + options.TestCase);
} }
} }
...@@ -313,32 +320,7 @@ namespace Grpc.IntegrationTesting ...@@ -313,32 +320,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!"); Console.WriteLine("Passed!");
} }
public static async Task RunServiceAccountCredsAsync(TestService.TestServiceClient client) public static async Task RunComputeEngineCredsAsync(TestService.TestServiceClient client, string defaultServiceAccount, string oauthScope)
{
Console.WriteLine("running service_account_creds");
var credential = await GoogleCredential.GetApplicationDefaultAsync();
credential = credential.CreateScoped(new[] { AuthScope });
client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
var request = new SimpleRequest
{
ResponseType = PayloadType.COMPRESSABLE,
ResponseSize = 314159,
Payload = CreateZerosPayload(271828),
FillUsername = true,
FillOauthScope = true
};
var response = client.UnaryCall(request);
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
Assert.AreEqual(314159, response.Payload.Body.Length);
Assert.AreEqual(AuthScopeResponse, response.OauthScope);
Assert.AreEqual(ServiceAccountUser, response.Username);
Console.WriteLine("Passed!");
}
public static async Task RunComputeEngineCredsAsync(TestService.TestServiceClient client)
{ {
Console.WriteLine("running compute_engine_creds"); Console.WriteLine("running compute_engine_creds");
var credential = await GoogleCredential.GetApplicationDefaultAsync(); var credential = await GoogleCredential.GetApplicationDefaultAsync();
...@@ -358,16 +340,16 @@ namespace Grpc.IntegrationTesting ...@@ -358,16 +340,16 @@ namespace Grpc.IntegrationTesting
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
Assert.AreEqual(314159, response.Payload.Body.Length); Assert.AreEqual(314159, response.Payload.Body.Length);
Assert.AreEqual(AuthScopeResponse, response.OauthScope); Assert.False(string.IsNullOrEmpty(response.OauthScope));
Assert.AreEqual(ComputeEngineUser, response.Username); Assert.True(oauthScope.Contains(response.OauthScope));
Assert.AreEqual(defaultServiceAccount, response.Username);
Console.WriteLine("Passed!"); Console.WriteLine("Passed!");
} }
public static async Task RunJwtTokenCredsAsync(TestService.TestServiceClient client) public static async Task RunJwtTokenCredsAsync(TestService.TestServiceClient client, string defaultServiceAccount)
{ {
Console.WriteLine("running jwt_token_creds"); Console.WriteLine("running jwt_token_creds");
var credential = await GoogleCredential.GetApplicationDefaultAsync(); var credential = await GoogleCredential.GetApplicationDefaultAsync();
// check this a credential with scope support, but don't add the scope.
Assert.IsTrue(credential.IsCreateScopedRequired); Assert.IsTrue(credential.IsCreateScopedRequired);
client.HeaderInterceptor = AuthInterceptors.FromCredential(credential); client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
...@@ -377,21 +359,20 @@ namespace Grpc.IntegrationTesting ...@@ -377,21 +359,20 @@ namespace Grpc.IntegrationTesting
ResponseSize = 314159, ResponseSize = 314159,
Payload = CreateZerosPayload(271828), Payload = CreateZerosPayload(271828),
FillUsername = true, FillUsername = true,
FillOauthScope = true
}; };
var response = client.UnaryCall(request); var response = client.UnaryCall(request);
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
Assert.AreEqual(314159, response.Payload.Body.Length); Assert.AreEqual(314159, response.Payload.Body.Length);
Assert.AreEqual(ServiceAccountUser, response.Username); Assert.AreEqual(defaultServiceAccount, response.Username);
Console.WriteLine("Passed!"); Console.WriteLine("Passed!");
} }
public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client) public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string defaultServiceAccount, string oauthScope)
{ {
Console.WriteLine("running oauth2_auth_token"); Console.WriteLine("running oauth2_auth_token");
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope }); ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
string oauth2Token = await credential.GetAccessTokenForRequestAsync(); string oauth2Token = await credential.GetAccessTokenForRequestAsync();
client.HeaderInterceptor = AuthInterceptors.FromAccessToken(oauth2Token); client.HeaderInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
...@@ -404,31 +385,30 @@ namespace Grpc.IntegrationTesting ...@@ -404,31 +385,30 @@ namespace Grpc.IntegrationTesting
var response = client.UnaryCall(request); var response = client.UnaryCall(request);
Assert.AreEqual(AuthScopeResponse, response.OauthScope); Assert.False(string.IsNullOrEmpty(response.OauthScope));
Assert.AreEqual(ServiceAccountUser, response.Username); Assert.True(oauthScope.Contains(response.OauthScope));
Assert.AreEqual(defaultServiceAccount, response.Username);
Console.WriteLine("Passed!"); Console.WriteLine("Passed!");
} }
public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client) public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string defaultServiceAccount)
{ {
Console.WriteLine("running per_rpc_creds"); Console.WriteLine("running per_rpc_creds");
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope }); ITokenAccess credential = await GoogleCredential.GetApplicationDefaultAsync();
string oauth2Token = await credential.GetAccessTokenForRequestAsync(); string accessToken = await credential.GetAccessTokenForRequestAsync();
var headerInterceptor = AuthInterceptors.FromAccessToken(oauth2Token); var headerInterceptor = AuthInterceptors.FromAccessToken(accessToken);
var request = new SimpleRequest var request = new SimpleRequest
{ {
FillUsername = true, FillUsername = true,
FillOauthScope = true
}; };
var headers = new Metadata(); var headers = new Metadata();
headerInterceptor(null, "", headers); headerInterceptor(null, "", headers);
var response = client.UnaryCall(request, headers: headers); var response = client.UnaryCall(request, headers: headers);
Assert.AreEqual(AuthScopeResponse, response.OauthScope); Assert.AreEqual(defaultServiceAccount, response.Username);
Assert.AreEqual(ServiceAccountUser, response.Username);
Console.WriteLine("Passed!"); Console.WriteLine("Passed!");
} }
...@@ -508,68 +488,5 @@ namespace Grpc.IntegrationTesting ...@@ -508,68 +488,5 @@ namespace Grpc.IntegrationTesting
{ {
return new Payload { Body = ByteString.CopyFrom(new byte[size]) }; return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
} }
private static ClientOptions ParseArguments(string[] args)
{
var options = new ClientOptions();
foreach (string arg in args)
{
ParseArgument(arg, options);
if (options.help)
{
break;
}
}
return options;
}
private static void ParseArgument(string arg, ClientOptions options)
{
Match match;
match = Regex.Match(arg, "--server_host=(.*)");
if (match.Success)
{
options.serverHost = match.Groups[1].Value.Trim();
return;
}
match = Regex.Match(arg, "--server_host_override=(.*)");
if (match.Success)
{
options.serverHostOverride = match.Groups[1].Value.Trim();
return;
}
match = Regex.Match(arg, "--server_port=(.*)");
if (match.Success)
{
options.serverPort = int.Parse(match.Groups[1].Value.Trim());
return;
}
match = Regex.Match(arg, "--test_case=(.*)");
if (match.Success)
{
options.testCase = match.Groups[1].Value.Trim();
return;
}
match = Regex.Match(arg, "--use_tls=(.*)");
if (match.Success)
{
options.useTls = bool.Parse(match.Groups[1].Value.Trim());
return;
}
match = Regex.Match(arg, "--use_test_ca=(.*)");
if (match.Success)
{
options.useTestCa = bool.Parse(match.Groups[1].Value.Trim());
return;
}
Console.WriteLine(string.Format("Unrecognized argument \"{0}\"", arg));
options.help = true;
}
} }
} }
...@@ -37,6 +37,9 @@ using System.Diagnostics; ...@@ -37,6 +37,9 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommandLine;
using CommandLine.Text;
using Grpc.Core; using Grpc.Core;
using Grpc.Core.Utils; using Grpc.Core.Utils;
using Grpc.Testing; using Grpc.Testing;
...@@ -48,9 +51,24 @@ namespace Grpc.IntegrationTesting ...@@ -48,9 +51,24 @@ namespace Grpc.IntegrationTesting
{ {
private class ServerOptions private class ServerOptions
{ {
public bool help; [Option("port", DefaultValue = 8070)]
public int? port = 8070; public int Port { get; set; }
public bool useTls;
[Option("use_tls")]
public bool UseTls { get; set; }
[HelpOption]
public string GetUsage()
{
var help = new HelpText
{
Heading = "gRPC C# interop testing server",
AddDashesToOption = true
};
help.AddPreOptionsLine("Usage:");
help.AddOptions(this);
return help;
}
} }
ServerOptions options; ServerOptions options;
...@@ -62,22 +80,9 @@ namespace Grpc.IntegrationTesting ...@@ -62,22 +80,9 @@ namespace Grpc.IntegrationTesting
public static void Run(string[] args) public static void Run(string[] args)
{ {
Console.WriteLine("gRPC C# interop testing server"); var options = new ServerOptions();
ServerOptions options = ParseArguments(args); if (!Parser.Default.ParseArguments(args, options))
if (!options.port.HasValue)
{
Console.WriteLine("Missing required argument.");
Console.WriteLine();
options.help = true;
}
if (options.help)
{ {
Console.WriteLine("Usage:");
Console.WriteLine(" --port=PORT");
Console.WriteLine(" --use_tls=BOOLEAN");
Console.WriteLine();
Environment.Exit(1); Environment.Exit(1);
} }
...@@ -93,54 +98,19 @@ namespace Grpc.IntegrationTesting ...@@ -93,54 +98,19 @@ namespace Grpc.IntegrationTesting
}; };
string host = "0.0.0.0"; string host = "0.0.0.0";
int port = options.port.Value; int port = options.Port;
if (options.useTls) if (options.UseTls)
{ {
server.Ports.Add(host, port, TestCredentials.CreateTestServerCredentials()); server.Ports.Add(host, port, TestCredentials.CreateTestServerCredentials());
} }
else else
{ {
server.Ports.Add(host, options.port.Value, ServerCredentials.Insecure); server.Ports.Add(host, options.Port, ServerCredentials.Insecure);
} }
Console.WriteLine("Running server on " + string.Format("{0}:{1}", host, port)); Console.WriteLine("Running server on " + string.Format("{0}:{1}", host, port));
server.Start(); server.Start();
server.ShutdownTask.Wait(); server.ShutdownTask.Wait();
} }
private static ServerOptions ParseArguments(string[] args)
{
var options = new ServerOptions();
foreach (string arg in args)
{
ParseArgument(arg, options);
if (options.help)
{
break;
}
}
return options;
}
private static void ParseArgument(string arg, ServerOptions options)
{
Match match;
match = Regex.Match(arg, "--port=(.*)");
if (match.Success)
{
options.port = int.Parse(match.Groups[1].Value.Trim());
return;
}
match = Regex.Match(arg, "--use_tls=(.*)");
if (match.Success)
{
options.useTls = bool.Parse(match.Groups[1].Value.Trim());
return;
}
Console.WriteLine(string.Format("Unrecognized argument \"{0}\"", arg));
options.help = true;
}
} }
} }
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" /> <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" /> <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
<package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" /> <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" /> <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment