Skip to content

Commit

Permalink
Add integration tests for Google.Cloud.Compute.V1
Browse files Browse the repository at this point in the history
  • Loading branch information
jskeet committed Apr 21, 2021
1 parent d2a2bf4 commit 9561883
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 9 deletions.
7 changes: 7 additions & 0 deletions TESTING.md
Expand Up @@ -214,3 +214,10 @@ To configure the project (in terms of permissions), visit the
[AutoML Vision console](https://cloud.google.com/automl/ui/vision/),
type in your project ID, click "Continue", and then click "Set up
now" on the next page.

Google.Cloud.Compute.V1
-----------------------

The `TEST_PROJECT_LOCATION` environment variable must be set to a
region, e.g. `us-west1`. (The value used for AppEngine testing
should be fine for Compute as well.)
@@ -0,0 +1,125 @@
// Copyright 2021 Google LLC
//
// 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
//
// https://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.

using System;
using System.Threading;
using Grpc.Core;
using Xunit;
using Xunit.Abstractions;

namespace Google.Cloud.Compute.V1.IntegrationTests
{
/// <summary>
/// Miscellaneous acceptance tests for the Compute API.
/// </summary>
[Collection(nameof(ComputeFixture))]
public sealed class AcceptanceTest
{
private readonly ITestOutputHelper _output;
private readonly ComputeFixture _fixture;

public AcceptanceTest(ComputeFixture fixture, ITestOutputHelper output) =>
(_fixture, _output) = (fixture, output);

[Fact]
public void CreateDeleteIPAddress()
{
string projectId = _fixture.ProjectId;
string region = _fixture.Region;

AddressesClient addressesClient = AddressesClient.Create();
var addressName = $"testaddr-csharp-{Guid.NewGuid()}";

FetchNonExistentAddress();
CreateAddress();
FetchNewAddress();
DeleteAddress();

void FetchNonExistentAddress()
{
_output.WriteLine($"Retrieving address with the name: {addressName}");
var exc = Assert.Throws<RpcException>(() => addressesClient.Get(projectId, region, addressName));
Assert.Equal(StatusCode.NotFound, exc.StatusCode);
}

void CreateAddress()
{
_output.WriteLine($"Creating address with the name: {addressName}");
Address addressResource = new Address
{
Name = addressName,
Region = region,
NetworkTier = Address.Types.NetworkTier.Premium
};

Operation insertOperation = addressesClient.Insert(projectId, region, addressResource);
_output.WriteLine($"Operation to create address: {insertOperation.Name} status {insertOperation.Status}; start time {insertOperation.StartTime}");
insertOperation = PollForCompletion(insertOperation, "create");
_output.WriteLine($"Operation to create address completed: status {insertOperation.Status}; start time {insertOperation.StartTime}; end time {insertOperation.EndTime}");
}

void FetchNewAddress()
{
_output.WriteLine($"Retrieving address with the name: {addressName}");
Address readAddr = addressesClient.Get(projectId, region, addressName);
Assert.NotNull(readAddr);
Assert.Equal(readAddr.Name, addressName);
}

void DeleteAddress()
{
_output.WriteLine($"Deleting address with the name: {addressName}");
Operation deleteOp = addressesClient.Delete(projectId, region, addressName);
_output.WriteLine($"Operation to delete address: {deleteOp.Name} status {deleteOp.Status}; start time {deleteOp.StartTime}");
deleteOp = PollForCompletion(deleteOp, "delete");
_output.WriteLine($"Operation to delete address completed: status {deleteOp.Status}; start time {deleteOp.StartTime}; end time {deleteOp.EndTime}");
}
}

private Operation PollForCompletion(Operation operation, string alias)
{
RegionOperationsClient regionOperationsClient = RegionOperationsClient.Create();

TimeSpan timeOut = TimeSpan.FromMinutes(3);
TimeSpan pollInterval = TimeSpan.FromSeconds(15);

DateTime deadline = DateTime.UtcNow + timeOut;
while (operation.Status != Operation.Types.Status.Done)
{
GetRegionOperationRequest request = new GetRegionOperationRequest
{
Operation = operation.Name,
Region = _fixture.Region,
Project = _fixture.ProjectId,
};
_output.WriteLine($"Checking for {alias} operation status ...");
operation = regionOperationsClient.Get(request);

if (operation.Status == Operation.Types.Status.Done)
{
break;
}
if (DateTime.UtcNow > deadline)
{
throw new InvalidOperationException(
$"Timeout hit while polling for the status of the {alias} operation\n{operation}");
}
_output.WriteLine($"Status: {operation.Status}. Sleeping for the {pollInterval.TotalSeconds}s");
Thread.Sleep(pollInterval);
}

return operation;
}
}
}
@@ -0,0 +1,43 @@
// Copyright 2021 Google LLC
//
// 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
//
// https://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.

using Google.Cloud.ClientTesting;
using System;
using Xunit;

namespace Google.Cloud.Compute.V1.IntegrationTests
{
[CollectionDefinition(nameof(ComputeFixture))]
public class ComputeFixture : CloudProjectFixtureBase, ICollectionFixture<ComputeFixture>
{
// Note: this would more naturally be called COMPUTE_TEST_REGION, but this
// environment variable already exists for App Engine testing, so it's handy to
// avoid requiring another one.
private const string TestRegionEnvironmentVariable = "TEST_PROJECT_LOCATION";

/// <summary>
/// Region to use for testing.
/// </summary>
public string Region { get; }

public ComputeFixture()
{
Region = Environment.GetEnvironmentVariable(TestRegionEnvironmentVariable);
if (string.IsNullOrEmpty(Region))
{
throw new InvalidOperationException($"Environment variable {TestRegionEnvironmentVariable} must be set");
}
}
}
}
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
<TestTargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.1</TestTargetFrameworks>
<IsPackable>false</IsPackable>
<NoWarn>1701;1702;1705;xUnit2004;xUnit2013;AD0001</NoWarn>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\tools\Google.Cloud.ClientTesting\Google.Cloud.ClientTesting.csproj" />
<ProjectReference Include="..\Google.Cloud.Compute.V1\Google.Cloud.Compute.V1.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Moq" Version="4.12.0" />
<PackageReference Include="System.Linq.Async" Version="4.0.0" />
<PackageReference Include="Xunit.SkippableFact" Version="1.3.12" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<Analyzer Condition="Exists('..\..\..\tools\Google.Cloud.Tools.Analyzers\bin\$(Configuration)\netstandard1.3\publish\Google.Cloud.Tools.Analyzers.dll')" Include="..\..\..\tools\Google.Cloud.Tools.Analyzers\bin\$(Configuration)\netstandard1.3\publish\Google.Cloud.Tools.Analyzers.dll" />
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
</Project>
@@ -0,0 +1,40 @@
// Copyright 2021 Google LLC
//
// 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
//
// https://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.

using Xunit;

namespace Google.Cloud.Compute.V1.IntegrationTests
{
/// <summary>
/// Integration tests focused on the GRPC Transcoding
/// </summary>
[Collection(nameof(ComputeFixture))]
public sealed class TranscodingTest
{
private readonly ComputeFixture _fixture;

public TranscodingTest(ComputeFixture fixture) => _fixture = fixture;

[Fact]
public void ListZones_MaxResults()
{
var client = ZonesClient.Create();
var allZones = client.List(_fixture.ProjectId);
Assert.InRange(allZones.Items.Count, 3, int.MaxValue);

var twoZones = client.List(new ListZonesRequest { Project = _fixture.ProjectId, MaxResults = 2 });
Assert.Equal(2, twoZones.Items.Count);
}
}
}
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<CoverageParams>
<TargetExecutable>C:/Program Files/dotnet/dotnet.exe</TargetExecutable>
<TargetArguments>test --no-build -c Release</TargetArguments>
<Filters>
<IncludeFilters>
<FilterEntry>
<ModuleMask>Google.Cloud.Compute.V1</ModuleMask>
</FilterEntry>
</IncludeFilters>
</Filters>
<AttributeFilters>
<AttributeFilterEntry>System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute</AttributeFilterEntry>
<AttributeFilterEntry>System.Diagnostics.DebuggerNonUserCodeAttribute</AttributeFilterEntry>
</AttributeFilters>
<TargetWorkingDir>.</TargetWorkingDir>
<Output>../../../coverage/Google.Cloud.Compute.V1.IntegrationTests.dvcr</Output>
</CoverageParams>
35 changes: 26 additions & 9 deletions apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.sln
@@ -1,15 +1,17 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
# Visual Studio Version 16
VisualStudioVersion = 16.0.31205.134
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Cloud.Compute.V1", "Google.Cloud.Compute.V1\Google.Cloud.Compute.V1.csproj", "{AA705DCA-FAD1-4D45-BF12-FFED6E07DB91}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Cloud.Compute.V1", "Google.Cloud.Compute.V1\Google.Cloud.Compute.V1.csproj", "{AA705DCA-FAD1-4D45-BF12-FFED6E07DB91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Cloud.Compute.V1.Snippets", "Google.Cloud.Compute.V1.Snippets\Google.Cloud.Compute.V1.Snippets.csproj", "{E42EF5AF-0E0F-40E1-AC7B-58A360700AEB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Cloud.Compute.V1.Snippets", "Google.Cloud.Compute.V1.Snippets\Google.Cloud.Compute.V1.Snippets.csproj", "{E42EF5AF-0E0F-40E1-AC7B-58A360700AEB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Cloud.ClientTesting", "..\..\tools\Google.Cloud.ClientTesting\Google.Cloud.ClientTesting.csproj", "{756BC412-834F-42DF-9D1C-9B4FFEAA993E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Cloud.ClientTesting", "..\..\tools\Google.Cloud.ClientTesting\Google.Cloud.ClientTesting.csproj", "{756BC412-834F-42DF-9D1C-9B4FFEAA993E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Cloud.Compute.V1.Tests", "Google.Cloud.Compute.V1.Tests\Google.Cloud.Compute.V1.Tests.csproj", "{8B297C1A-12A9-462F-A1B2-2681114B1C76}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Cloud.Compute.V1.Tests", "Google.Cloud.Compute.V1.Tests\Google.Cloud.Compute.V1.Tests.csproj", "{8B297C1A-12A9-462F-A1B2-2681114B1C76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Cloud.Compute.V1.IntegrationTests", "Google.Cloud.Compute.V1.IntegrationTests\Google.Cloud.Compute.V1.IntegrationTests.csproj", "{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -20,9 +22,6 @@ Global
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA705DCA-FAD1-4D45-BF12-FFED6E07DB91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA705DCA-FAD1-4D45-BF12-FFED6E07DB91}.Debug|Any CPU.Build.0 = Debug|Any CPU
Expand Down Expand Up @@ -72,5 +71,23 @@ Global
{8B297C1A-12A9-462F-A1B2-2681114B1C76}.Release|x64.Build.0 = Release|Any CPU
{8B297C1A-12A9-462F-A1B2-2681114B1C76}.Release|x86.ActiveCfg = Release|Any CPU
{8B297C1A-12A9-462F-A1B2-2681114B1C76}.Release|x86.Build.0 = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|x64.ActiveCfg = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|x64.Build.0 = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|x86.ActiveCfg = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Debug|x86.Build.0 = Debug|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|Any CPU.Build.0 = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|x64.ActiveCfg = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|x64.Build.0 = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|x86.ActiveCfg = Release|Any CPU
{96C6DBED-B6FF-4868-8DC7-18D8BA39C6E9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {34A4205A-3908-43B3-BF66-BEE1C697B641}
EndGlobalSection
EndGlobal

0 comments on commit 9561883

Please sign in to comment.