diff --git a/TESTING.md b/TESTING.md index 86f499889fc4..229e05b07e48 100644 --- a/TESTING.md +++ b/TESTING.md @@ -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.) diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/AcceptanceTest.cs b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/AcceptanceTest.cs new file mode 100644 index 000000000000..c49a5006781b --- /dev/null +++ b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/AcceptanceTest.cs @@ -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 +{ + /// + /// Miscellaneous acceptance tests for the Compute API. + /// + [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(() => 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; + } + } +} diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/ComputeFixture.cs b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/ComputeFixture.cs new file mode 100644 index 000000000000..6eb1de40e1e0 --- /dev/null +++ b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/ComputeFixture.cs @@ -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 + { + // 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"; + + /// + /// Region to use for testing. + /// + public string Region { get; } + + public ComputeFixture() + { + Region = Environment.GetEnvironmentVariable(TestRegionEnvironmentVariable); + if (string.IsNullOrEmpty(Region)) + { + throw new InvalidOperationException($"Environment variable {TestRegionEnvironmentVariable} must be set"); + } + } + } +} diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/Google.Cloud.Compute.V1.IntegrationTests.csproj b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/Google.Cloud.Compute.V1.IntegrationTests.csproj new file mode 100644 index 000000000000..781ce4a56779 --- /dev/null +++ b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/Google.Cloud.Compute.V1.IntegrationTests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.1;net461 + netcoreapp2.1 + false + 1701;1702;1705;xUnit2004;xUnit2013;AD0001 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/TranscodingTest.cs b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/TranscodingTest.cs new file mode 100644 index 000000000000..dabe61cd8465 --- /dev/null +++ b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/TranscodingTest.cs @@ -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 +{ + /// + /// Integration tests focused on the GRPC Transcoding + /// + [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); + } + } +} diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/coverage.xml b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/coverage.xml new file mode 100644 index 000000000000..7a35bdd8a88a --- /dev/null +++ b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.IntegrationTests/coverage.xml @@ -0,0 +1,18 @@ + + + C:/Program Files/dotnet/dotnet.exe + test --no-build -c Release + + + + Google.Cloud.Compute.V1 + + + + + System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute + System.Diagnostics.DebuggerNonUserCodeAttribute + + . + ../../../coverage/Google.Cloud.Compute.V1.IntegrationTests.dvcr + \ No newline at end of file diff --git a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.sln b/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.sln index 7118d180a70c..f3f90ffadd87 100644 --- a/apis/Google.Cloud.Compute.V1/Google.Cloud.Compute.V1.sln +++ b/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 @@ -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 @@ -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