This reverts commit 8afb78fb95.
This commit is contained in:
parent
dab0296983
commit
236dcd9fbe
|
|
@ -674,9 +674,9 @@ stages:
|
|||
# Build the shared framework
|
||||
- script: ./build.cmd -ci -all -pack -arch x64 -buildNative /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log /bl:artifacts/log/helix.build.x64.binlog
|
||||
displayName: Build shared fx
|
||||
- script: .\restore.cmd -ci /p:BuildInteropProjects=true
|
||||
- script: .\restore.cmd -ci
|
||||
displayName: Restore
|
||||
- script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsRequiredCheck=true /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildInteropProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
- script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsRequiredCheck=true /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
displayName: Run build.cmd helix target
|
||||
env:
|
||||
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||
|
|
@ -701,7 +701,7 @@ stages:
|
|||
# Build the x86 shared framework
|
||||
- script: .\restore.cmd -ci
|
||||
displayName: Restore
|
||||
- script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:BuildAllProjects=true /p:BuildInteropProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
- script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:BuildAllProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
displayName: Run build.cmd helix target
|
||||
env:
|
||||
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
displayName: Build shared fx
|
||||
- script: .\restore.cmd -ci
|
||||
displayName: Restore
|
||||
- script: .\build.cmd -ci -NoRestore -test -noBuildJava -projects eng\helix\helix.proj /p:RunQuarantinedTests=true /p:IsRequiredCheck=true /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildInteropProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
- script: .\build.cmd -ci -NoRestore -test -noBuildJava -projects eng\helix\helix.proj /p:RunQuarantinedTests=true /p:IsRequiredCheck=true /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildNative=true /p:RunTemplateTests=true /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log -bl
|
||||
displayName: Run build.cmd helix target
|
||||
env:
|
||||
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
|
||||
|
|
|
|||
|
|
@ -167,7 +167,5 @@
|
|||
<Import Project="eng\targets\Npm.Common.targets" Condition="'$(MSBuildProjectExtension)' == '.npmproj'" />
|
||||
<Import Project="eng\targets\ReferenceAssembly.targets" Condition=" $(HasReferenceAssembly) " />
|
||||
<Import Project="eng\targets\Helix.targets" Condition="'$(IsTestProject)' == 'true'" />
|
||||
<Import Project="eng\targets\FunctionalTestAsset.targets" Condition="'$(IsTestAssetProject)' == 'true'" />
|
||||
<Import Project="eng\targets\FunctionalTestWithAssets.targets" Condition="'$(ContainsFunctionalTestAssets)' == 'true'" />
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -123,13 +123,6 @@
|
|||
<ProjectToBuild Condition=" '$(BuildJava)' == 'true'" Include="@(JavaProjects)" Exclude="@(ProjectToExclude)" />
|
||||
<ProjectToExclude Condition=" '$(BuildJava)' != 'true'" Include="@(JavaProjects)" />
|
||||
|
||||
<!-- These interop test projects can only be restored and built after the shared framework is built -->
|
||||
<InteropProjects Include="$(RepoRoot)src\Grpc\**\*.csproj"
|
||||
Exclude="@(ProjectToExclude)" />
|
||||
|
||||
<ProjectToBuild Condition=" '$(BuildInteropProjects)' == 'true'" Include="@(InteropProjects)" Exclude="@(ProjectToExclude)" />
|
||||
<ProjectToExclude Condition=" '$(BuildInteropProjects)' != 'true'" Include="@(InteropProjects)" />
|
||||
|
||||
<!--
|
||||
Use caution to avoid deep recursion. If the globbing pattern picks up something which exceeds MAX_PATH,
|
||||
the entire pattern will silently fail to evaluate correctly.
|
||||
|
|
|
|||
|
|
@ -154,13 +154,8 @@ and are generated based on the last package release.
|
|||
<ItemGroup Label="External dependencies" Condition="'$(DotNetBuildFromSource)' != 'true'">
|
||||
<LatestPackageReference Include="AngleSharp" Version="$(AngleSharpPackageVersion)" />
|
||||
<LatestPackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetPackageVersion)" />
|
||||
<LatestPackageReference Include="CommandLineParser" Version="$(CommandLineParserPackageVersion)" />
|
||||
<LatestPackageReference Include="FSharp.Core" Version="$(FSharpCorePackageVersion)" />
|
||||
<LatestPackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
|
||||
<LatestPackageReference Include="Grpc.AspNetCore" Version="$(GrpcAspNetCorePackageVersion)" />
|
||||
<LatestPackageReference Include="Grpc.Auth" Version="$(GrpcAuthPackageVersion)" />
|
||||
<LatestPackageReference Include="Grpc.Net.Client" Version="$(GrpcNetClientPackageVersion)" />
|
||||
<LatestPackageReference Include="Grpc.Tools" Version="$(GrpcToolsPackageVersion)" />
|
||||
<LatestPackageReference Include="Google.ProtoBuf" Version="$(GoogleProtoBufPackageVersion)" />
|
||||
<LatestPackageReference Include="IdentityServer4" Version="$(IdentityServer4PackageVersion)" />
|
||||
<LatestPackageReference Include="IdentityServer4.AspNetIdentity" Version="$(IdentityServer4AspNetIdentityPackageVersion)" />
|
||||
<LatestPackageReference Include="IdentityServer4.EntityFramework" Version="$(IdentityServer4EntityFrameworkPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -217,13 +217,9 @@
|
|||
<AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
|
||||
<BenchmarkDotNetPackageVersion>0.12.0</BenchmarkDotNetPackageVersion>
|
||||
<CastleCorePackageVersion>4.2.1</CastleCorePackageVersion>
|
||||
<CommandLineParserPackageVersion>2.3.0</CommandLineParserPackageVersion>
|
||||
<FSharpCorePackageVersion>4.2.1</FSharpCorePackageVersion>
|
||||
<GoogleProtobufPackageVersion>3.10.0</GoogleProtobufPackageVersion>
|
||||
<GoogleProtobufPackageVersion>3.8.0</GoogleProtobufPackageVersion>
|
||||
<GrpcAspNetCorePackageVersion>2.27.0</GrpcAspNetCorePackageVersion>
|
||||
<GrpcAuthPackageVersion>2.27.0</GrpcAuthPackageVersion>
|
||||
<GrpcNetClientPackageVersion>2.27.0</GrpcNetClientPackageVersion>
|
||||
<GrpcToolsPackageVersion>2.27.0</GrpcToolsPackageVersion>
|
||||
<IdentityServer4AspNetIdentityPackageVersion>3.0.0</IdentityServer4AspNetIdentityPackageVersion>
|
||||
<IdentityServer4EntityFrameworkPackageVersion>3.0.0</IdentityServer4EntityFrameworkPackageVersion>
|
||||
<IdentityServer4PackageVersion>3.0.0</IdentityServer4PackageVersion>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ echo "Creating nugetRestore directory: $NUGET_RESTORE"
|
|||
mkdir $NUGET_RESTORE
|
||||
mkdir logs
|
||||
|
||||
ls -laR
|
||||
ls -la
|
||||
|
||||
RESET="\033[0m"
|
||||
RED="\033[0;31m"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<Project>
|
||||
<Target Name="CollectFunctionalTestPayload" DependsOnTargets="Publish" Returns="@(DependencyPayload)" >
|
||||
<ItemGroup>
|
||||
<DependencyPayload Include="@(ResolvedFileToPublish)">
|
||||
<RelativePath>$(MSBuildProjectName)\%(ResolvedFileToPublish.RelativePath)</RelativePath>
|
||||
</DependencyPayload>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<Project>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="@(FunctionalTestAssetProjectReference)" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CollectTestAssetPayload" BeforeTargets="GetCopyToOutputDirectoryItems" >
|
||||
<MSBuild Targets="CollectFunctionalTestPayload"
|
||||
BuildInParallel="true"
|
||||
SkipNonexistentTargets="true"
|
||||
Projects="%(FunctionalTestAssetProjectReference.Identity)"
|
||||
RebaseOutputs="True">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="DependencyPayload" />
|
||||
</MSBuild>
|
||||
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath
|
||||
Include="@(DependencyPayload)"
|
||||
Condition="'@(DependencyPayload->Count())' != '0'">
|
||||
<TargetPath>%(DependencyPayload.RelativePath)</TargetPath>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29505.145
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0FFB3605-0203-450F-80C8-F82CA2E8269F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{F5841B0A-901A-448F-9CC5-4CB393CE86AF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTests", "test\InteropTests\InteropTests.csproj", "{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropWebsite", "test\testassets\InteropWebsite\InteropWebsite.csproj", "{3AB7E8E4-BA36-44CE-844E-39DB66E46D45}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropClient", "test\testassets\InteropClient\InteropClient.csproj", "{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3AB7E8E4-BA36-44CE-844E-39DB66E46D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3AB7E8E4-BA36-44CE-844E-39DB66E46D45}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3AB7E8E4-BA36-44CE-844E-39DB66E46D45}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3AB7E8E4-BA36-44CE-844E-39DB66E46D45}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{90BF37E6-B3F1-4EFC-A233-8288D8B32DD2} = {0FFB3605-0203-450F-80C8-F82CA2E8269F}
|
||||
{3AB7E8E4-BA36-44CE-844E-39DB66E46D45} = {F5841B0A-901A-448F-9CC5-4CB393CE86AF}
|
||||
{66E6C55E-E4E3-4F4B-834A-BB34BFE00D2F} = {F5841B0A-901A-448F-9CC5-4CB393CE86AF}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3CAE66FD-9A59-49C2-B133-1D599225259A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
.NET Core uses third-party libraries or other resources that may be
|
||||
distributed under licenses different than the .NET Core software.
|
||||
|
||||
In the event that we accidentally failed to list a required notice, please
|
||||
bring it to our attention. Post an issue or email us:
|
||||
|
||||
dotnet@microsoft.com
|
||||
|
||||
The attached notices are provided for information only.
|
||||
|
||||
License notice for gRPC interop tests
|
||||
-------------------------------------
|
||||
|
||||
Copyright 2019 The gRPC Authors
|
||||
|
||||
Licensed 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.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
@ECHO OFF
|
||||
SET RepoRoot=%~dp0..\..
|
||||
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %*
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
repo_root="$DIR/../.."
|
||||
"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "$@"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
@ECHO OFF
|
||||
|
||||
%~dp0..\..\startvs.cmd %~dp0Grpc.sln
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace InteropTests.Helpers
|
||||
{
|
||||
public class ClientProcess : IDisposable
|
||||
{
|
||||
private readonly Process _process;
|
||||
private readonly ProcessEx _processEx;
|
||||
private readonly TaskCompletionSource<object> _startTcs;
|
||||
|
||||
public ClientProcess(ITestOutputHelper output, string path, string serverPort, string testCase)
|
||||
{
|
||||
_process = new Process();
|
||||
_process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
FileName = "dotnet",
|
||||
Arguments = @$"{path} --use_tls false --server_port {serverPort} --client_type httpclient --test_case {testCase}"
|
||||
};
|
||||
_process.EnableRaisingEvents = true;
|
||||
_process.OutputDataReceived += Process_OutputDataReceived;
|
||||
_process.Start();
|
||||
|
||||
_processEx = new ProcessEx(output, _process);
|
||||
|
||||
_startTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
}
|
||||
|
||||
public Task WaitForReady()
|
||||
{
|
||||
return _startTcs.Task;
|
||||
}
|
||||
|
||||
public int ExitCode => _process.ExitCode;
|
||||
public Task Exited => _processEx.Exited;
|
||||
|
||||
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
var data = e.Data;
|
||||
if (data != null)
|
||||
{
|
||||
if (data.Contains("Application started."))
|
||||
{
|
||||
_startTcs.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_processEx.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace InteropTests.Helpers
|
||||
{
|
||||
public class InteropTestsFixture : IDisposable
|
||||
{
|
||||
private WebsiteProcess _process;
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
|
||||
public string ServerPort { get; private set; }
|
||||
|
||||
|
||||
public async Task EnsureStarted(ITestOutputHelper output)
|
||||
{
|
||||
if (_process != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
{
|
||||
throw new InvalidOperationException("Path has not been set.");
|
||||
}
|
||||
|
||||
_process = new WebsiteProcess(Path, output);
|
||||
|
||||
await _process.WaitForReady();
|
||||
|
||||
ServerPort = _process.ServerPort;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_process.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace InteropTests.Helpers
|
||||
{
|
||||
public class WebsiteProcess : IDisposable
|
||||
{
|
||||
private readonly Process _process;
|
||||
private readonly ProcessEx _processEx;
|
||||
private readonly TaskCompletionSource<object> _startTcs;
|
||||
private readonly StringBuilder _consoleOut = new StringBuilder();
|
||||
private static readonly Regex NowListeningRegex = new Regex(@"^\s*Now listening on: .*:(?<port>\d*)$");
|
||||
|
||||
public string ServerPort { get; private set; }
|
||||
|
||||
public WebsiteProcess(string path, ITestOutputHelper output)
|
||||
{
|
||||
_process = new Process();
|
||||
_process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
FileName = "dotnet",
|
||||
Arguments = path
|
||||
};
|
||||
_process.EnableRaisingEvents = true;
|
||||
_process.OutputDataReceived += Process_OutputDataReceived;
|
||||
_process.Start();
|
||||
|
||||
_processEx = new ProcessEx(output, _process);
|
||||
|
||||
_startTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
}
|
||||
|
||||
public Task WaitForReady()
|
||||
{
|
||||
if (_processEx.HasExited)
|
||||
{
|
||||
return Task.FromException(new InvalidOperationException("Server is not running."));
|
||||
}
|
||||
|
||||
return _startTcs.Task;
|
||||
}
|
||||
|
||||
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
var data = e.Data;
|
||||
if (data != null)
|
||||
{
|
||||
_consoleOut.AppendLine(data);
|
||||
var m = NowListeningRegex.Match(data);
|
||||
if (m.Success)
|
||||
{
|
||||
ServerPort = m.Groups["port"].Value;
|
||||
}
|
||||
|
||||
if (data.Contains("Application started. Press Ctrl+C to shut down."))
|
||||
{
|
||||
_startTcs.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
var attributes = Assembly.GetExecutingAssembly()
|
||||
.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
var serverLogPath = attributes.SingleOrDefault(a => a.Key == "ServerLogPath")?.Value;
|
||||
if (!string.IsNullOrEmpty(serverLogPath))
|
||||
{
|
||||
File.WriteAllText(serverLogPath, _consoleOut.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
var logDir = Path.Combine(Directory.GetCurrentDirectory(), "artifacts", "logs");
|
||||
Directory.CreateDirectory(logDir);
|
||||
File.WriteAllText(Path.Combine(logDir, "InteropServer.log"), _consoleOut.ToString());
|
||||
}
|
||||
_processEx.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using InteropTests.Helpers;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace InteropTests
|
||||
{
|
||||
public class InteropTests : IClassFixture<InteropTestsFixture>
|
||||
{
|
||||
private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
private readonly string _clientPath = Path.Combine(Directory.GetCurrentDirectory(), "InteropClient", "InteropClient.dll");
|
||||
private readonly InteropTestsFixture _fixture;
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
public InteropTests(InteropTestsFixture fixture, ITestOutputHelper output)
|
||||
{
|
||||
var attributes = Assembly.GetExecutingAssembly()
|
||||
.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
|
||||
fixture.Path = Path.Combine(Directory.GetCurrentDirectory(), "InteropWebsite", "InteropWebsite.dll");
|
||||
|
||||
_fixture = fixture;
|
||||
_output = output;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TestCaseData))]
|
||||
public async Task InteropTestCase(string name)
|
||||
{
|
||||
await _fixture.EnsureStarted(_output).TimeoutAfter(DefaultTimeout);
|
||||
|
||||
using (var clientProcess = new ClientProcess(_output, _clientPath, _fixture.ServerPort, name))
|
||||
{
|
||||
await clientProcess.WaitForReady().TimeoutAfter(DefaultTimeout);
|
||||
|
||||
await clientProcess.Exited.TimeoutAfter(DefaultTimeout);
|
||||
|
||||
Assert.Equal(0, clientProcess.ExitCode);
|
||||
}
|
||||
}
|
||||
|
||||
#region TestData
|
||||
// All interop test cases, minus GCE authentication specific tests
|
||||
private static string[] AllTests = new string[]
|
||||
{
|
||||
"empty_unary",
|
||||
"large_unary",
|
||||
"client_streaming",
|
||||
"server_streaming",
|
||||
"ping_pong",
|
||||
"empty_stream",
|
||||
|
||||
"cancel_after_begin",
|
||||
"cancel_after_first_response",
|
||||
"timeout_on_sleeping_server",
|
||||
"custom_metadata",
|
||||
"status_code_and_message",
|
||||
"special_status_message",
|
||||
"unimplemented_service",
|
||||
"unimplemented_method",
|
||||
"client_compressed_unary",
|
||||
"client_compressed_streaming",
|
||||
"server_compressed_unary",
|
||||
"server_compressed_streaming"
|
||||
};
|
||||
|
||||
public static IEnumerable<object[]> TestCaseData => AllTests.Select(t => new object[] { t });
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ContainsFunctionalTestAssets>true</ContainsFunctionalTestAssets>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\Shared\Process\ProcessEx.cs" Link="Helpers\ProcessEx.cs" />
|
||||
<Compile Include="..\..\..\Shared\Process\ProcessExtensions.cs" Link="Helpers\ProcessExtensions.cs" />
|
||||
|
||||
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute" Condition="'$(IsHelixJob)' != 'true'">
|
||||
<_Parameter1>ServerLogPath</_Parameter1>
|
||||
<_Parameter2>$(ArtifactsLogDir)InteropServer.log</_Parameter2>
|
||||
</AssemblyAttribute>
|
||||
|
||||
<FunctionalTestAssetProjectReference Include="..\testassets\InteropClient\InteropClient.csproj" />
|
||||
<FunctionalTestAssetProjectReference Include="..\testassets\InteropWebsite\InteropWebsite.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace InteropTestsClient
|
||||
{
|
||||
internal static class Assert
|
||||
{
|
||||
public static void IsTrue(bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw new InvalidOperationException("Expected true but got false.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void IsFalse(bool condition)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
throw new InvalidOperationException("Expected false but got true.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AreEqual(object expected, object actual)
|
||||
{
|
||||
if (!Equals(expected, actual))
|
||||
{
|
||||
throw new InvalidOperationException($"Expected {expected} but got {actual}.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void IsNotNull(object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new InvalidOperationException("Expected not null but got null.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fail()
|
||||
{
|
||||
throw new InvalidOperationException("Failure assert.");
|
||||
}
|
||||
|
||||
public static async Task<TException> ThrowsAsync<TException>(Func<Task> action) where TException : Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.GetType() == typeof(TException))
|
||||
{
|
||||
return (TException)ex;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Expected ${typeof(TException)} but got ${ex.GetType()}.");
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("No exception thrown.");
|
||||
}
|
||||
|
||||
public static TException Throws<TException>(Action action) where TException : Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.GetType() == typeof(TException))
|
||||
{
|
||||
return (TException)ex;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Expected ${typeof(TException)} but got ${ex.GetType()}.");
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("No exception thrown.");
|
||||
}
|
||||
|
||||
public static void Contains(object expected, ICollection actual)
|
||||
{
|
||||
foreach (var item in actual)
|
||||
{
|
||||
if (Equals(item, expected))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Could not find {expected} in the collection.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CollectionAssert
|
||||
{
|
||||
public static void AreEqual(IList expected, IList actual)
|
||||
{
|
||||
if (expected.Count != actual.Count)
|
||||
{
|
||||
throw new InvalidOperationException($"Collection lengths differ. {expected.Count} but got {actual.Count}.");
|
||||
}
|
||||
|
||||
for (var i = 0; i < expected.Count; i++)
|
||||
{
|
||||
Assert.AreEqual(expected[i]!, actual[i]!);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace InteropTestsClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods that simplify work with gRPC streaming calls.
|
||||
/// </summary>
|
||||
public static class AsyncStreamExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads the entire stream and executes an async action for each element.
|
||||
/// </summary>
|
||||
public static async Task ForEachAsync<T>(this IAsyncStreamReader<T> streamReader, Func<T, Task> asyncAction)
|
||||
where T : class
|
||||
{
|
||||
while (await streamReader.MoveNext().ConfigureAwait(false))
|
||||
{
|
||||
await asyncAction(streamReader.Current).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the entire stream and creates a list containing all the elements read.
|
||||
/// </summary>
|
||||
public static async Task<List<T>> ToListAsync<T>(this IAsyncStreamReader<T> streamReader)
|
||||
where T : class
|
||||
{
|
||||
var result = new List<T>();
|
||||
while (await streamReader.MoveNext().ConfigureAwait(false))
|
||||
{
|
||||
result.Add(streamReader.Current);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes all elements from given enumerable to the stream.
|
||||
/// Completes the stream afterwards unless close = false.
|
||||
/// </summary>
|
||||
public static async Task WriteAllAsync<T>(this IClientStreamWriter<T> streamWriter, IEnumerable<T> elements, bool complete = true)
|
||||
where T : class
|
||||
{
|
||||
foreach (var element in elements)
|
||||
{
|
||||
await streamWriter.WriteAsync(element).ConfigureAwait(false);
|
||||
}
|
||||
if (complete)
|
||||
{
|
||||
await streamWriter.CompleteAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes all elements from given enumerable to the stream.
|
||||
/// </summary>
|
||||
public static async Task WriteAllAsync<T>(this IServerStreamWriter<T> streamWriter, IEnumerable<T> elements)
|
||||
where T : class
|
||||
{
|
||||
foreach (var element in elements)
|
||||
{
|
||||
await streamWriter.WriteAsync(element).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
namespace InteropTestsClient
|
||||
{
|
||||
public interface IChannelWrapper
|
||||
{
|
||||
ChannelBase Channel { get; }
|
||||
Task ShutdownAsync();
|
||||
}
|
||||
|
||||
public class GrpcChannelWrapper : IChannelWrapper
|
||||
{
|
||||
public ChannelBase Channel { get; }
|
||||
|
||||
public GrpcChannelWrapper(GrpcChannel channel)
|
||||
{
|
||||
Channel = channel;
|
||||
}
|
||||
|
||||
public Task ShutdownAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,899 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommandLine;
|
||||
using Google.Apis.Auth.OAuth2;
|
||||
using Google.Protobuf;
|
||||
using Grpc.Auth;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
using Grpc.Net.Client;
|
||||
using Grpc.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace InteropTestsClient
|
||||
{
|
||||
public class InteropClient : IDisposable
|
||||
{
|
||||
internal const string CompressionRequestAlgorithmMetadataKey = "grpc-internal-encoding-request";
|
||||
|
||||
private class ClientOptions
|
||||
{
|
||||
[Option("client_type", Default = "httpclient")]
|
||||
public string? ClientType { get; set; }
|
||||
|
||||
[Option("server_host", Default = "localhost")]
|
||||
public string? ServerHost { get; set; }
|
||||
|
||||
[Option("server_host_override")]
|
||||
public string? ServerHostOverride { get; set; }
|
||||
|
||||
[Option("server_port"
|
||||
#if DEBUG
|
||||
, Default = 50052
|
||||
#endif
|
||||
)]
|
||||
public int ServerPort { get; set; }
|
||||
|
||||
[Option("test_case"
|
||||
#if DEBUG
|
||||
, Default = "large_unary"
|
||||
#endif
|
||||
)]
|
||||
public string? TestCase { get; set; }
|
||||
|
||||
// Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
|
||||
[Option("use_tls", Default = false)]
|
||||
public bool? UseTls { get; set; }
|
||||
|
||||
// Deliberately using nullable bool type to allow --use_test_ca=true syntax (as opposed to --use_test_ca)
|
||||
[Option("use_test_ca", Default = false)]
|
||||
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; }
|
||||
}
|
||||
|
||||
private ServiceProvider serviceProvider;
|
||||
private ILoggerFactory loggerFactory;
|
||||
private ClientOptions options;
|
||||
|
||||
private InteropClient(ClientOptions options)
|
||||
{
|
||||
this.options = options;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging(configure =>
|
||||
{
|
||||
configure.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
configure.AddConsole(loggerOptions => loggerOptions.IncludeScopes = true);
|
||||
});
|
||||
|
||||
serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
serviceProvider.Dispose();
|
||||
}
|
||||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
var parserResult = Parser.Default.ParseArguments<ClientOptions>(args)
|
||||
.WithNotParsed(errors => Environment.Exit(1))
|
||||
.WithParsed(options =>
|
||||
{
|
||||
Console.WriteLine("Use TLS: " + options.UseTls);
|
||||
Console.WriteLine("Use Test CA: " + options.UseTestCa);
|
||||
Console.WriteLine("Client type: " + options.ClientType);
|
||||
Console.WriteLine("Server host: " + options.ServerHost);
|
||||
Console.WriteLine("Server port: " + options.ServerPort);
|
||||
|
||||
using (var interopClient = new InteropClient(options))
|
||||
{
|
||||
interopClient.Run().GetAwaiter().GetResult();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task Run()
|
||||
{
|
||||
var channel = await HttpClientCreateChannel();
|
||||
await RunTestCaseAsync(channel, options);
|
||||
await channel.ShutdownAsync();
|
||||
}
|
||||
|
||||
private async Task<IChannelWrapper> HttpClientCreateChannel()
|
||||
{
|
||||
var credentials = await CreateCredentialsAsync(useTestCaOverride: false);
|
||||
|
||||
string scheme;
|
||||
if (!(options.UseTls ?? false))
|
||||
{
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
scheme = "http";
|
||||
}
|
||||
else
|
||||
{
|
||||
scheme = "https";
|
||||
}
|
||||
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||
|
||||
if (options.UseTestCa ?? false)
|
||||
{
|
||||
var pem = File.ReadAllText("Certs/ca.pem");
|
||||
var certData = GetBytesFromPem(pem, "CERTIFICATE");
|
||||
var cert = new X509Certificate2(certData!);
|
||||
|
||||
httpClientHandler.ClientCertificates.Add(cert);
|
||||
}
|
||||
|
||||
var httpClient = new HttpClient(httpClientHandler);
|
||||
|
||||
var channel = GrpcChannel.ForAddress($"{scheme}://{options.ServerHost}:{options.ServerPort}", new GrpcChannelOptions
|
||||
{
|
||||
Credentials = credentials,
|
||||
HttpClient = httpClient,
|
||||
LoggerFactory = loggerFactory
|
||||
});
|
||||
|
||||
return new GrpcChannelWrapper(channel);
|
||||
}
|
||||
|
||||
private bool IsHttpClient() => string.Equals(options.ClientType, "httpclient", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private async Task<ChannelCredentials> CreateCredentialsAsync(bool? useTestCaOverride = null)
|
||||
{
|
||||
var credentials = ChannelCredentials.Insecure;
|
||||
if (options.UseTls.GetValueOrDefault())
|
||||
{
|
||||
credentials = new SslCredentials();
|
||||
}
|
||||
|
||||
if (options.TestCase == "jwt_token_creds")
|
||||
{
|
||||
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
Assert.IsTrue(googleCredential.IsCreateScopedRequired);
|
||||
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
|
||||
}
|
||||
|
||||
if (options.TestCase == "compute_engine_creds")
|
||||
{
|
||||
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
Assert.IsFalse(googleCredential.IsCreateScopedRequired);
|
||||
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
|
||||
}
|
||||
return credentials;
|
||||
}
|
||||
|
||||
private TClient CreateClient<TClient>(IChannelWrapper channel) where TClient : ClientBase
|
||||
{
|
||||
return (TClient)Activator.CreateInstance(typeof(TClient), channel.Channel)!;
|
||||
}
|
||||
|
||||
private async Task RunTestCaseAsync(IChannelWrapper channel, ClientOptions options)
|
||||
{
|
||||
var client = CreateClient<TestService.TestServiceClient>(channel);
|
||||
switch (options.TestCase)
|
||||
{
|
||||
case "empty_unary":
|
||||
RunEmptyUnary(client);
|
||||
break;
|
||||
case "large_unary":
|
||||
RunLargeUnary(client);
|
||||
break;
|
||||
case "client_streaming":
|
||||
await RunClientStreamingAsync(client);
|
||||
break;
|
||||
case "server_streaming":
|
||||
await RunServerStreamingAsync(client);
|
||||
break;
|
||||
case "ping_pong":
|
||||
await RunPingPongAsync(client);
|
||||
break;
|
||||
case "empty_stream":
|
||||
await RunEmptyStreamAsync(client);
|
||||
break;
|
||||
case "compute_engine_creds":
|
||||
RunComputeEngineCreds(client, options.DefaultServiceAccount!, options.OAuthScope!);
|
||||
break;
|
||||
case "jwt_token_creds":
|
||||
RunJwtTokenCreds(client);
|
||||
break;
|
||||
case "oauth2_auth_token":
|
||||
await RunOAuth2AuthTokenAsync(client, options.OAuthScope!);
|
||||
break;
|
||||
case "per_rpc_creds":
|
||||
await RunPerRpcCredsAsync(client, options.OAuthScope!);
|
||||
break;
|
||||
case "cancel_after_begin":
|
||||
await RunCancelAfterBeginAsync(client);
|
||||
break;
|
||||
case "cancel_after_first_response":
|
||||
await RunCancelAfterFirstResponseAsync(client);
|
||||
break;
|
||||
case "timeout_on_sleeping_server":
|
||||
await RunTimeoutOnSleepingServerAsync(client);
|
||||
break;
|
||||
case "custom_metadata":
|
||||
await RunCustomMetadataAsync(client);
|
||||
break;
|
||||
case "status_code_and_message":
|
||||
await RunStatusCodeAndMessageAsync(client);
|
||||
break;
|
||||
case "unimplemented_service":
|
||||
RunUnimplementedService(CreateClient<UnimplementedService.UnimplementedServiceClient>(channel));
|
||||
break;
|
||||
case "special_status_message":
|
||||
await RunSpecialStatusMessageAsync(client);
|
||||
break;
|
||||
case "unimplemented_method":
|
||||
RunUnimplementedMethod(client);
|
||||
break;
|
||||
case "client_compressed_unary":
|
||||
RunClientCompressedUnary(client);
|
||||
break;
|
||||
case "client_compressed_streaming":
|
||||
await RunClientCompressedStreamingAsync(client);
|
||||
break;
|
||||
case "server_compressed_unary":
|
||||
await RunServerCompressedUnary(client);
|
||||
break;
|
||||
case "server_compressed_streaming":
|
||||
await RunServerCompressedStreamingAsync(client);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unknown test case " + options.TestCase);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RunEmptyUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running empty_unary");
|
||||
var response = client.EmptyCall(new Empty());
|
||||
Assert.IsNotNull(response);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunLargeUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running large_unary");
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828)
|
||||
};
|
||||
var response = client.UnaryCall(request);
|
||||
|
||||
Assert.AreEqual(314159, response.Payload.Body.Length);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunClientStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running client_streaming");
|
||||
|
||||
var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.Select((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
|
||||
|
||||
using (var call = client.StreamingInputCall())
|
||||
{
|
||||
await call.RequestStream.WriteAllAsync(bodySizes);
|
||||
|
||||
var response = await call.ResponseAsync;
|
||||
Assert.AreEqual(74922, response.AggregatedPayloadSize);
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunServerStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running server_streaming");
|
||||
|
||||
var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
|
||||
|
||||
var request = new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { bodySizes.Select((size) => new ResponseParameters { Size = size }) }
|
||||
};
|
||||
|
||||
using (var call = client.StreamingOutputCall(request))
|
||||
{
|
||||
var responseList = await call.ResponseStream.ToListAsync();
|
||||
CollectionAssert.AreEqual(bodySizes, responseList.Select((item) => item.Payload.Body.Length).ToList());
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunPingPongAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running ping_pong");
|
||||
|
||||
using (var call = client.FullDuplexCall())
|
||||
{
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 31415 } },
|
||||
Payload = CreateZerosPayload(27182)
|
||||
});
|
||||
|
||||
Assert.IsTrue(await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
|
||||
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 9 } },
|
||||
Payload = CreateZerosPayload(8)
|
||||
});
|
||||
|
||||
Assert.IsTrue(await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
|
||||
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 2653 } },
|
||||
Payload = CreateZerosPayload(1828)
|
||||
});
|
||||
|
||||
Assert.IsTrue(await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
|
||||
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 58979 } },
|
||||
Payload = CreateZerosPayload(45904)
|
||||
});
|
||||
|
||||
Assert.IsTrue(await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
|
||||
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
Assert.IsFalse(await call.ResponseStream.MoveNext());
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunEmptyStreamAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running empty_stream");
|
||||
using (var call = client.FullDuplexCall())
|
||||
{
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
var responseList = await call.ResponseStream.ToListAsync();
|
||||
Assert.AreEqual(0, responseList.Count);
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunComputeEngineCreds(TestService.TestServiceClient client, string defaultServiceAccount, string oauthScope)
|
||||
{
|
||||
Console.WriteLine("running compute_engine_creds");
|
||||
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828),
|
||||
FillUsername = true,
|
||||
FillOauthScope = true
|
||||
};
|
||||
|
||||
// not setting credentials here because they were set on channel already
|
||||
var response = client.UnaryCall(request);
|
||||
|
||||
Assert.AreEqual(314159, response.Payload.Body.Length);
|
||||
Assert.IsFalse(string.IsNullOrEmpty(response.OauthScope));
|
||||
Assert.IsTrue(oauthScope.Contains(response.OauthScope));
|
||||
Assert.AreEqual(defaultServiceAccount, response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunJwtTokenCreds(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running jwt_token_creds");
|
||||
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828),
|
||||
FillUsername = true,
|
||||
};
|
||||
|
||||
// not setting credentials here because they were set on channel already
|
||||
var response = client.UnaryCall(request);
|
||||
|
||||
Assert.AreEqual(314159, response.Payload.Body.Length);
|
||||
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
|
||||
{
|
||||
Console.WriteLine("running oauth2_auth_token");
|
||||
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
|
||||
string oauth2Token = await credential.GetAccessTokenForRequestAsync();
|
||||
|
||||
var credentials = GoogleGrpcCredentials.FromAccessToken(oauth2Token);
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
FillUsername = true,
|
||||
FillOauthScope = true
|
||||
};
|
||||
|
||||
var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
|
||||
|
||||
Assert.IsFalse(string.IsNullOrEmpty(response.OauthScope));
|
||||
Assert.IsTrue(oauthScope.Contains(response.OauthScope));
|
||||
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
|
||||
{
|
||||
Console.WriteLine("running per_rpc_creds");
|
||||
ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
|
||||
var credentials = googleCredential.ToCallCredentials();
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
FillUsername = true,
|
||||
};
|
||||
|
||||
var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
|
||||
|
||||
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running cancel_after_begin");
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
using (var call = client.StreamingInputCall(cancellationToken: cts.Token))
|
||||
{
|
||||
// TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
|
||||
await Task.Delay(1000);
|
||||
cts.Cancel();
|
||||
|
||||
var ex = await Assert.ThrowsAsync<RpcException>(() => call.ResponseAsync);
|
||||
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCancelAfterFirstResponseAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running cancel_after_first_response");
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
|
||||
{
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 31415 } },
|
||||
Payload = CreateZerosPayload(27182)
|
||||
});
|
||||
|
||||
Assert.IsTrue(await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
try
|
||||
{
|
||||
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
|
||||
await call.ResponseStream.MoveNext();
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (RpcException ex)
|
||||
{
|
||||
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunTimeoutOnSleepingServerAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running timeout_on_sleeping_server");
|
||||
|
||||
var deadline = DateTime.UtcNow.AddMilliseconds(1);
|
||||
using (var call = client.FullDuplexCall(deadline: deadline))
|
||||
{
|
||||
try
|
||||
{
|
||||
await call.RequestStream.WriteAsync(new StreamingOutputCallRequest { Payload = CreateZerosPayload(27182) });
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// Deadline was reached before write has started. Eat the exception and continue.
|
||||
}
|
||||
catch (RpcException)
|
||||
{
|
||||
// Deadline was reached before write has started. Eat the exception and continue.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await call.ResponseStream.MoveNext();
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (RpcException ex)
|
||||
{
|
||||
Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCustomMetadataAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running custom_metadata");
|
||||
{
|
||||
// step 1: test unary call
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828)
|
||||
};
|
||||
|
||||
var call = client.UnaryCallAsync(request, headers: CreateTestMetadata());
|
||||
await call.ResponseAsync;
|
||||
|
||||
var responseHeaders = await call.ResponseHeadersAsync;
|
||||
var responseTrailers = call.GetTrailers();
|
||||
|
||||
Assert.AreEqual("test_initial_metadata_value", responseHeaders.First((entry) => entry.Key == "x-grpc-test-echo-initial").Value);
|
||||
CollectionAssert.AreEqual(new byte[] { 0xab, 0xab, 0xab }, responseTrailers.First((entry) => entry.Key == "x-grpc-test-echo-trailing-bin").ValueBytes);
|
||||
}
|
||||
|
||||
{
|
||||
// step 2: test full duplex call
|
||||
var request = new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { new ResponseParameters { Size = 31415 } },
|
||||
Payload = CreateZerosPayload(27182)
|
||||
};
|
||||
|
||||
var call = client.FullDuplexCall(headers: CreateTestMetadata());
|
||||
|
||||
await call.RequestStream.WriteAsync(request);
|
||||
await call.RequestStream.CompleteAsync();
|
||||
await call.ResponseStream.ToListAsync();
|
||||
|
||||
var responseHeaders = await call.ResponseHeadersAsync;
|
||||
var responseTrailers = call.GetTrailers();
|
||||
|
||||
Assert.AreEqual("test_initial_metadata_value", responseHeaders.First((entry) => entry.Key == "x-grpc-test-echo-initial").Value);
|
||||
CollectionAssert.AreEqual(new byte[] { 0xab, 0xab, 0xab }, responseTrailers.First((entry) => entry.Key == "x-grpc-test-echo-trailing-bin").ValueBytes);
|
||||
}
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunStatusCodeAndMessageAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running status_code_and_message");
|
||||
var echoStatus = new EchoStatus
|
||||
{
|
||||
Code = 2,
|
||||
Message = "test status message"
|
||||
};
|
||||
|
||||
{
|
||||
// step 1: test unary call
|
||||
var request = new SimpleRequest { ResponseStatus = echoStatus };
|
||||
|
||||
var e = Assert.Throws<RpcException>(() => client.UnaryCall(request));
|
||||
Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
|
||||
Assert.AreEqual(echoStatus.Message, e.Status.Detail);
|
||||
}
|
||||
|
||||
{
|
||||
// step 2: test full duplex call
|
||||
var request = new StreamingOutputCallRequest { ResponseStatus = echoStatus };
|
||||
|
||||
var call = client.FullDuplexCall();
|
||||
await call.RequestStream.WriteAsync(request);
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
try
|
||||
{
|
||||
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
|
||||
await call.ResponseStream.ToListAsync();
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (RpcException e)
|
||||
{
|
||||
Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
|
||||
Assert.AreEqual(echoStatus.Message, e.Status.Detail);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
private static async Task RunSpecialStatusMessageAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running special_status_message");
|
||||
|
||||
var echoStatus = new EchoStatus
|
||||
{
|
||||
Code = 2,
|
||||
Message = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n"
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await client.UnaryCallAsync(new SimpleRequest
|
||||
{
|
||||
ResponseStatus = echoStatus
|
||||
});
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (RpcException e)
|
||||
{
|
||||
Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
|
||||
Assert.AreEqual(echoStatus.Message, e.Status.Detail);
|
||||
}
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunUnimplementedService(UnimplementedService.UnimplementedServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running unimplemented_service");
|
||||
var e = Assert.Throws<RpcException>(() => client.UnimplementedCall(new Empty()));
|
||||
|
||||
Assert.AreEqual(StatusCode.Unimplemented, e.Status.StatusCode);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunUnimplementedMethod(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running unimplemented_method");
|
||||
var e = Assert.Throws<RpcException>(() => client.UnimplementedCall(new Empty()));
|
||||
|
||||
Assert.AreEqual(StatusCode.Unimplemented, e.Status.StatusCode);
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunClientCompressedUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running client_compressed_unary");
|
||||
var probeRequest = new SimpleRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = true // lie about compression
|
||||
},
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828)
|
||||
};
|
||||
var e = Assert.Throws<RpcException>(() => client.UnaryCall(probeRequest, CreateClientCompressionMetadata(false)));
|
||||
Assert.AreEqual(StatusCode.InvalidArgument, e.Status.StatusCode);
|
||||
|
||||
var compressedRequest = new SimpleRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = true
|
||||
},
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828)
|
||||
};
|
||||
var response1 = client.UnaryCall(compressedRequest, CreateClientCompressionMetadata(true));
|
||||
Assert.AreEqual(314159, response1.Payload.Body.Length);
|
||||
|
||||
var uncompressedRequest = new SimpleRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = false
|
||||
},
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828)
|
||||
};
|
||||
var response2 = client.UnaryCall(uncompressedRequest, CreateClientCompressionMetadata(false));
|
||||
Assert.AreEqual(314159, response2.Payload.Body.Length);
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunClientCompressedStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running client_compressed_streaming");
|
||||
try
|
||||
{
|
||||
var probeCall = client.StreamingInputCall(CreateClientCompressionMetadata(false));
|
||||
await probeCall.RequestStream.WriteAsync(new StreamingInputCallRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = true
|
||||
},
|
||||
Payload = CreateZerosPayload(27182)
|
||||
});
|
||||
|
||||
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
|
||||
await probeCall;
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (RpcException e)
|
||||
{
|
||||
Assert.AreEqual(StatusCode.InvalidArgument, e.Status.StatusCode);
|
||||
}
|
||||
|
||||
var call = client.StreamingInputCall(CreateClientCompressionMetadata(true));
|
||||
await call.RequestStream.WriteAsync(new StreamingInputCallRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = true
|
||||
},
|
||||
Payload = CreateZerosPayload(27182)
|
||||
});
|
||||
|
||||
call.RequestStream.WriteOptions = new WriteOptions(WriteFlags.NoCompress);
|
||||
await call.RequestStream.WriteAsync(new StreamingInputCallRequest
|
||||
{
|
||||
ExpectCompressed = new BoolValue
|
||||
{
|
||||
Value = false
|
||||
},
|
||||
Payload = CreateZerosPayload(45904)
|
||||
});
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
var response = await call.ResponseAsync;
|
||||
Assert.AreEqual(73086, response.AggregatedPayloadSize);
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunServerCompressedUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running server_compressed_unary");
|
||||
|
||||
var request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828),
|
||||
ResponseCompressed = new BoolValue { Value = true }
|
||||
};
|
||||
var response = await client.UnaryCallAsync(request);
|
||||
|
||||
// Compression of response message is not verified because there is no API available
|
||||
Assert.AreEqual(314159, response.Payload.Body.Length);
|
||||
|
||||
request = new SimpleRequest
|
||||
{
|
||||
ResponseSize = 314159,
|
||||
Payload = CreateZerosPayload(271828),
|
||||
ResponseCompressed = new BoolValue { Value = false }
|
||||
};
|
||||
response = await client.UnaryCallAsync(request);
|
||||
|
||||
// Compression of response message is not verified because there is no API available
|
||||
Assert.AreEqual(314159, response.Payload.Body.Length);
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunServerCompressedStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running server_compressed_streaming");
|
||||
|
||||
var bodySizes = new List<int> { 31415, 92653 };
|
||||
|
||||
var request = new StreamingOutputCallRequest
|
||||
{
|
||||
ResponseParameters = { bodySizes.Select((size) => new ResponseParameters { Size = size, Compressed = new BoolValue { Value = true } }) }
|
||||
};
|
||||
|
||||
using (var call = client.StreamingOutputCall(request))
|
||||
{
|
||||
// Compression of response message is not verified because there is no API available
|
||||
var responseList = await call.ResponseStream.ToListAsync();
|
||||
CollectionAssert.AreEqual(bodySizes, responseList.Select((item) => item.Payload.Body.Length).ToList());
|
||||
}
|
||||
|
||||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
private static Payload CreateZerosPayload(int size)
|
||||
{
|
||||
return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
|
||||
}
|
||||
|
||||
private static Metadata CreateClientCompressionMetadata(bool compressed)
|
||||
{
|
||||
var algorithmName = compressed ? "gzip" : "identity";
|
||||
return new Metadata
|
||||
{
|
||||
{ new Metadata.Entry(CompressionRequestAlgorithmMetadataKey, algorithmName) }
|
||||
};
|
||||
}
|
||||
|
||||
// extracts the client_email field from service account file used for auth test cases
|
||||
private static string GetEmailFromServiceAccountFile()
|
||||
{
|
||||
string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS")!;
|
||||
Assert.IsNotNull(keyFile);
|
||||
var jobject = JObject.Parse(File.ReadAllText(keyFile));
|
||||
string email = jobject.GetValue("client_email").Value<string>();
|
||||
Assert.IsTrue(email.Length > 0); // spec requires nonempty client email.
|
||||
return email;
|
||||
}
|
||||
|
||||
private static Metadata CreateTestMetadata()
|
||||
{
|
||||
return new Metadata
|
||||
{
|
||||
{"x-grpc-test-echo-initial", "test_initial_metadata_value"},
|
||||
{"x-grpc-test-echo-trailing-bin", new byte[] {0xab, 0xab, 0xab}}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO(JamesNK): PEM loading logic from https://stackoverflow.com/a/10498045/11829
|
||||
// .NET does not have a built-in API for loading pem files
|
||||
// Consider providing ca file in a different format and removing method
|
||||
private byte[]? GetBytesFromPem(string pemString, string section)
|
||||
{
|
||||
var header = string.Format("-----BEGIN {0}-----", section);
|
||||
var footer = string.Format("-----END {0}-----", section);
|
||||
|
||||
var start = pemString.IndexOf(header, StringComparison.Ordinal);
|
||||
if (start == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
start += header.Length;
|
||||
var end = pemString.IndexOf(footer, start, StringComparison.Ordinal) - start;
|
||||
|
||||
if (end == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Convert.FromBase64String(pemString.Substring(start, end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\grpc\testing\test.proto" GrpcServices="Client" Link="Protos\test.proto" />
|
||||
<Protobuf Include="..\Proto\grpc\testing\empty.proto" GrpcServices="None" Link="Protos\empty.proto" />
|
||||
<Protobuf Include="..\Proto\grpc\testing\messages.proto" GrpcServices="None" Link="Protos\messages.proto" />
|
||||
|
||||
<Reference Include="CommandLineParser" />
|
||||
<Reference Include="Google.Protobuf" />
|
||||
<Reference Include="Grpc.Auth" />
|
||||
<Reference Include="Grpc.Net.Client" />
|
||||
<Reference Include="Grpc.Tools" PrivateAssets="All" />
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<Reference Include="Microsoft.Extensions.Logging.Console" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace InteropTestsClient
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Application started.");
|
||||
|
||||
InteropClient.Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
Param
|
||||
(
|
||||
[bool]$use_tls = $false
|
||||
)
|
||||
|
||||
$allTests =
|
||||
"empty_unary",
|
||||
"large_unary",
|
||||
"client_streaming",
|
||||
"server_streaming",
|
||||
"ping_pong",
|
||||
"empty_stream",
|
||||
|
||||
#"compute_engine_creds",
|
||||
#"jwt_token_creds",
|
||||
#"oauth2_auth_token",
|
||||
#"per_rpc_creds",
|
||||
|
||||
"cancel_after_begin",
|
||||
"cancel_after_first_response",
|
||||
"timeout_on_sleeping_server",
|
||||
"custom_metadata",
|
||||
"status_code_and_message",
|
||||
"special_status_message",
|
||||
"unimplemented_service",
|
||||
"unimplemented_method",
|
||||
"client_compressed_unary",
|
||||
"client_compressed_streaming",
|
||||
"server_compressed_unary",
|
||||
"server_compressed_streaming"
|
||||
|
||||
Write-Host "Running $($allTests.Count) tests" -ForegroundColor Cyan
|
||||
Write-Host "Use TLS: $use_tls" -ForegroundColor Cyan
|
||||
Write-Host
|
||||
|
||||
foreach ($test in $allTests)
|
||||
{
|
||||
Write-Host "Running $test" -ForegroundColor Cyan
|
||||
|
||||
if (!$use_tls)
|
||||
{
|
||||
dotnet run --use_tls false --server_port 50052 --client_type httpclient --test_case $test
|
||||
}
|
||||
else
|
||||
{
|
||||
# Certificate is for test.google.com host. To run locally, setup the host file to point test.google.com to 127.0.0.1
|
||||
dotnet run --use_tls true --server_port 50052 --client_type httpclient --test_case $test --server_host test.google.com
|
||||
}
|
||||
|
||||
Write-Host
|
||||
}
|
||||
|
||||
Write-Host "Done" -ForegroundColor Cyan
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace InteropTestsWebsite
|
||||
{
|
||||
// Implementation copied from https://github.com/grpc/grpc/blob/master/src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs
|
||||
internal static class AsyncStreamExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads the entire stream and executes an async action for each element.
|
||||
/// </summary>
|
||||
public static async Task ForEachAsync<T>(this IAsyncStreamReader<T> streamReader, Func<T, Task> asyncAction)
|
||||
where T : class
|
||||
{
|
||||
while (await streamReader.MoveNext().ConfigureAwait(false))
|
||||
{
|
||||
await asyncAction(streamReader.Current).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<Project>
|
||||
<!-- Skip the parent folder to prevent getting test package references. -->
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\..\, Directory.Build.targets))\Directory.Build.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RestoreAdditionalProjectSources>$(RestoreAdditionalProjectSources);$(ArtifactsShippingPackagesDir)</RestoreAdditionalProjectSources>
|
||||
<MicrosoftAspNetCoreAppRefPackageVersion Condition="'$(IsTargetingPackBuilding)' != 'false'">$(TargetingPackVersion)</MicrosoftAspNetCoreAppRefPackageVersion>
|
||||
<MicrosoftAspNetCoreAppRefPackageVersion Condition="'$(IsTargetingPackBuilding)' == 'false'">$(AspNetCoreBaselineVersion)</MicrosoftAspNetCoreAppRefPackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Use the shared framework that was produced -->
|
||||
<ItemGroup>
|
||||
<KnownFrameworkReference
|
||||
Include="Microsoft.AspNetCore.App"
|
||||
TargetFramework="$(DefaultNetCoreTargetFramework)"
|
||||
RuntimeFrameworkName="Microsoft.AspNetCore.App"
|
||||
TargetingPackName="Microsoft.AspNetCore.App.Ref"
|
||||
RuntimePackNamePatterns="Microsoft.AspNetCore.App.Runtime.**RID**"
|
||||
DefaultRuntimeFrameworkVersion="$(SharedFxVersion)"
|
||||
LatestRuntimeFrameworkVersion="$(SharedFxVersion)"
|
||||
TargetingPackVersion="$(MicrosoftAspNetCoreAppRefPackageVersion)"
|
||||
RuntimePackRuntimeIdentifiers="$(SupportedRuntimeIdentifiers)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
|
||||
<GenerateUserSecretsAttribute>false</GenerateUserSecretsAttribute>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\grpc\testing\test.proto" GrpcServices="Server" Link="Protos\test.proto" />
|
||||
<Protobuf Include="..\Proto\grpc\testing\empty.proto" GrpcServices="None" Link="Protos\empty.proto" />
|
||||
<Protobuf Include="..\Proto\grpc\testing\messages.proto" GrpcServices="None" Link="Protos\messages.proto" />
|
||||
|
||||
<Reference Include="Grpc.AspNetCore" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace InteropTestsWebsite
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.ConfigureKestrel((context, options) =>
|
||||
{
|
||||
// Support --port and --use_tls cmdline arguments normally supported
|
||||
// by gRPC interop servers.
|
||||
var useTls = context.Configuration.GetValue("use_tls", false);
|
||||
|
||||
options.Limits.MinRequestBodyDataRate = null;
|
||||
options.ListenAnyIP(0, listenOptions =>
|
||||
{
|
||||
Console.WriteLine($"Enabling connection encryption: {useTls}");
|
||||
|
||||
if (useTls)
|
||||
{
|
||||
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
||||
var certPath = Path.Combine(basePath!, "Certs", "server1.pfx");
|
||||
|
||||
listenOptions.UseHttps(certPath, "1111");
|
||||
}
|
||||
listenOptions.Protocols = HttpProtocols.Http2;
|
||||
});
|
||||
});
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Grpc.Testing;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace InteropTestsWebsite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddGrpc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicationLifetime)
|
||||
{
|
||||
// Required to notify test infrastructure that it can begin tests
|
||||
applicationLifetime.ApplicationStarted.Register(() => Console.WriteLine("Application started."));
|
||||
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGrpcService<TestServiceImpl>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Protobuf;
|
||||
using Grpc.Core;
|
||||
using InteropTestsWebsite;
|
||||
|
||||
namespace Grpc.Testing
|
||||
{
|
||||
// Implementation copied from https://github.com/grpc/grpc/blob/master/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
|
||||
public class TestServiceImpl : TestService.TestServiceBase
|
||||
{
|
||||
public override Task<Empty> EmptyCall(Empty request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public override async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context, request.ResponseCompressed?.Value ?? false);
|
||||
EnsureEchoStatus(request.ResponseStatus, context);
|
||||
EnsureCompression(request.ExpectCompressed, context);
|
||||
|
||||
var response = new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context, request.ResponseParameters.Any(rp => rp.Compressed?.Value ?? false));
|
||||
EnsureEchoStatus(request.ResponseStatus, context);
|
||||
|
||||
foreach (var responseParam in request.ResponseParameters)
|
||||
{
|
||||
responseStream.WriteOptions = !(responseParam.Compressed?.Value ?? false)
|
||||
? new WriteOptions(WriteFlags.NoCompress)
|
||||
: null;
|
||||
|
||||
var response = new StreamingOutputCallResponse { Payload = CreateZerosPayload(responseParam.Size) };
|
||||
await responseStream.WriteAsync(response);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
|
||||
int sum = 0;
|
||||
await requestStream.ForEachAsync(request =>
|
||||
{
|
||||
EnsureCompression(request.ExpectCompressed, context);
|
||||
|
||||
sum += request.Payload.Body.Length;
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
return new StreamingInputCallResponse { AggregatedPayloadSize = sum };
|
||||
}
|
||||
|
||||
public override async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
|
||||
await requestStream.ForEachAsync(async request =>
|
||||
{
|
||||
EnsureEchoStatus(request.ResponseStatus, context);
|
||||
foreach (var responseParam in request.ResponseParameters)
|
||||
{
|
||||
var response = new StreamingOutputCallResponse { Payload = CreateZerosPayload(responseParam.Size) };
|
||||
await responseStream.WriteAsync(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static Payload CreateZerosPayload(int size)
|
||||
{
|
||||
return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
|
||||
}
|
||||
|
||||
private static async Task EnsureEchoMetadataAsync(ServerCallContext context, bool enableCompression = false)
|
||||
{
|
||||
var echoInitialList = context.RequestHeaders.Where((entry) => entry.Key == "x-grpc-test-echo-initial").ToList();
|
||||
|
||||
// Append grpc internal compression header if compression is requested by the client
|
||||
if (enableCompression)
|
||||
{
|
||||
echoInitialList.Add(new Metadata.Entry("grpc-internal-encoding-request", "gzip"));
|
||||
}
|
||||
|
||||
if (echoInitialList.Any()) {
|
||||
var entry = echoInitialList.Single();
|
||||
await context.WriteResponseHeadersAsync(new Metadata { entry });
|
||||
}
|
||||
|
||||
var echoTrailingList = context.RequestHeaders.Where((entry) => entry.Key == "x-grpc-test-echo-trailing-bin").ToList();
|
||||
if (echoTrailingList.Any()) {
|
||||
context.ResponseTrailers.Add(echoTrailingList.Single());
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureEchoStatus(EchoStatus responseStatus, ServerCallContext context)
|
||||
{
|
||||
if (responseStatus != null)
|
||||
{
|
||||
var statusCode = (StatusCode)responseStatus.Code;
|
||||
context.Status = new Status(statusCode, responseStatus.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureCompression(BoolValue? expectCompressed, ServerCallContext context)
|
||||
{
|
||||
if (expectCompressed != null)
|
||||
{
|
||||
// ServerCallContext.RequestHeaders filters out grpc-* headers
|
||||
// Get grpc-encoding from HttpContext instead
|
||||
var encoding = context.GetHttpContext().Request.Headers.SingleOrDefault(h => h.Key == "grpc-encoding").Value.SingleOrDefault();
|
||||
if (expectCompressed.Value)
|
||||
{
|
||||
if (encoding == null || encoding == "identity")
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.testing;
|
||||
|
||||
// An empty message that you can re-use to avoid defining duplicated empty
|
||||
// messages in your project. A typical example is to use it as argument or the
|
||||
// return value of a service API. For instance:
|
||||
//
|
||||
// service Foo {
|
||||
// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
|
||||
// };
|
||||
//
|
||||
message Empty {}
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
|
||||
// Copyright 2015-2016 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
// Message definitions to be used by integration test service definitions.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.testing;
|
||||
|
||||
// TODO(dgq): Go back to using well-known types once
|
||||
// https://github.com/grpc/grpc/issues/6980 has been fixed.
|
||||
// import "google/protobuf/wrappers.proto";
|
||||
message BoolValue {
|
||||
// The bool value.
|
||||
bool value = 1;
|
||||
}
|
||||
|
||||
// The type of payload that should be returned.
|
||||
enum PayloadType {
|
||||
// Compressable text format.
|
||||
COMPRESSABLE = 0;
|
||||
}
|
||||
|
||||
// A block of data, to simply increase gRPC message size.
|
||||
message Payload {
|
||||
// The type of data in body.
|
||||
PayloadType type = 1;
|
||||
// Primary contents of payload.
|
||||
bytes body = 2;
|
||||
}
|
||||
|
||||
// A protobuf representation for grpc status. This is used by test
|
||||
// clients to specify a status that the server should attempt to return.
|
||||
message EchoStatus {
|
||||
int32 code = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
// Unary request.
|
||||
message SimpleRequest {
|
||||
// Desired payload type in the response from the server.
|
||||
// If response_type is RANDOM, server randomly chooses one from other formats.
|
||||
PayloadType response_type = 1;
|
||||
|
||||
// Desired payload size in the response from the server.
|
||||
int32 response_size = 2;
|
||||
|
||||
// Optional input payload sent along with the request.
|
||||
Payload payload = 3;
|
||||
|
||||
// Whether SimpleResponse should include username.
|
||||
bool fill_username = 4;
|
||||
|
||||
// Whether SimpleResponse should include OAuth scope.
|
||||
bool fill_oauth_scope = 5;
|
||||
|
||||
// Whether to request the server to compress the response. This field is
|
||||
// "nullable" in order to interoperate seamlessly with clients not able to
|
||||
// implement the full compression tests by introspecting the call to verify
|
||||
// the response's compression status.
|
||||
BoolValue response_compressed = 6;
|
||||
|
||||
// Whether server should return a given status
|
||||
EchoStatus response_status = 7;
|
||||
|
||||
// Whether the server should expect this request to be compressed.
|
||||
BoolValue expect_compressed = 8;
|
||||
}
|
||||
|
||||
// Unary response, as configured by the request.
|
||||
message SimpleResponse {
|
||||
// Payload to increase message size.
|
||||
Payload payload = 1;
|
||||
// The user the request came from, for verifying authentication was
|
||||
// successful when the client expected it.
|
||||
string username = 2;
|
||||
// OAuth scope.
|
||||
string oauth_scope = 3;
|
||||
}
|
||||
|
||||
// Client-streaming request.
|
||||
message StreamingInputCallRequest {
|
||||
// Optional input payload sent along with the request.
|
||||
Payload payload = 1;
|
||||
|
||||
// Whether the server should expect this request to be compressed. This field
|
||||
// is "nullable" in order to interoperate seamlessly with servers not able to
|
||||
// implement the full compression tests by introspecting the call to verify
|
||||
// the request's compression status.
|
||||
BoolValue expect_compressed = 2;
|
||||
|
||||
// Not expecting any payload from the response.
|
||||
}
|
||||
|
||||
// Client-streaming response.
|
||||
message StreamingInputCallResponse {
|
||||
// Aggregated size of payloads received from the client.
|
||||
int32 aggregated_payload_size = 1;
|
||||
}
|
||||
|
||||
// Configuration for a particular response.
|
||||
message ResponseParameters {
|
||||
// Desired payload sizes in responses from the server.
|
||||
int32 size = 1;
|
||||
|
||||
// Desired interval between consecutive responses in the response stream in
|
||||
// microseconds.
|
||||
int32 interval_us = 2;
|
||||
|
||||
// Whether to request the server to compress the response. This field is
|
||||
// "nullable" in order to interoperate seamlessly with clients not able to
|
||||
// implement the full compression tests by introspecting the call to verify
|
||||
// the response's compression status.
|
||||
BoolValue compressed = 3;
|
||||
}
|
||||
|
||||
// Server-streaming request.
|
||||
message StreamingOutputCallRequest {
|
||||
// Desired payload type in the response from the server.
|
||||
// If response_type is RANDOM, the payload from each response in the stream
|
||||
// might be of different types. This is to simulate a mixed type of payload
|
||||
// stream.
|
||||
PayloadType response_type = 1;
|
||||
|
||||
// Configuration for each expected response message.
|
||||
repeated ResponseParameters response_parameters = 2;
|
||||
|
||||
// Optional input payload sent along with the request.
|
||||
Payload payload = 3;
|
||||
|
||||
// Whether server should return a given status
|
||||
EchoStatus response_status = 7;
|
||||
}
|
||||
|
||||
// Server-streaming response, as configured by the request and parameters.
|
||||
message StreamingOutputCallResponse {
|
||||
// Payload to increase response size.
|
||||
Payload payload = 1;
|
||||
}
|
||||
|
||||
// For reconnect interop test only.
|
||||
// Client tells server what reconnection parameters it used.
|
||||
message ReconnectParams {
|
||||
int32 max_reconnect_backoff_ms = 1;
|
||||
}
|
||||
|
||||
// For reconnect interop test only.
|
||||
// Server tells client whether its reconnects are following the spec and the
|
||||
// reconnect backoffs it saw.
|
||||
message ReconnectInfo {
|
||||
bool passed = 1;
|
||||
repeated int32 backoff_ms = 2;
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
|
||||
// Copyright 2015-2016 gRPC authors.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
// An integration test service that covers all the method signature permutations
|
||||
// of unary/streaming requests/responses.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
import "empty.proto";
|
||||
import "messages.proto";
|
||||
|
||||
package grpc.testing;
|
||||
|
||||
// A simple service to test the various types of RPCs and experiment with
|
||||
// performance with various types of payload.
|
||||
service TestService {
|
||||
// One empty request followed by one empty response.
|
||||
rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
|
||||
|
||||
// One request followed by one response.
|
||||
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
|
||||
|
||||
// One request followed by one response. Response has cache control
|
||||
// headers set such that a caching HTTP proxy (such as GFE) can
|
||||
// satisfy subsequent requests.
|
||||
rpc CacheableUnaryCall(SimpleRequest) returns (SimpleResponse);
|
||||
|
||||
// One request followed by a sequence of responses (streamed download).
|
||||
// The server returns the payload with client desired type and sizes.
|
||||
rpc StreamingOutputCall(StreamingOutputCallRequest)
|
||||
returns (stream StreamingOutputCallResponse);
|
||||
|
||||
// A sequence of requests followed by one response (streamed upload).
|
||||
// The server returns the aggregated size of client payload as the result.
|
||||
rpc StreamingInputCall(stream StreamingInputCallRequest)
|
||||
returns (StreamingInputCallResponse);
|
||||
|
||||
// A sequence of requests with each request served by the server immediately.
|
||||
// As one request could lead to multiple responses, this interface
|
||||
// demonstrates the idea of full duplexing.
|
||||
rpc FullDuplexCall(stream StreamingOutputCallRequest)
|
||||
returns (stream StreamingOutputCallResponse);
|
||||
|
||||
// A sequence of requests followed by a sequence of responses.
|
||||
// The server buffers all the client requests and then serves them in order. A
|
||||
// stream of responses are returned to the client when the server starts with
|
||||
// first request.
|
||||
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
|
||||
returns (stream StreamingOutputCallResponse);
|
||||
|
||||
// The test server will not implement this method. It will be used
|
||||
// to test the behavior when clients call unimplemented methods.
|
||||
rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty);
|
||||
}
|
||||
|
||||
// A simple service NOT implemented at servers so clients can test for
|
||||
// that case.
|
||||
service UnimplementedService {
|
||||
// A call that no server should implement
|
||||
rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty);
|
||||
}
|
||||
|
||||
// A service used to control reconnect server.
|
||||
service ReconnectService {
|
||||
rpc Start(grpc.testing.ReconnectParams) returns (grpc.testing.Empty);
|
||||
rpc Stop(grpc.testing.Empty) returns (grpc.testing.ReconnectInfo);
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
InteropTestsClient and InteropTestsWebsite are copied from [grpc-dotnet](https://github.com/grpc/grpc-dotnet/tree/master/testassets).
|
||||
|
||||
For more information about the interop tests, see the [interop tests specification](https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md).
|
||||
|
|
@ -11,7 +11,6 @@ using System.Threading.Tasks;
|
|||
using AngleSharp.Dom.Html;
|
||||
using AngleSharp.Parser.Html;
|
||||
using Microsoft.AspNetCore.Certificates.Generation;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
|
||||
namespace Templates.Test.Helpers
|
||||
{
|
||||
internal static class ErrorMessages
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.Extensions.Internal;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Internal
|
||||
namespace Templates.Test.Helpers
|
||||
{
|
||||
internal class ProcessEx : IDisposable
|
||||
{
|
||||
|
|
@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Internal
|
|||
}
|
||||
|
||||
startInfo.EnvironmentVariables["NUGET_PACKAGES"] = NUGET_PACKAGES;
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("helix")))
|
||||
{
|
||||
startInfo.EnvironmentVariables["NUGET_FALLBACK_PACKAGES"] = Environment.GetEnvironmentVariable("NUGET_FALLBACK_PACKAGES");
|
||||
|
|
@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private static string GetNugetPackagesRestorePath() => (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NUGET_RESTORE")))
|
||||
private static string GetNugetPackagesRestorePath() => (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NUGET_RESTORE")))
|
||||
? typeof(ProcessEx).Assembly
|
||||
.GetCustomAttributes<AssemblyMetadataAttribute>()
|
||||
.First(attribute => attribute.Key == "TestPackageRestorePath")
|
||||
|
|
@ -10,7 +10,6 @@ using System.Reflection;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using System.Linq;
|
|||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using System.Net.Http;
|
|||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenQA.Selenium;
|
||||
using Templates.Test.Helpers;
|
||||
|
|
|
|||
Loading…
Reference in New Issue