From 3a8a150f59dc48df11fbb5c0f0dce51fa4f48241 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 26 May 2021 14:16:13 -0700 Subject: [PATCH 01/10] workspace properties --- .../JobManagement/IWorkspace.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs b/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs index e2ac5921114..24507b51cb5 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs @@ -13,6 +13,26 @@ namespace Microsoft.Azure.Quantum /// public interface IWorkspace { + /// + /// The Workspace's Azure Subscription. + /// + string SubscriptionId { get; } + + /// + /// The Workspace's resource group in Azure. + /// + string ResourceGroupName { get; } + + /// + /// The Workspace's location (region) in Azure. + /// + string Location { get; } + + /// + /// The Workspace's name. + /// + string WorkspaceName { get; } + /// /// Submits the job. /// From 04ed40cdd3143a2be0d9424fc1eed64c23ccb35b Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 26 May 2021 20:26:32 -0700 Subject: [PATCH 02/10] Adding ProviderStatus to IWorkspace --- .../WorkspaceTest.cs | 25 ++++++++++++ .../JobManagement/IWorkspace.cs | 28 +++++++++---- .../JobManagement/ProviderStatusInfo.cs | 39 +++++++++++++++++++ .../JobManagement/QuotaInfo.cs | 6 +-- .../JobManagement/Workspace.cs | 30 +++++++++++++- 5 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs diff --git a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs index ecb5a84ed93..2e3706a86d2 100644 --- a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs +++ b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs @@ -135,6 +135,31 @@ public async Task ListQuotasTest() Assert.AreEqual(0, max); } + [TestMethod] + public async Task ListProviderStatusTest() + { + IWorkspace workspace = GetLiveWorkspace(); + int max = 1; + + // Since this is a live workspace, we don't have much control about what quotas are in there + // Just make sure there is more than one. + await foreach (var s in workspace.ListProvidersStatusAsync()) + { + Assert.IsNotNull(s); + Assert.IsNotNull(s.Status); + Assert.IsNotNull(s.Status.Id); + + max--; + if (max <= 0) + { + break; + } + } + + // Make sure we iterated through all the expected jobs: + Assert.AreEqual(0, max); + } + private static void AssertJob(CloudJob job) { Assert.IsNotNull(job); diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs b/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs index 24507b51cb5..739e9dc087c 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/IWorkspace.cs @@ -1,13 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Quantum.Runtime; - namespace Microsoft.Azure.Quantum { + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + + using global::Azure.Quantum.Jobs; + /// /// IWorkspace interface. /// @@ -33,6 +34,11 @@ public interface IWorkspace /// string WorkspaceName { get; } + /// + /// The low-level client used to communicate with the service. + /// + public QuantumJobClient Client { get; } + /// /// Submits the job. /// @@ -67,7 +73,7 @@ Task GetJobAsync( /// Lists the jobs. /// /// The cancellation token. - /// List of jobs + /// List of jobs. IAsyncEnumerable ListJobsAsync( CancellationToken cancellationToken = default); @@ -75,10 +81,18 @@ IAsyncEnumerable ListJobsAsync( /// Returns the list of quotas for a workspace. /// /// The cancellation token. - /// List of jobs + /// List of quotas. IAsyncEnumerable ListQuotasAsync( CancellationToken cancellationToken = default); + /// + /// Returns a list with the status of each of the Providers in a workspace + /// + /// The cancellation token. + /// List of provider status. + IAsyncEnumerable ListProvidersStatusAsync( + CancellationToken cancellationToken = default); + /// /// Gets as SAS Uri for the storage account associated with the workspace. /// diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs new file mode 100644 index 00000000000..5897b290675 --- /dev/null +++ b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Azure.Quantum +{ + using Microsoft.Azure.Quantum.Utility; + + using Models = global::Azure.Quantum.Jobs.Models; + + /// + /// Wrapper for Azure.Quantum.Jobs.Models.ProviderStatus. + /// + public class ProviderStatusInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The workspace. + /// The provider status details. + public ProviderStatusInfo(IWorkspace workspace, Models.ProviderStatus status) + { + Ensure.NotNull(workspace, nameof(workspace)); + Ensure.NotNull(status, nameof(status)); + + Workspace = workspace; + Status = status; + } + + /// + /// Gets the workspace. + /// + public virtual IWorkspace Workspace { get; private set; } + + /// + /// Gets the provider status information. + /// + public virtual Models.ProviderStatus Status { get; private set; } + } +} diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs index 6906963b65a..a2c978e1624 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs @@ -8,7 +8,7 @@ namespace Microsoft.Azure.Quantum using Microsoft.Azure.Quantum.Utility; /// - /// Wrapper for Microsoft.Azure.Quantum.Client.Models.Quota. + /// Wrapper for Azure.Quantum.Jobs.Models.QuantumJobQuota. /// public class QuotaInfo { @@ -29,11 +29,11 @@ public QuotaInfo(IWorkspace workspace, QuantumJobQuota quota) /// /// Gets the workspace. /// - public IWorkspace Workspace { get; private set; } + public virtual IWorkspace Workspace { get; private set; } /// /// Gets the quota information. /// - public QuantumJobQuota Quota { get; private set; } + public virtual QuantumJobQuota Quota { get; private set; } } } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs b/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs index 2b269a945a8..a1588e23cec 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs @@ -48,7 +48,17 @@ public Workspace( Ensure.NotNullOrWhiteSpace(location, nameof(location)); // Optional parameters: - credential ??= new DefaultAzureCredential(includeInteractiveCredentials: true); + if (credential == null) + { + // We have to disable VisualStudio, see: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1332071 + var credOptions = new DefaultAzureCredentialOptions() + { + ExcludeVisualStudioCredential = true, + }; + + credential = new DefaultAzureCredential(credOptions); + } + options ??= new QuantumJobClientOptions(); this.ResourceGroupName = resourceGroupName; @@ -194,6 +204,24 @@ public async IAsyncEnumerable ListQuotasAsync([EnumeratorCancellation } } + + /// + /// Lists the quotas. + /// + /// The cancellation token. + /// + /// List of quotas. + /// + public async IAsyncEnumerable ListProvidersStatusAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) + { + var status = this.Client.GetProviderStatusAsync(cancellationToken); + + await foreach (var s in status) + { + yield return new ProviderStatusInfo(this, s); + } + } + /// /// Gets as SAS Uri for the linked storage account. /// From cc3ac6893f81772e36a6a25736b05fd7bd508240 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 26 May 2021 20:29:26 -0700 Subject: [PATCH 03/10] ignore live tests --- src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs index 2e3706a86d2..f177380b153 100644 --- a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs +++ b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs @@ -136,6 +136,7 @@ public async Task ListQuotasTest() } [TestMethod] + [Ignore] public async Task ListProviderStatusTest() { IWorkspace workspace = GetLiveWorkspace(); From 68aac8e3c9f6430a1655f7377330a6aab7beff55 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 26 May 2021 22:28:07 -0700 Subject: [PATCH 04/10] improve mockability --- .../WorkspaceTest.cs | 10 ++-- .../JobManagement/CloudJob.cs | 2 +- .../JobManagement/ProviderStatusInfo.cs | 32 +++++++++-- .../JobManagement/QuotaInfo.cs | 42 ++++++++++++++- .../JobManagement/TargetStatusInfo.cs | 54 +++++++++++++++++++ 5 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs diff --git a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs index f177380b153..a581e4bf7eb 100644 --- a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs +++ b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; @@ -121,8 +122,8 @@ public async Task ListQuotasTest() await foreach (var q in workspace.ListQuotasAsync()) { Assert.IsNotNull(q); - Assert.IsNotNull(q.Quota); - Assert.IsNotNull(q.Quota.Dimension); + Assert.IsNotNull(q.ProviderId); + Assert.IsNotNull(q.Dimension); max--; if (max <= 0) @@ -147,8 +148,9 @@ public async Task ListProviderStatusTest() await foreach (var s in workspace.ListProvidersStatusAsync()) { Assert.IsNotNull(s); - Assert.IsNotNull(s.Status); - Assert.IsNotNull(s.Status.Id); + Assert.IsNotNull(s.ProviderId); + Assert.IsNotNull(s.Targets); + Assert.IsTrue(s.Targets.Any()); max--; if (max <= 0) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs index 34d7360b81b..1dba163abef 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs @@ -70,7 +70,7 @@ public CloudJob(IWorkspace workspace, JobDetails jobDetails) public virtual IWorkspace Workspace { get; private set; } /// - /// Gets the job details. + /// Gets the underlying job details. /// public virtual JobDetails Details { get; private set; } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs index 5897b290675..96353d4c053 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs @@ -3,6 +3,8 @@ namespace Microsoft.Azure.Quantum { + using System.Collections.Generic; + using Microsoft.Azure.Quantum.Utility; using Models = global::Azure.Quantum.Jobs.Models; @@ -23,17 +25,41 @@ public ProviderStatusInfo(IWorkspace workspace, Models.ProviderStatus status) Ensure.NotNull(status, nameof(status)); Workspace = workspace; - Status = status; + Details = status; } /// /// Gets the workspace. /// - public virtual IWorkspace Workspace { get; private set; } + public virtual IWorkspace Workspace { get; } + + /// + /// Provider id. + /// + public virtual string ProviderId => this.Details.Id; + + /// + /// Provider availability. + /// + public virtual Models.ProviderAvailability? CurrentAvailability => this.Details.CurrentAvailability; + + /// + /// List of all available targets for this provider. + /// + public virtual IEnumerable Targets + { + get + { + foreach (var ps in this.Details.Targets) + { + yield return new TargetStatusInfo(ps); + } + } + } /// /// Gets the provider status information. /// - public virtual Models.ProviderStatus Status { get; private set; } + protected Models.ProviderStatus Details { get; private set; } } } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs index a2c978e1624..6039c036531 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs @@ -23,7 +23,7 @@ public QuotaInfo(IWorkspace workspace, QuantumJobQuota quota) Ensure.NotNull(quota, nameof(quota)); Workspace = workspace; - Quota = quota; + Details = quota; } /// @@ -31,9 +31,47 @@ public QuotaInfo(IWorkspace workspace, QuantumJobQuota quota) /// public virtual IWorkspace Workspace { get; private set; } + + /// + /// The name of the dimension associated with the quota. + /// + public virtual string Dimension => Details.Dimension; + + /// + /// The scope at which the quota is applied. + /// + public virtual DimensionScope? Scope => Details.Scope; + + /// + /// The unique identifier for the provider. + /// + public virtual string ProviderId => Details.ProviderId; + + /// + /// The amount of the usage that has been applied for the current period. + /// + public virtual float? Utilization => Details.Utilization; + + /// + /// The amount of the usage that has been reserved but not applied for the current + /// period. + /// + public virtual float? Holds => Details.Holds; + + /// + /// The maximum amount of usage allowed for the current period. + /// + public virtual float? Limit => Details.Limit; + + /// + /// The time period in which the quota's underlying meter is accumulated. Based on + /// calendar year. 'None' is used for concurrent quotas. + /// + public virtual MeterPeriod? Period => Details.Period; + /// /// Gets the quota information. /// - public virtual QuantumJobQuota Quota { get; private set; } + protected QuantumJobQuota Details { get; private set; } } } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs new file mode 100644 index 00000000000..090140e708b --- /dev/null +++ b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Azure.Quantum +{ + using System.Collections.Generic; + + using Microsoft.Azure.Quantum.Utility; + + using Models = global::Azure.Quantum.Jobs.Models; + + /// + /// Wrapper for Azure.Quantum.Jobs.Models.ProviderStatus. + /// + public class TargetStatusInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The workspace. + /// The provider status details. + public TargetStatusInfo(Models.TargetStatus status) + { + Ensure.NotNull(status, nameof(status)); + + Details = status; + } + + /// + /// Target id. + /// + public virtual string TargetId => Details.Id; + + /// + /// Target availability. + /// + public virtual Models.TargetAvailability? CurrentAvailability => Details.CurrentAvailability; + + /// + /// Average queue time in seconds. + /// + public virtual long? AverageQueueTime => Details.AverageQueueTime; + + /// + /// A page with detailed status of the provider. + /// + public virtual string StatusPage => Details.StatusPage; + + /// + /// Gets the provider status information. + /// + protected Models.TargetStatus Details { get; private set; } + } +} From fbce925eb68e3b6d9a3baeccd025d3948d43869a Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 2 Jun 2021 11:36:36 -0700 Subject: [PATCH 05/10] stylecop --- .../Azure.Quantum.Client/JobManagement/QuotaInfo.cs | 1 - .../Azure.Quantum.Client/JobManagement/Workspace.cs | 9 ++++----- .../JobManagement/WorkspaceExtensions.cs | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs index 6039c036531..d167e388cfd 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs @@ -31,7 +31,6 @@ public QuotaInfo(IWorkspace workspace, QuantumJobQuota quota) /// public virtual IWorkspace Workspace { get; private set; } - /// /// The name of the dimension associated with the quota. /// diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs b/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs index a1588e23cec..b8eb8349377 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs @@ -50,7 +50,7 @@ public Workspace( // Optional parameters: if (credential == null) { - // We have to disable VisualStudio, see: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1332071 + // We have to disable VisualStudio until 16.11 goes out, see: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1332071 var credOptions = new DefaultAzureCredentialOptions() { ExcludeVisualStudioCredential = true, @@ -101,12 +101,12 @@ public async Task SubmitJobAsync( CancellationToken cancellationToken = default) { Ensure.NotNull(jobDefinition, nameof(jobDefinition)); - Ensure.NotNullOrWhiteSpace(jobDefinition.Details.Id, nameof(jobDefinition.Details.Id)); + Ensure.NotNullOrWhiteSpace(jobDefinition.Id, nameof(jobDefinition.Id)); try { JobDetails jobDetails = await this.Client.CreateJobAsync( - jobId: jobDefinition.Details.Id, + jobId: jobDefinition.Id, job: jobDefinition.Details, cancellationToken: cancellationToken); @@ -114,7 +114,7 @@ public async Task SubmitJobAsync( } catch (Exception ex) { - throw CreateException(ex, "Could not submit job", jobDefinition.Details.Id); + throw CreateException(ex, "Could not submit job", jobDefinition.Id); } } @@ -204,7 +204,6 @@ public async IAsyncEnumerable ListQuotasAsync([EnumeratorCancellation } } - /// /// Lists the quotas. /// diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/WorkspaceExtensions.cs b/src/Azure/Azure.Quantum.Client/JobManagement/WorkspaceExtensions.cs index d220d2560d0..3e49c020285 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/WorkspaceExtensions.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/WorkspaceExtensions.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Collections.Generic; - namespace Microsoft.Azure.Quantum { /// From eb27dd806f3f1ffed6b941679d4fcdad80d0ec33 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 2 Jun 2021 12:13:40 -0700 Subject: [PATCH 06/10] parameter-less constructors --- .../Helpers/Problem.cs | 4 +-- .../JobManagement/ProviderStatusInfo.cs | 27 +++++++++++++----- .../JobManagement/QuotaInfo.cs | 28 +++++++++++++------ .../JobManagement/TargetStatusInfo.cs | 20 +++++++++---- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs b/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs index 5a527dc9c6e..e01b346721f 100644 --- a/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs +++ b/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs @@ -54,12 +54,12 @@ public void Add(int i, float c) public void Add(int i, int j, float c) { - terms.Add(new Term( new int[] { i, j }, c)); + terms.Add(new Term(new int[] { i, j }, c)); } public void Add(int i, int j, int k, float c) { - terms.Add(new Term( new int[] { i, j, k }, c)); + terms.Add(new Term(new int[] { i, j, k }, c)); } public void AddRange(IEnumerable collection) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs index 96353d4c053..222f496c5de 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/ProviderStatusInfo.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#nullable enable + namespace Microsoft.Azure.Quantum { using System.Collections.Generic; @@ -28,31 +30,42 @@ public ProviderStatusInfo(IWorkspace workspace, Models.ProviderStatus status) Details = status; } + /// + /// Initializes a new instance of the class. + /// Use only for testing. + /// + protected ProviderStatusInfo() + { + } + /// /// Gets the workspace. /// - public virtual IWorkspace Workspace { get; } + public virtual IWorkspace? Workspace { get; } /// /// Provider id. /// - public virtual string ProviderId => this.Details.Id; + public virtual string? ProviderId => this.Details?.Id; /// /// Provider availability. /// - public virtual Models.ProviderAvailability? CurrentAvailability => this.Details.CurrentAvailability; + public virtual Models.ProviderAvailability? CurrentAvailability => this.Details?.CurrentAvailability; /// /// List of all available targets for this provider. /// - public virtual IEnumerable Targets + public virtual IEnumerable? Targets { get { - foreach (var ps in this.Details.Targets) + if (this.Details != null) { - yield return new TargetStatusInfo(ps); + foreach (var ps in this.Details.Targets) + { + yield return new TargetStatusInfo(ps); + } } } } @@ -60,6 +73,6 @@ public virtual IEnumerable Targets /// /// Gets the provider status information. /// - protected Models.ProviderStatus Details { get; private set; } + protected Models.ProviderStatus? Details { get; private set; } } } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs index d167e388cfd..a36ca7ca7ee 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/QuotaInfo.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#nullable enable + namespace Microsoft.Azure.Quantum { using global::Azure.Quantum.Jobs.Models; @@ -26,51 +28,59 @@ public QuotaInfo(IWorkspace workspace, QuantumJobQuota quota) Details = quota; } + /// + /// Initializes a new instance of the class. + /// Use only for testing. + /// + protected QuotaInfo() + { + } + /// /// Gets the workspace. /// - public virtual IWorkspace Workspace { get; private set; } + public virtual IWorkspace? Workspace { get; private set; } /// /// The name of the dimension associated with the quota. /// - public virtual string Dimension => Details.Dimension; + public virtual string? Dimension => Details?.Dimension; /// /// The scope at which the quota is applied. /// - public virtual DimensionScope? Scope => Details.Scope; + public virtual DimensionScope? Scope => Details?.Scope; /// /// The unique identifier for the provider. /// - public virtual string ProviderId => Details.ProviderId; + public virtual string? ProviderId => Details?.ProviderId; /// /// The amount of the usage that has been applied for the current period. /// - public virtual float? Utilization => Details.Utilization; + public virtual float? Utilization => Details?.Utilization; /// /// The amount of the usage that has been reserved but not applied for the current /// period. /// - public virtual float? Holds => Details.Holds; + public virtual float? Holds => Details?.Holds; /// /// The maximum amount of usage allowed for the current period. /// - public virtual float? Limit => Details.Limit; + public virtual float? Limit => Details?.Limit; /// /// The time period in which the quota's underlying meter is accumulated. Based on /// calendar year. 'None' is used for concurrent quotas. /// - public virtual MeterPeriod? Period => Details.Period; + public virtual MeterPeriod? Period => Details?.Period; /// /// Gets the quota information. /// - protected QuantumJobQuota Details { get; private set; } + protected QuantumJobQuota? Details { get; private set; } } } diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs index 090140e708b..4194a10a269 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#nullable enable + namespace Microsoft.Azure.Quantum { using System.Collections.Generic; @@ -26,29 +28,37 @@ public TargetStatusInfo(Models.TargetStatus status) Details = status; } + /// + /// Initializes a new instance of the class. + /// Use only for testing. + /// + protected TargetStatusInfo() + { + } + /// /// Target id. /// - public virtual string TargetId => Details.Id; + public virtual string? TargetId => Details?.Id; /// /// Target availability. /// - public virtual Models.TargetAvailability? CurrentAvailability => Details.CurrentAvailability; + public virtual Models.TargetAvailability? CurrentAvailability => Details?.CurrentAvailability; /// /// Average queue time in seconds. /// - public virtual long? AverageQueueTime => Details.AverageQueueTime; + public virtual long? AverageQueueTime => Details?.AverageQueueTime; /// /// A page with detailed status of the provider. /// - public virtual string StatusPage => Details.StatusPage; + public virtual string? StatusPage => Details?.StatusPage; /// /// Gets the provider status information. /// - protected Models.TargetStatus Details { get; private set; } + protected Models.TargetStatus? Details { get; private set; } } } From 772b5bc3fd568b6c08a3783216ae83a3c5628249 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 2 Jun 2021 12:40:03 -0700 Subject: [PATCH 07/10] Enable live tests based on env variables. --- .../Helpers/Problem.cs | 5 ++- .../Helpers/TestConstants.cs | 15 ------- .../WorkspaceTest.cs | 40 ++++++++++++++----- 3 files changed, 34 insertions(+), 26 deletions(-) delete mode 100644 src/Azure/Azure.Quantum.Client.Test/Helpers/TestConstants.cs diff --git a/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs b/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs index e01b346721f..2fcd64c1dec 100644 --- a/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs +++ b/src/Azure/Azure.Quantum.Client.Test/Helpers/Problem.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; using System.IO; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/src/Azure/Azure.Quantum.Client.Test/Helpers/TestConstants.cs b/src/Azure/Azure.Quantum.Client.Test/Helpers/TestConstants.cs deleted file mode 100644 index d9007003394..00000000000 --- a/src/Azure/Azure.Quantum.Client.Test/Helpers/TestConstants.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.Azure.Quantum.Test -{ - public static class TestConstants - { - // Used when connecting live - public const string LiveSubscriptionId = "916dfd6d-030c-4bd9-b579-7bb6d1926e97"; - public const string LiveLocation = "westus2"; - public const string LiveResourceGroupName = "e2e-scenarios"; - public const string LiveStorageAccount = "e2etests"; - public const string LiveWorkspaceName = "e2e-qsharp-tests"; - } -} diff --git a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs index a581e4bf7eb..bb5fb81f7ba 100644 --- a/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs +++ b/src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs @@ -22,8 +22,20 @@ namespace Microsoft.Azure.Quantum.Test [TestClass] public class WorkspaceTest { + private const string SETUP = @" +Live tests require you to configure your environment with these variables: + * E2E_WORKSPACE_NAME: the name of an Azure Quantum workspace to use for live testing. + * E2E_SUBSCRIPTION_ID: the Azure Quantum workspace's Subscription Id. + * E2E_WORKSPACE_RG: the Azure Quantum workspace's resource group. + * E2E_WORKSPACE_LOCATION: the Azure Quantum workspace's location (region). + +You'll also need to authenticate with Azure using any of the methods listed in: +https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme#authenticate-the-client + +Tests will be marked as Inconclusive if the pre-reqs are not correctly setup."; + [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task SubmitJobTest() { // Create Job @@ -42,7 +54,7 @@ public async Task SubmitJobTest() } [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task GetJobTest() { IWorkspace workspace = GetLiveWorkspace(); @@ -62,7 +74,7 @@ public async Task GetJobTest() } [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task CancelJobTest() { // Create Job @@ -83,7 +95,7 @@ public async Task CancelJobTest() } [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task ListJobsTest() { IWorkspace workspace = GetLiveWorkspace(); @@ -111,7 +123,7 @@ public async Task ListJobsTest() } [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task ListQuotasTest() { IWorkspace workspace = GetLiveWorkspace(); @@ -137,7 +149,7 @@ public async Task ListQuotasTest() } [TestMethod] - [Ignore] + [TestCategory("Live")] public async Task ListProviderStatusTest() { IWorkspace workspace = GetLiveWorkspace(); @@ -174,14 +186,22 @@ private static void AssertJob(CloudJob job) private IWorkspace GetLiveWorkspace() { + if (string.IsNullOrWhiteSpace(System.Environment.GetEnvironmentVariable("E2E_SUBSCRIPTION_ID")) || + string.IsNullOrWhiteSpace(System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_RG")) || + string.IsNullOrWhiteSpace(System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_NAME")) || + string.IsNullOrWhiteSpace(System.Environment.GetEnvironmentVariable("E2E_SUBSCRIPTION_ID"))) + { + Assert.Inconclusive(SETUP); + } + var options = new QuantumJobClientOptions(); options.Diagnostics.ApplicationId = "ClientTests"; return new Workspace( - subscriptionId: System.Environment.GetEnvironmentVariable("E2E_SUBSCRIPTION_ID") ?? TestConstants.LiveSubscriptionId, - resourceGroupName: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_RG") ?? TestConstants.LiveResourceGroupName, - workspaceName: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_NAME") ?? TestConstants.LiveWorkspaceName, - location: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_LOCATION") ?? TestConstants.LiveLocation, + subscriptionId: System.Environment.GetEnvironmentVariable("E2E_SUBSCRIPTION_ID"), + resourceGroupName: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_RG"), + workspaceName: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_NAME"), + location: System.Environment.GetEnvironmentVariable("E2E_WORKSPACE_LOCATION"), options: options); } From 4350c67e9a017c50a32643163846c54cab82e1e7 Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 4 Jun 2021 23:30:48 +0000 Subject: [PATCH 08/10] Build 0.17.2106.145735. --- global.json | 2 +- .../Microsoft.Quantum.Development.Kit.nuspec | 2 +- .../CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj | 2 +- src/Xunit/Microsoft.Quantum.Xunit.nuspec | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/global.json b/global.json index da2e1177aa6..703a5dae1e1 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "msbuild-sdks": { - "Microsoft.Quantum.Sdk": "0.16.2105143425-alpha" + "Microsoft.Quantum.Sdk": "0.17.2106145735-alpha" } } diff --git a/src/Quantum.Development.Kit/Microsoft.Quantum.Development.Kit.nuspec b/src/Quantum.Development.Kit/Microsoft.Quantum.Development.Kit.nuspec index b3f2dc492ef..2b2a6cd0a2b 100644 --- a/src/Quantum.Development.Kit/Microsoft.Quantum.Development.Kit.nuspec +++ b/src/Quantum.Development.Kit/Microsoft.Quantum.Development.Kit.nuspec @@ -20,7 +20,7 @@ Quantum Q# QSharp - + diff --git a/src/Simulation/CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj b/src/Simulation/CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj index dba0c6256c8..f1838ea1cb4 100644 --- a/src/Simulation/CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj +++ b/src/Simulation/CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj @@ -22,7 +22,7 @@ - + diff --git a/src/Xunit/Microsoft.Quantum.Xunit.nuspec b/src/Xunit/Microsoft.Quantum.Xunit.nuspec index 2de3f2c585f..053332e1ef4 100644 --- a/src/Xunit/Microsoft.Quantum.Xunit.nuspec +++ b/src/Xunit/Microsoft.Quantum.Xunit.nuspec @@ -22,7 +22,7 @@ - + From ca5a74d2ee539c0f7ee816b823ae9f83cf4138eb Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Mon, 7 Jun 2021 15:03:12 -0700 Subject: [PATCH 09/10] OutputData fields --- .../Azure.Quantum.Client/JobManagement/CloudJob.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs index 1dba163abef..49983d07987 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs @@ -69,6 +69,18 @@ public CloudJob(IWorkspace workspace, JobDetails jobDetails) /// public virtual IWorkspace Workspace { get; private set; } + /// + /// If available, returns Uri with the results of the execution. + /// + public virtual Uri OutputDataUri => (this.Details?.OutputDataUri != null) + ? new Uri(this.Details.OutputDataUri) + : null; + + /// + /// If available, returns the data format of the execution results. + /// + public virtual string OutputDataFormat => this.Details?.OutputDataFormat; + /// /// Gets the underlying job details. /// From 7f13f0eb7f62debae019253283124bbd7d967bdb Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Mon, 7 Jun 2021 21:09:38 -0700 Subject: [PATCH 10/10] CloudJob fields++ --- .../JobManagement/CloudJob.cs | 17 ++++++++++++++++- .../JobManagement/TargetStatusInfo.cs | 2 -- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs index 49983d07987..05c92de3e0b 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/CloudJob.cs @@ -42,6 +42,11 @@ public CloudJob(IWorkspace workspace, JobDetails jobDetails) /// public virtual string Id => Details.Id; + /// + /// Gets the job id. + /// + public virtual string Name => Details.Name; + /// /// Gets whether the job execution has completed. /// @@ -70,8 +75,18 @@ public CloudJob(IWorkspace workspace, JobDetails jobDetails) public virtual IWorkspace Workspace { get; private set; } /// - /// If available, returns Uri with the results of the execution. + /// Gets or sets the unique identifier for the provider. /// + public virtual string ProviderId => this.Details?.ProviderId; + + /// + /// Gets or sets the target identifier to run the job. + /// + public string Target => this.Details.Target; + + /// + /// If available, returns Uri with the results of the execution. + /// > public virtual Uri OutputDataUri => (this.Details?.OutputDataUri != null) ? new Uri(this.Details.OutputDataUri) : null; diff --git a/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs index 4194a10a269..98afab13a36 100644 --- a/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs +++ b/src/Azure/Azure.Quantum.Client/JobManagement/TargetStatusInfo.cs @@ -5,8 +5,6 @@ namespace Microsoft.Azure.Quantum { - using System.Collections.Generic; - using Microsoft.Azure.Quantum.Utility; using Models = global::Azure.Quantum.Jobs.Models;