Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion src/Azure/Azure.Quantum.Client.Test/WorkspaceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

using Azure.Identity;
using Azure.Quantum;
using Azure.Quantum.Jobs;
using Azure.Quantum.Jobs.Models;

using Microsoft.Azure.Quantum.Exceptions;
Expand Down Expand Up @@ -176,6 +178,100 @@ public async Task ListProviderStatusTest()
Assert.AreEqual(0, max);
}

[TestMethod]
[TestCategory("Local")]
public async Task ApplicationIdTest()
{
const string ENV_VAR_APPID = "EnvVarAppId";
const string OPTIONS_APPID = "OptionAppId";
const string LONG_ENV_VAR_APPID = "LongEnvVarAppId";
const string LONG_OPTIONS_APPID = "LongOptionAppId";
const string VERY_LONG_ENV_VAR_APPID = "VeryVeryVeryVeryVeryVeryLongEnvVarAppId";
const string VERY_LONG_OPTIONS_APPID = "VeryVeryVeryVeryVeryVeryLongOptionAppId";
const string APPID_ENV_VAR_NAME = "AZURE_QUANTUM_NET_APPID";

Func<QuantumJobClientOptions, Workspace> createWorkspace = (QuantumJobClientOptions options) =>
{
var credential = new ClientSecretCredential(tenantId: "72f988bf-86f1-41af-91ab-2d7cd011db47",
clientId: "00000000-0000-0000-0000-000000000000",
clientSecret: "PLACEHOLDER");
return new Workspace(subscriptionId: "SubscriptionId",
resourceGroupName: "ResourceGroupName",
workspaceName: "WorkspaceName",
location: "WestUs",
options: options,
credential: credential);
};

var originalEnvironmentAppId = Environment.GetEnvironmentVariable(APPID_ENV_VAR_NAME);
try
{

// Test with no Environment AppId and no Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, null);
var workspace = createWorkspace(null);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
Assert.AreEqual("", workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with Environment AppId and no Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, ENV_VAR_APPID);
workspace = createWorkspace(null);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
Assert.AreEqual(ENV_VAR_APPID, workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with no Environment AppId and with Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, null);
var options = new QuantumJobClientOptions();
options.Diagnostics.ApplicationId = OPTIONS_APPID;
workspace = createWorkspace(options);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
Assert.AreEqual(OPTIONS_APPID, workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with Environment AppId and with Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, ENV_VAR_APPID);
options = new QuantumJobClientOptions();
options.Diagnostics.ApplicationId = OPTIONS_APPID;
workspace = createWorkspace(options);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
Assert.AreEqual($"{OPTIONS_APPID}-{ENV_VAR_APPID}", workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with long (>24 chars) combination of Environment AppId and Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, LONG_ENV_VAR_APPID);
options = new QuantumJobClientOptions();
options.Diagnostics.ApplicationId = LONG_OPTIONS_APPID;
workspace = createWorkspace(options);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
var truncatedAppId = $"{LONG_OPTIONS_APPID}-{LONG_ENV_VAR_APPID}".Substring(0, 24);
Assert.AreEqual(truncatedAppId, workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with long (>24 chars) Environment AppId and no Options AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, VERY_LONG_ENV_VAR_APPID);
workspace = createWorkspace(null);
Assert.IsNotNull(workspace.ClientOptions);
Assert.IsNotNull(workspace.ClientOptions.Diagnostics);
Assert.AreEqual(VERY_LONG_ENV_VAR_APPID.Substring(0, 24), workspace.ClientOptions.Diagnostics.ApplicationId);

// Test with long (>24 chars) Options AppId and no Environment AppId
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, null);
options = new QuantumJobClientOptions();
Assert.ThrowsException<System.ArgumentOutOfRangeException>(() =>
options.Diagnostics.ApplicationId = VERY_LONG_OPTIONS_APPID);
}
finally
{
// restore original env var AZURE_QUANTUM_NET_APPID
if (originalEnvironmentAppId != null)
{
Environment.SetEnvironmentVariable(APPID_ENV_VAR_NAME, originalEnvironmentAppId);
}
}
}

private static void AssertJob(CloudJob job)
{
Assert.IsNotNull(job);
Expand Down
38 changes: 33 additions & 5 deletions src/Azure/Azure.Quantum.Client/JobManagement/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Microsoft.Azure.Quantum
using System.Threading;
using System.Threading.Tasks;
using global::Azure.Core;
using global::Azure.Identity;
using global::Azure.Quantum;
using global::Azure.Quantum.Jobs;
using global::Azure.Quantum.Jobs.Models;
Expand Down Expand Up @@ -50,9 +49,10 @@ public Workspace(

// Optional parameters:
credential ??= CredentialFactory.CreateCredential(CredentialType.Default, subscriptionId);
options ??= new QuantumJobClientOptions();
options.Diagnostics.ApplicationId = options.Diagnostics.ApplicationId
?? Environment.GetEnvironmentVariable("AZURE_QUANTUM_NET_APPID");

// Make sure use the property Setter as we have some logic
// tto apply here
this.ClientOptions = options;

this.ResourceGroupName = resourceGroupName;
this.WorkspaceName = workspaceName;
Expand All @@ -65,7 +65,7 @@ public Workspace(
workspaceName,
location,
credential,
options);
this.ClientOptions);
}

public string ResourceGroupName { get; }
Expand All @@ -81,6 +81,34 @@ public Workspace(
/// </summary>
public QuantumJobClient Client { get; }

/// <summary>
/// The options used to create the client to communicate with the service.
/// </summary>
public QuantumJobClientOptions ClientOptions
{
get => this.clientOptions;
set
{
// Set the ApplicationId that will be added as a UserAgent prefix
// in calls to the Azure Quantum API.
var applicationId = string.Join('-',
value?.Diagnostics?.ApplicationId?.Trim(),
Environment.GetEnvironmentVariable("AZURE_QUANTUM_NET_APPID")?.Trim()
)?.Trim('-', ' ');
if (applicationId?.Length > 24)
{
applicationId = applicationId?.Substring(0, 24);
}

value ??= new QuantumJobClientOptions();
value.Diagnostics.ApplicationId = applicationId;

this.clientOptions = value;
}
}

private QuantumJobClientOptions clientOptions;

/// <summary>
/// Submits the job.
/// </summary>
Expand Down
11 changes: 5 additions & 6 deletions src/Simulation/EntryPointDriver.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ let ``Submit allows overriding default values`` () =

https://www.example.com/00000000-0000-0000-0000-0000000000000"


[<Fact>]
let ``Submit allows a long user-agent`` () =
let given = test "Returns Unit"
Expand All @@ -661,7 +661,7 @@ let ``Submit allows a long user-agent`` () =
"--shots"
"750"
"--user-agent"
"a-very-long-user-agent-(it-will-be-truncated)"
"a-very-long-user-agent-(it-will-be-not-be-truncated-here)"
"--credential"
"cli"
])
Expand All @@ -674,18 +674,17 @@ let ``Submit allows a long user-agent`` () =
Location: myLocation
Credential: CLI
AadToken: myTok
UserAgent: a-very-long-user-agent-(
UserAgent: a-very-long-user-agent-(it-will-be-not-be-truncated-here)
Job Name: myJobName
Job Parameters:
Shots: 750
Output: FriendlyUri
Dry Run: False
Verbose: True

Submitting Q# entry point using a quantum machine.

https://www.example.com/00000000-0000-0000-0000-0000000000000"



[<Fact>]
let ``Submit extracts the location from a quantum endpoint`` () =
let given = test "Returns Unit"
Expand Down
23 changes: 12 additions & 11 deletions src/Simulation/EntryPointDriver/Azure/AzureSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,20 @@ internal TokenCredential CreateCredentials()
}
}

internal string? TrimmedUserAgent() {
var userAgent = (UserAgent ?? System.Environment.GetEnvironmentVariable("USER_AGENT"))?.Trim();

return (userAgent == null || userAgent.Length < 25)
? userAgent
: userAgent.Substring(0, 24);
}


internal QuantumJobClientOptions CreateClientOptions()
{
var options = new QuantumJobClientOptions();
options.Diagnostics.ApplicationId = TrimmedUserAgent();

// This value will be added as a prefix in the UserAgent when
// calling the Azure Quantum API
// It cannot be larger than 24 characters.
var applicationId = string.Join('@', "Q#Run", UserAgent?.Trim()).Trim(' ', '@');
if (applicationId?.Length > 24)
{
applicationId = applicationId.Substring(0, 24);
}

options.Diagnostics.ApplicationId = applicationId;
return options;
}

Expand Down Expand Up @@ -187,7 +188,7 @@ public override string ToString() => string.Join(
$"Location: {Location ?? ExtractLocation(BaseUri)}",
$"Credential: {Credential}",
$"AadToken: {AadToken?.Substring(0, 5)}",
$"UserAgent: {TrimmedUserAgent()}",
$"UserAgent: {UserAgent}",
$"Job Name: {JobName}",
$"Job Parameters: {string.Join(", ", JobParams.OrderBy(item => item.Key))}",
$"Shots: {Shots}",
Expand Down