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
+
+ .
+
+
\ 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