diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 6b63385a2d59..0b249a97d15f 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1033,12 +1033,12 @@ packages: dev: false resolution: integrity: sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== - /@types/yargs/15.0.13: + /@types/yargs/15.0.12: dependencies: '@types/yargs-parser': 20.2.0 dev: false resolution: - integrity: sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + integrity: sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== /@types/yauzl/2.9.1: dependencies: '@types/node': 8.10.66 @@ -9102,14 +9102,12 @@ packages: '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.3.4_rollup@1.32.1 '@types/chai': 4.2.14 - '@types/chai-as-promised': 7.1.3 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 '@types/sinon': 9.0.10 assert: 1.5.0 chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9148,7 +9146,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-2T3z2w3gA8WLmpZNCAXxQPEkyE3yiO6cOBHKt/UEXwCris9pvqpkfbMcEmkaX+gWwiNt0ptXJlnysziiiB7Auw== + integrity: sha512-FBv4UmvUcBH10v1TQRJfbHSFUUn+nrnjceC4jClIpp2QrEUbN5YXKuI9uOU2J1RYXLWY4CaV2rSWd20b3xVw4g== tarball: file:projects/keyvault-keys.tgz version: 0.0.0 file:projects/keyvault-secrets.tgz: @@ -9292,16 +9290,14 @@ packages: '@microsoft/api-extractor': 7.7.11 '@opentelemetry/api': 0.10.2 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 - '@rollup/plugin-inject': 4.0.2_rollup@1.32.1 '@rollup/plugin-json': 4.1.0_rollup@1.32.1 '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.3.4_rollup@1.32.1 '@types/chai': 4.2.14 '@types/mocha': 7.0.2 - '@types/node': 8.10.66 + '@types/node': 10.17.51 '@types/sinon': 9.0.10 - assert: 1.5.0 chai: 4.2.0 cross-env: 7.0.3 dotenv: 8.2.0 @@ -9314,24 +9310,23 @@ packages: karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.3.0 karma-ie-launcher: 1.0.0_karma@5.2.3 + karma-json-preprocessor: 0.3.3_karma@5.2.3 + karma-json-to-file-reporter: 1.0.1 karma-junit-reporter: 2.0.1_karma@5.2.3 karma-mocha: 2.0.1 karma-mocha-reporter: 2.2.5_karma@5.2.3 karma-sourcemap-loader: 0.3.8 - mkdirp: 1.0.4 mocha: 7.2.0 mocha-junit-reporter: 1.23.3_mocha@7.2.0 - nock: 12.0.3 nyc: 14.1.1 prettier: 1.19.1 rimraf: 3.0.2 rollup: 1.32.1 - rollup-plugin-node-resolve: 3.4.0 rollup-plugin-shim: 1.0.0 rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 rollup-plugin-terser: 5.3.1_rollup@1.32.1 + rollup-plugin-visualizer: 4.2.0_rollup@1.32.1 sinon: 9.2.4 - ts-node: 8.10.2_typescript@4.1.2 tslib: 2.1.0 typedoc: 0.15.2 typescript: 4.1.2 @@ -9339,7 +9334,7 @@ packages: dev: false name: '@rush-temp/quantum-jobs' resolution: - integrity: sha512-00vl//xwFuYdKIqG8/vHsECkbahLvLCITRKScPmxl8PrQ+5YssXH5IsbWBAKu4gndla+eGr/OajfqBInqNvp+Q== + integrity: sha512-XPouSBvla9KRgRxU/dQ/8mJ+L5B+rLucQvMFp0BahqpAHFMmZ625YWEMThQ9GuNhoOQvNC5hpIuiQV+CSON4tQ== tarball: file:projects/quantum-jobs.tgz version: 0.0.0 file:projects/schema-registry-avro.tgz: @@ -9575,7 +9570,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-b8OV32wgLusNRZu6kmj7oWTYA+TvRxcYd6UHZX9Z1QTOUueIrZEVzGLqU2/+kTptItqxIyj0vyalKBIIODwvcA== + integrity: sha512-WzR4R9h7IwmBSij3j7ToynpbAFvjcHMt669AvyVEaTLYqbWXjx1zK+kfOO8t/S5ZVhYBBdNj4U1PDt8UWBfj3Q== tarball: file:projects/service-bus.tgz version: 0.0.0 file:projects/storage-blob-changefeed.tgz: @@ -10170,7 +10165,7 @@ packages: '@azure/event-hubs': 2.1.4 '@types/node': 8.10.66 '@types/uuid': 8.3.0 - '@types/yargs': 15.0.13 + '@types/yargs': 15.0.12 async-lock: 1.2.8 death: 1.1.0 debug: 4.3.1 diff --git a/sdk/quantum/ci.yml b/sdk/quantum/ci.yml new file mode 100644 index 000000000000..36b65d6742d5 --- /dev/null +++ b/sdk/quantum/ci.yml @@ -0,0 +1,32 @@ +# DO NOT EDIT THIS FILE +# This file is generated automatically and any changes will be lost. + +trigger: + branches: + include: + - master + - release/* + - hotfix/* + paths: + include: + - sdk/quantum/ + - eng/common/ + +pr: + branches: + include: + - master + - feature/* + - release/* + - hotfix/* + paths: + include: + - sdk/quantum/ + +extends: + template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: quantum + Artifacts: + - name: azure-quantum-jobs + safeName: quantumjobs diff --git a/sdk/quantum/quantum-jobs/CHANGELOG.md b/sdk/quantum/quantum-jobs/CHANGELOG.md new file mode 100644 index 000000000000..0bfa3acc7919 --- /dev/null +++ b/sdk/quantum/quantum-jobs/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 1.0.0-beta.1 (2021-02-05) + +Initial public preview of the @azure/quantum-jobs library. diff --git a/sdk/quantum/quantum-jobs/generate.ps1 b/sdk/quantum/quantum-jobs/generate.ps1 new file mode 100644 index 000000000000..2cdd300bfe28 --- /dev/null +++ b/sdk/quantum/quantum-jobs/generate.ps1 @@ -0,0 +1,2 @@ +autorest --version=3.0.6335 --typescript --use=@autorest/modelerfour@4.15.452 swagger\README.md +rushx build diff --git a/sdk/quantum/quantum-jobs/karma.conf.js b/sdk/quantum/quantum-jobs/karma.conf.js index ca3a84a4f2c8..98bbcbd85277 100644 --- a/sdk/quantum/quantum-jobs/karma.conf.js +++ b/sdk/quantum/quantum-jobs/karma.conf.js @@ -1,6 +1,12 @@ // https://github.com/karma-runner/karma-chrome-launcher process.env.CHROME_BIN = require("puppeteer").executablePath(); require("dotenv").config(); +const { + jsonRecordingFilterFunction, + isPlaybackMode, + isSoftRecordMode, + isRecordMode +} = require("@azure/test-utils-recorder"); module.exports = function(config) { config.set({ @@ -21,7 +27,9 @@ module.exports = function(config) { "karma-env-preprocessor", "karma-coverage", "karma-sourcemap-loader", - "karma-junit-reporter" + "karma-junit-reporter", + "karma-json-to-file-reporter", + "karma-json-preprocessor" ], // list of files / patterns to load in the browser @@ -29,9 +37,9 @@ module.exports = function(config) { // polyfill service supporting IE11 missing features // Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys "https://cdn.polyfill.io/v2/polyfill.js?features=Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys|always", - "test-browser/index.js", - { pattern: "test-browser/index.js.map", type: "html", included: false, served: true } - ], + "dist-test/index.browser.js", + { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true } + ].concat(isPlaybackMode() || isSoftRecordMode() ? ["recordings/browsers/**/*.json"] : []), // list of files / patterns to exclude exclude: [], @@ -39,10 +47,11 @@ module.exports = function(config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - "**/*.js": ["env"] + "**/*.js": ["sourcemap", "env"], // IMPORTANT: COMMENT following line if you want to debug in your browsers!! // Preprocess source file to calculate code coverage, however this will make source file unreadable - // "test-browser/index.js": ["coverage"] + // "dist-test/index.browser.js": ["coverage"], + "recordings/browsers/**/*.json": ["json"] }, // inject following environment values into browser testing with window.__env__ @@ -52,13 +61,16 @@ module.exports = function(config) { "AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_TENANT_ID", + "SUBSCRIPTION_ID", + "RESOURCE_GROUP", + "WORKSPACE_NAME", "TEST_MODE" ], // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], + reporters: ["mocha", "coverage", "junit", "json-to-file"], coverageReporter: { // specify a common output directory @@ -81,6 +93,12 @@ module.exports = function(config) { properties: {} // key value pair of properties to add to the section of the report }, + jsonToFileReporter: { + // required - to save the recordings of browser tests + filter: jsonRecordingFilterFunction, + outputPath: "." + }, + // web server port port: 9876, @@ -97,11 +115,12 @@ module.exports = function(config) { // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' + // --no-sandbox allows our tests to run in Linux without having to change the system. browsers: ["ChromeHeadlessNoSandbox"], customLaunchers: { ChromeHeadlessNoSandbox: { base: "ChromeHeadless", - flags: ["--no-sandbox"] + flags: ["--no-sandbox", "--disable-web-security"] } }, @@ -116,6 +135,9 @@ module.exports = function(config) { browserNoActivityTimeout: 600000, browserDisconnectTimeout: 10000, browserDisconnectTolerance: 3, + browserConsoleLogOptions: { + terminal: !isRecordMode() + }, client: { mocha: { diff --git a/sdk/quantum/quantum-jobs/package.json b/sdk/quantum/quantum-jobs/package.json index d71cb33a4828..d170ba31d177 100644 --- a/sdk/quantum/quantum-jobs/package.json +++ b/sdk/quantum/quantum-jobs/package.json @@ -1,49 +1,96 @@ { "name": "@azure/quantum-jobs", - "author": "Microsoft Corporation", - "description": "Azure Quantum REST API client", "version": "1.0.0-beta.1", - "dependencies": { - "@azure/core-paging": "^1.1.1", - "@azure/core-http": "^1.2.0", - "tslib": "^2.0.0", - "@opentelemetry/api": "^0.10.2" + "description": "An isomorphic client library for Azure Quantum", + "sdk-type": "client", + "author": "Microsoft Corporation", + "license": "MIT", + "main": "dist/index.js", + "module": "dist-esm/src/index.js", + "types": "./types/latest/quantum-jobs.d.ts", + "engines": { + "node": ">=8.0.0" }, + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", + "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run extract-api", + "build": "npm run build:node && npm run build:browser", + "build:test:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c rollup.test.config.js 2>&1", + "build:test:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c rollup.test.config.js 2>&1", + "build:test": "npm run build:test:node && npm run build:test:browser", + "build:samples": "echo Skipped.", + "check-format": "prettier --list-different --config ../../.prettierrc.json --ignore-path ../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf dist dist-esm dist-browser test-dist test-browser types *.tgz *.log", + "coverage": "nyc --reporter=lcov --exclude-after-remap=false mocha -t 120000 dist-test/index.node.js --reporter ../../../common/tools/mocha-multi-reporter.js", + "execute:js-samples": "node ../../../common/scripts/run-samples.js samples/javascript/", + "execute:samples": "npm run build:samples && dev-tool samples run dist-samples/javascript dist-samples/typescript/dist/dist-samples/typescript/src/", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write --config ../../.prettierrc.json --ignore-path ../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace dist-esm/test/*.spec.js dist-esm/test/**/*.spec.js --harmony", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts -f html -o search-lintReport.html || exit 0", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "test:node": "npm run clean && npm run build:test:node && npm run unit-test:node", + "test:browser": "npm run clean && npm run build:test:browser && npm run unit-test:browser", + "test": "npm run clean && npm run build:test && npm run unit-test", + "unit-test:browser": "echo skipped", + "unit-test:node": "mocha --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace dist-test/index.node.js --harmony", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src" + }, + "files": [ + "dist/", + "dist-esm/src/", + "types/latest/quantum-jobs.d.ts", + "README.md", + "LICENSE.txt" + ], "keywords": [ - "node", "azure", + "quantum", + "cloud", + "node", "typescript", "browser", - "isomorphic", - "cloud" + "isomorphic" ], - "license": "MIT", - "main": "dist/index.js", - "module": "./dist-esm/src/index.js", - "types": "./types/latest/quantum-jobs.d.ts", + "repository": "github:Azure/azure-sdk-for-js", + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/quantum/quantum-jobs/", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "dependencies": { + "@azure/core-paging": "^1.1.1", + "@azure/core-http": "^1.2.0", + "@opentelemetry/api": "^0.10.2", + "tslib": "^2.0.0" + }, "devDependencies": { - "rollup-plugin-node-resolve": "^3.4.0", - "mkdirp": "^1.0.4", + "@azure/storage-blob": "^12.4.1", "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure/identity": "^1.1.0", "@azure/test-utils-recorder": "^1.0.0", "@microsoft/api-extractor": "7.7.11", "@rollup/plugin-commonjs": "11.0.2", - "@rollup/plugin-inject": "^4.0.0", "@rollup/plugin-json": "^4.0.0", "@rollup/plugin-multi-entry": "^3.0.0", "@rollup/plugin-node-resolve": "^8.0.0", "@rollup/plugin-replace": "^2.2.0", "@types/chai": "^4.1.6", "@types/mocha": "^7.0.2", - "@types/node": "^8.0.0", + "@types/node": "^10.0.0", "@types/sinon": "^9.0.4", - "assert": "^1.4.1", "chai": "^4.2.0", + "cross-env": "^7.0.2", "dotenv": "^8.2.0", "eslint": "^7.15.0", - "esm": "^3.2.18", + "events": "^3.0.0", + "inherits": "^2.0.3", "karma": "^5.1.0", "karma-chrome-launcher": "^3.0.0", "karma-coverage": "^2.0.0", @@ -51,13 +98,14 @@ "karma-env-preprocessor": "^0.1.1", "karma-firefox-launcher": "^1.1.0", "karma-ie-launcher": "^1.0.0", + "karma-json-preprocessor": "^0.3.3", + "karma-json-to-file-reporter": "^1.0.1", "karma-junit-reporter": "^2.0.1", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", "karma-sourcemap-loader": "^0.3.8", "mocha": "^7.1.1", "mocha-junit-reporter": "^1.18.0", - "nock": "^12.0.3", "nyc": "^14.0.0", "prettier": "^1.16.4", "rimraf": "^3.0.0", @@ -65,52 +113,11 @@ "rollup-plugin-shim": "^1.0.0", "rollup-plugin-sourcemaps": "^0.4.2", "rollup-plugin-terser": "^5.1.1", + "rollup-plugin-visualizer": "^4.0.4", "sinon": "^9.0.2", - "ts-node": "^8.3.0", "typescript": "4.1.2", - "uglify-js": "^3.4.9", - "cross-env": "^7.0.2", + "util": "^0.12.1", "typedoc": "0.15.2" }, - "homepage": "https://github.com/Azure/azure-sdk-for-js", - "repository": "github:Azure/azure-sdk-for-js", - "bugs": { - "url": "https://github.com/Azure/azure-sdk-for-js/issues" - }, - "files": [ - "dist/", - "dist-esm/src/", - "README.md", - "types/latest/quantum-jobs.d.ts", - "LICENSE.txt" - ], - "scripts": { - "build": "npm run build:node && npm run build:browser", - "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run extract-api", - "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", - "build:test": "npm run build:test:node && npm run build:test:browser", - "build:test:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c rollup.test.config.js 2>&1", - "build:test:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c rollup.test.config.js 2>&1", - "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-esm dist-browser test-dist test-browser types *.tgz *.log", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix", - "lint": "eslint package.json api-extractor.json src test --ext .ts -f html -o quantum-jobs-lintReport.html || exit 0", - "prebuild": "npm run clean", - "pack": "npm pack 2>&1", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "integration-test:browser": "karma start --single-run", - "integration-test:node": "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace dist-esm/test/*.spec.js dist-esm/test/**/*.spec.js", - "test:browser": "npm run clean && npm run build:test:browser && npm run unit-test:browser", - "test:node": "npm run clean && npm run build:test:node && npm run unit-test:node", - "test": "npm run clean && npm run test:node && npm run test:browser", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "mocha --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace test-dist/index.node.js", - "unit-test": "npm run unit-test:node && npm run unit-test:browser", - "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src", - "build:samples": "echo skip", - "execute:samples": "echo skip" - }, "sideEffects": false } diff --git a/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_providers_status.js b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_providers_status.js new file mode 100644 index 000000000000..35c825eb84bf --- /dev/null +++ b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_providers_status.js @@ -0,0 +1,67 @@ +let nock = require('nock'); + +module.exports.hash = "52b5aa847a5b1c0fe03c25dba6d1c1f5"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/88888888-8888-8888-8888-888888888888/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=ce7bd34e-0000-0000-0000-000000000000&client_secret=clientsecret&scope=https%3A%2F%2Fquantum.microsoft.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '38220cee-6aec-4d0f-8d93-508e1c4a2e01', + 'x-ms-ests-server', + '2.1.11444.12 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=Au-JfYCfeJ1Os2_0kwujtZ7POrquAQAAANw-rdcOAAAA; expires=Sat, 06-Mar-2021 01:03:25 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Thu, 04 Feb 2021 01:03:25 GMT', + 'Content-Length', + '1323' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .get('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/providerStatus') + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef1479759b9ce3f7af4bd5ffc5131fbe8d1475f14d3ba6aaaf3f6a3d147d3755de7cbf6f8322bca6c5294457b4d2df4cf32a7166d565fe46de35e5f98d7c74db15897599bcfb2e532cfca6279313e5f5d64f4d2cd60b3cbbcce2ef29f58e7ebfc4db120f476461f356dd6ae9b97f4f9478f96ebb2fc25a35bf4b9bdcaea6c91b7797d5ee7f9cf3e06e8ae2cf3b2cd17abbcee23305dad09fa0fb1ff9ff51e6fa4f90f1f819ff52edb6cb2fe218f125dfeac77f28b16d36fb88fefff92ef8f3e5ae6efdae7c5f2ad7e","f6ff008e3aacf974040000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Set-Cookie', + 'ARRAffinity=a80c7c3a42bc29f88c9055a7e2789984b224746994993027ab866c65455cca24;Path=/;HttpOnly;Secure;Domain=westus.quantum.azure.com', + 'Set-Cookie', + 'ARRAffinitySameSite=a80c7c3a42bc29f88c9055a7e2789984b224746994993027ab866c65455cca24;Path=/;HttpOnly;SameSite=None;Secure;Domain=westus.quantum.azure.com', + 'Date', + 'Thu, 04 Feb 2021 01:03:24 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_quotas.js b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_quotas.js new file mode 100644 index 000000000000..fa7a97d3fb48 --- /dev/null +++ b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_get_quotas.js @@ -0,0 +1,63 @@ +let nock = require('nock'); + +module.exports.hash = "f909c630ef6bc7852e8aad46732be7e7"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/88888888-8888-8888-8888-888888888888/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=ce7bd34e-0000-0000-0000-000000000000&client_secret=clientsecret&scope=https%3A%2F%2Fquantum.microsoft.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1323', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '9734eb80-243f-4ebe-ad29-b6c942614201', + 'x-ms-ests-server', + '2.1.11444.12 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=Au-JfYCfeJ1Os2_0kwujtZ7POrquAQAAANw-rdcOAAAA; expires=Sat, 06-Mar-2021 01:03:25 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Thu, 04 Feb 2021 01:03:25 GMT' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .get('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/quotas') + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef1479759b9ce3f7af4bd5ffcd1ac58e4cba6a8961f3dfa685a2d26c5329ffdfe3f5d4d7eff79b5ae9b8f461f35d36a454d3ffa6e55bf6d56d934a7cf56757559ccf2fa6c465f7c514cebaaa9ce5bfa62dd1665f183ac6578db3be39dbddd870f760e76ef1fc8f3707ff4d1bc2a67cd478fe8cbd14765b128da8f1eedf11fabbc2e2a86582ddb7979fdd12f19bd077eafd793665a172bee9b807dc328eeeeecf09fb74072395dd775be6c7fffe96a0d547d2cdf9f8adc6b04a1fbf8dd62f3a25ae69b50395f5d643f7bb8ece1f7cdb818047af3f6cd61b18bdf2d1643f33388c8d76220ee3f86cb20bb7c7ff4d1327fd73e2f966f3f7ab45c97e5","2ff97f0023254de58f030000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:25 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_quantum_job_lifecycle.js b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_quantum_job_lifecycle.js new file mode 100644 index 000000000000..bb5bb7698d21 --- /dev/null +++ b/sdk/quantum/quantum-jobs/recordings/node/quantum_job_lifecycle/recording_test_quantum_job_lifecycle.js @@ -0,0 +1,213 @@ +let nock = require('nock'); + +module.exports.hash = "d72be875b213407d3bd89ae5a3328135"; + +module.exports.testInfo = {"uniqueName":{"input-":"input-161240060833601459","job-":"job-161240060889002218","jobname-":"jobname-161240060889009123"},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/88888888-8888-8888-8888-888888888888/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=ce7bd34e-0000-0000-0000-000000000000&client_secret=clientsecret&scope=https%3A%2F%2Fquantum.microsoft.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1323', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '4d71d28a-bc87-4012-8486-fec249262c01', + 'x-ms-ests-server', + '2.1.11444.12 - SCUS ProdSlices', + 'Set-Cookie', + 'fpc=Au-JfYCfeJ1Os2_0kwujtZ7POrquAgAAANw-rdcOAAAA; expires=Sat, 06-Mar-2021 01:03:26 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Thu, 04 Feb 2021 01:03:25 GMT' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .post('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/storage/sasUri', {"containerName":"testcontainer"}) + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef1474dd67c55171f3dfa68deb6abe6d1ddbbf3ac6ee6d9b269ab3abbc8dbbc69c793b29a8ca7559d8faf8ae5acba6ac6cbbcbd8bafa6d5b2cd8a655eff1ecde5677b3bbb0fb777f6e87fbfb0292e3e9b3ffbf4d3176fef7f67f6bbef3dd9f97d9e675fbdbcde9f5ceffcdedfbe38ffc9ef7ebefee9af5e5dbeb9fc8967d72f5f9ceeeffceef79efec22627107bbbf4fef6cefd37bbf77ef77bc73bf867efc14ffdc2a66e3f9b56bfb0693e9bfcc266f5599d4daf3efa","25ff0f84dd30debe000000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:27 GMT', + 'Connection', + 'close' +]); + +nock('https://dummystorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/testcontainer') + .query(true) + .reply(409, "ContainerAlreadyExistsThe specified container already exists.\nRequestId:c4b2992c-c01e-006b-0691-fa3baa000000\nTime:2021-02-04T01:03:27.5565544Z", [ + 'Content-Length', + '230', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c4b2992c-c01e-006b-0691-fa3baa000000', + 'x-ms-client-request-id', + '5f40b6cf-a1a6-42b4-b47d-1d6f4346ff0f', + 'x-ms-version', + '2020-04-08', + 'x-ms-error-code', + 'ContainerAlreadyExists', + 'Date', + 'Thu, 04 Feb 2021 01:03:27 GMT' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .post('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/storage/sasUri', {"containerName":"testcontainer","blobName":"input-161240060833601459.json"}) + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef1474dd67c55171f3dfa68deb6abe6d1ddbbf3ac6ee6d9b269ab3abbc8dbbc69c793b29a8ca7559d8faf8ae5acba6ac6cbbcbd8bafa6d5b2cd8a655edf2d96ab75bbbdfbe9eedefececea73b07f7ee7dbab3bb7fffe1f8a79b6af97b34979fededec3edcded9a3fffdc2a6fe6cf20b9be2e2b3c5abfdc9b767fbe7bffbdeb327d9eff583177b17efda6af6e08b8b9d7be7ebf9fdd3df7bd6bc5cb75f7e677272fdb6f9ddef3dfd854d4e70f67609c8f6cefd37bbf77ef77bc73bf867efe0a77e61b3faac9e5e7df4","4bfe1f41fff503d4000000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:27 GMT', + 'Connection', + 'close' +]); + +nock('https://dummystorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/testcontainer/input-161240060833601459.json', {"cost_function":{"version":"1.0","type":"ising","terms":[{"c":-3,"ids":[1,0]},{"c":5,"ids":[2,0]},{"c":9,"ids":[2,1]},{"c":2,"ids":[3,0]},{"c":-4,"ids":[3,1]},{"c":4,"ids":[3,2]}]}}) + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Content-MD5', + 'X8K62ldLT+xYkvrjps/bQQ==', + 'Last-Modified', + 'Thu, 04 Feb 2021 01:03:28 GMT', + 'ETag', + '"0x8D8C8A8AE88E1CA"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c4b299c1-c01e-006b-0291-fa3baa000000', + 'x-ms-client-request-id', + '13da6bf1-62f7-425b-bdd8-04340c34fd5f', + 'x-ms-version', + '2020-04-08', + 'x-ms-content-crc64', + 'BXcAuCMpTtQ=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Thu, 04 Feb 2021 01:03:27 GMT' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .put('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/jobs/job-161240060889002218', {"id":"job-161240060889002218","name":"jobname-161240060889009123","containerUri":"https://dummystorageaccount.blob.core.windows.net/testcontainer?sv=2019-02-02&sig=0000000000000000000000000000000000000000000000&se=2021-02-05T13%3A03%3A27Z&srt=co&ss=b&sp=racw","inputDataUri":"https://dummystorageaccount.blob.core.windows.net/testcontainer/input-161240060833601459.json?sv=2019-02-02&sr=b&sig=0000000000000000000000000000000000000000000000&se=2021-02-05T13%3A03%3A28Z&sp=rcw","inputDataFormat":"microsoft.qio.v2","providerId":"microsoft","target":"microsoft.paralleltempering-parameterfree.cpu","outputDataFormat":"microsoft.qio-results.v2"}) + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef147d36ad966c532afbfaa8b8f1e7d346fdb55f3e8eedd795637f36cd9b4559d5de46ddeb4e349594dc6d3aacec757c572565d35e365dedec55716c6efd15c7eb6b7b3fb707b678ffef70b9be2e2b3f9b34f3f7df1f6fe7766bffbde939ddfe779f6d5cbebfdc9f5ceeffded8bf39ffceee7eb9ffeead5e59bcb9f7876fdf2c5e9feceef7eefe92f6c7202b1b74bef6fefdc7fb37bef77bf77bc837ff61efcd42f6ceaf6b369f50b9be6b3c92f6c569fd5d9f4eaa3d147c572b56e9f666df64d0ce12e43dbdefd74776f7f67e7d39d837bf73eddd9ddbfff70fcd34db5ec0eb0062234cac5abfdc9b767fbe7bffbdeb327d9eff583177b17efda6af6e08b8b9d7be7ebf9fdd3df7bd6bc5cb75f7e677272fdb6d938ca031a258d2c1cd8b3aa5e642d8d6d514cebaaa9cedbf12f2aaaf1e59e69f432abb345f3d1a35ffc4b461fadeaeab298e5f5d9cc7f815ab6594d74f03f1cafe8bdb2cccb365facf2ba585e6ce3930551ab3eaff37c3c5dade945fa3b9b111a1f3d5aaecb72f4d1925a10989fae26f8cda3d5c1c39d9d87bb7bf7e89d02bd538bceb77b7bbb07f46dd366ed9af0fde8bb59d152b7f451b56e6920c3a3ddaef3665db68d8cdab5fe7a93fe687fff5e67e21dc8ee2cd304ff10d8785ae7595b54cb370553d7bebdff6667f7d1cebd477b07e383fd877bbb3b0f3ed9d979b4b343af4cf28b6279fa2e9faedd8b3245f97216fd7c9a2da779597a1dc9e7795d5735c62e1ffc","92ff07d0dcc9fa19040000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:28 GMT', + 'Connection', + 'close' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .get('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/jobs/job-161240060889002218') + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef147d36ad966c532afbfaa8b8f1e7d346fdb55f3e8eedd795637f36cd9b4559d5de46ddeb4e349594dc6d3aacec757c572565d35e365dedec55716c6efd15c7eb6b7b3fb707b678ffef70b9be2e2b3f9b34f3f7df1f6fe7766bffbde939ddfe779f6d5cbebfdc9f5ceeffded8bf39ffceee7eb9ffeead5e59bcb9f7876fdf2c5e9feceef7eefe92f6c7202b1b74bef6fefdc7fb37bef77bf77bc837ff61efcd42f6ceaf6b369f50b9be6b3c92f6c569fd5d9f4eaa3d147c572b56e9f666df64d0ce12e43dbdefd74776f7f67e7d39d837bf73eddd9ddbfff70fcd34db5ec0eb0062234cadf7defd9c1ea8b1fbcdbbb9e35afbeacce5efde0a7df3e9dbf78d6ac2f66d5eadde77bbbaf1f3c7dfda2babf3eae4e378ef2218d9246e60feb59552fb29646b628a675d554e7edf81715d5f872cf347a99d5d9a2f9e8d12ffe25a38f56757559ccf2fa6ce6bf402ddbac262af81f8e57f45e59e6659b2f56795d2c2fb6f1c98268559fd7793e9eaed6f422fd9dcd088d8f1e2dd76539fa68492d08cc4f5713fce651eae0e1cecec3ddbd7bf44e81dea945e7dbbdbddd03fab669b3764df87ef4ddac68a95bfaa85ab73490e1d16ed779b32edb4646ed5a7f2353eec00dcdefc5ab33e2df9f2aef9d9d4fbfdaffb47df813cdfcc1fee47c363b9f7cfe9d57eb9ff8ea174d5e7ce7e2075fac4f5e4f6f39bfd33acfdaa25abe29989eb6f9fe9b9ddd473bf71eed1d8c0ff61feeedee3cf86467e7d1ce0ebd32c92f8ae5e9bb7cba762fcaa4e4cb59f4f369b69ce665e975249fe7755dd518b17cf0","4bfe1fd3efd0dd09040000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:29 GMT', + 'Connection', + 'close' +]); + +nock('https://westus.quantum.azure.com:443', {"encodedQueryParams":true}) + .get('/v1.0/subscriptions/677fc922-91d0-4bf6-0000-4274d319a0fa/resourceGroups/resourcegroup/providers/Microsoft.Quantum/workspaces/workspace/jobs') + .reply(200, ["1f8b0800000000000400edbd07601c499625262f6dca7b7f4af54ad7e074a10880601324d8904010ecc188cde692ec1d69472329ab2a81ca6556655d661640cced9dbcf7de7befbdf7de7befbdf7ba3b9d4e27f7dfff3f5c6664016cf6ce4adac99e2180aac81f3f7e7c1f3f227ef1479759b9ce3f7af4bd5ffcd1b45ab659b1ccebafeae2a3471fcddb76d53cba7b779ed5cd3c5b366d556717799b37ed78525693f1b4aaf3f155b19c5557cd7899b777f19585f17b34979fededec3edcded9a3fffdc2a6b8f8ec603f6bcf7757d3eb873f79f09ddf7def59f1ed07cfa62f5e7f77affe7dee5f5e95cfeb97d5fca7ef3593f3bcfebd7fe277bff7f417363981d8dba5f7b777eebfd9ddfbddef1defedd03f3bf77fea173675fbd9b4fa854df3d9e41736abcfea6c7af5d1e8a362b95ab74fb336fb26867097a16def7ebabb77efe1c1cecea70f761ed03f0ff6c73fdd54cbee006b2042a37cf06e41637b367f797a96ffe0e5abd50fbe3a3f7bd5fef4c322dffde23bb3b7d517d5eae43bc5572fbefb839f9cbcdd38ca4f699434b27060cfaa7a91b534b64531adaba63a6fc7bfa8a8c6977ba6d1cbacce16cd478f7ef12f197db4aaabcb6296d76733ff056ad96635d1c1ff70bca2f7ca322fdb7cb1caeb6279b18d4f1644adfabccef3f174b5a617e9ef6c46687cf468b92ecbd1474b6a41607eba9ae03747ab077b07bb3b0ff7f7f6e99d02bd538bceb77b0fef3da46f9b366bd784ef47cfb2a2cc67f449b56e691cc383ddaef3665db68d0cdab5fe7a73fe687fff5e67de1dc8ee24d3fcfe10b8785ae7595b54cb370513d7bebdff6667e7d1decea39d07e39d07bb0744ca9fa2d693fca2589ebecba7eb1bde3978b0bbf7f0537e275fce6e7ee3d3f1fdbdbd7b0feeddc71bd36c39cdcbd2c34b1820afebaa06a988e34883cce88b8fce96a4548ad919d891bf02df340d4d037df9669ea7593d9d1797799a2fdbfa3abdca9a745a2d5634ad4d3e4bd70d315f9a2dd3f5b259af5655ddd287e67bea3d251e9c57b3f147bfe4978cd0a5cedad79bfd70e623d34d337c7cfa13bffbde939f5a1d3c78f9fcab9ffeeaf7690fb287cfce2fdffed4f1eb17d3e9de4fedac4e1a6af6ec070f8f5f7ffed5a629df7b3034e52cbaa0d537318c8ee2da3b2016dfb9ff70676fa3e2caeb9fac5f7ee7fae9e7abf6f75e3f5dfef4f397cfdfbe7a785d5e7d77b7f8bdbf7b725dfc3ed9bd9f784803fd899ffe8a06b3619407344a1a5938b0b82c8b0c73a3ff5728aebd83870f7776eedddf67b4d03bb5e87cbbbbb7f780befdff9ae2a299fb6170f24dca6bef607c7fffd37bf71f7e0ab5723be545ef3c7c78ffd37bf2ce6d94d7eea7e34ff7efd354e1859fafbaebf7bef7d5f54fcf2ebf783d2f69da3f3f5e7ff9530fdb2f8ed7c5bbaa389e9f3c5d5d3fffaa9e4cebf2a7bff3ea7468b677e99ffd7b43b3cd920b3a7d134308f5d6eecefe831d722276ee6fd65bf5ef432cfbe5ef933f5c9d15af3f6daf8f976fdebefae92fd73ff5133ffde9eb2fbf7df58393efacee5fae9a66da1c6c1ee53e8d9246160e2c2eca22c2dce8ff0d7a6b97880476dfd98566eaea2dfd76efe10ebefdff9adefa2170f1669db5fb68fffe78e7dec1ce837bfb5027b7d159fccefefea707077bbb78e7669db5fbe8dedef8c1fdfbf7ee7fca5aeee7abd2fa0149f393f2c9d39f7876f5ddeacd4fbffd7d265f7e7b2fdf3bcf17bfe86dfe7bddbfff93cf8e5fbdfbeacdc31fbc5efc802c517cbaf1cf2ec4393add2cb6a0d33731848ed2ba77ffc1eec39dfdfbf777362aadd3975f7eb1f3ddd3ab273ff16c76fdf43b4fbffce9e207abe977db625d10932fee3fb93e39be2cbf7c71feaadaf97d368e1251048d2c1c585c8e457eb991515a3fa74aebdea77bf77777ee3d78f829bdd3535af87667e7e0fede7dfaf6ff6b4aeb87c0c59b95d6dea3ddfbe30707bbf71f1e3c803ab98dd2a2773e1defed1f3cfc74e721deb995d2da1fef3cbc7ff0a9b8663f5f95d6faf9f43be7bfd7f94f7ffefce5eccb59fee94fee4c8b97dffdbdd693a7ed779fbd9b7f67726f76d5bcdbfdbd7f6270b2efdda37feeef0d4d360b2da8f44d0c20545907f7ee7d7af070077f6c5459df3ddd3bfbf6fe9be3fae125a9a8fbeff6dbf3fae994f8fccdfefda79f9f3dac4e0f7eeaa78fbffc920cf5c193dda1d4968c139698c6160e2d2ec722bfdce8ff0d4aebe0defede830714211edca377ba4a4bbf7db8f729125fff5f535a3feb5cbc5165ddbbf7e8fefe7897e9075d720b8d25af10d5efeded71a477a3c6c21ba417ef7f4af9909fd779ad7ba73ffd2a5f1e974f5efe3ef3c5e7f3a73f7df993d9415d7ef5f9ef352191febd5eee2f3292f2b7d7f5972f2e5e5e0df9d5f71ed23ff70773012cb5a0d4373188406b3ddca5ffdd7bb0737ff7e1ee46ad35fd6e79f1e0ed657ebf7c70f2e0ddbb372f7fd1e2e0e0bbabb3bdebd5e4f7face570f3fcdc8cdfa4534e4fce59bcda3fcff6c560bb4faf42111e7c1fe2ebdd3d159e6dbfd5dfef6ff6b3aeb87c2c79bf5d6c347f71f52aa7c77f7e1035642b7505cfb945edf19ef3dd8a794e2ede243790311e5fe2ebff1f35571fdf4eb17edeffdf0e46067fa533fbd5e34f73fbfa8af7eafabc94f4d8b1fdcff455fbdb9fa4e3db977efdefd8bd31f5c0d4cf6fe7dfae71ec4393ad92cb6a0d23731805069dddfa7dc3227903fdda8b45e9fff20bbbf3b6f9efea2ebbdb7c4c63ff8c9e7f46ff5a66a76bffcbd5f5ddf5bfee4ee7ef513dff989dfabbdbf78fed343c658c6f990c649630b8716976491606ef4ff06b545d4fa74f71e45170fa098ba6a4bbffdf46017dffe7f4d6dfdac73f14695b57f9ff4c9787fe7fecefd9ddb4687786777bcbb4f6be0fbec39ddacb2ee2371ffe0d3ddfd4ff7b9979faf2aeb2959a09f7cf17b7ffed5a7cb93e7fbebfd9d7b4fa6e5f26cfdeae1d39ffa8966f9ea7afae4e1d5ee4fbc7bda7ea71e8a9bee1fd03f947f1c986e165ad0e99b1882a7b4a0b076ef1f3cd8dbf9f4fec1fd8d4aeb273e2fdf7c67a77cf2f9abd3f28b972f68ccdf7ed7bef941f553a70f56c5b7afbe4b1f7c7731fda9eb83b7974f772fce368ef3ffa3492da6d6a7fbf7f62802ec2b2df7ed03d25ef4edffd794d60f818f37aaadfb078fee51826ae7c11e65c5a8f12db496bcf2f0e1bd9d838303bc73a3d6c21b0fc60f1e7c4ab9477ee3e7abd69a3ffbf4d3176fef7f6746b3bef3fb3ccfbe7a79bd3fb9def9bdbf7d71fe93dffd7cfdd35fbdba7c73f913cfae5fbe38dd8fb9204805ece09fbd41bf9aa51674fa2686106aad4f77282bf0e9ceee3ef9e69bb4d6e2d5fee4dbb3fd73f2af9e64bfd70f5eec5dbc6babd9832f2e76ee9dafe7f74f7fef59f372dd7ef99dc9c9f5db66e328618a6964e1c0e2622ce2cb8dfedfa0b388569400dc79487e15bdd3d559faeddedeee017d6b75d677b3a2a56ee923a733e2a3fdb9555a3f0436dea0b4761feddc831774b0ff706f7787bda098d692d9e9eb26f9fc","161a081ffc92efd304e7efdae7c5f2ad7e","f2ff00880ee059df290000"], [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json; charset=utf-8', + 'Content-Encoding', + 'gzip', + 'Vary', + 'Accept-Encoding', + 'Server', + 'Microsoft-IIS/10.0', + 'Request-Context', + 'appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f', + 'Strict-Transport-Security', + 'max-age=2592000', + 'X-Powered-By', + 'ASP.NET', + 'Date', + 'Thu, 04 Feb 2021 01:03:29 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/quantum/quantum-jobs/review/quantum-jobs.api.md b/sdk/quantum/quantum-jobs/review/quantum-jobs.api.md index 5e9f512fefe0..0d206f4ac31b 100644 --- a/sdk/quantum/quantum-jobs/review/quantum-jobs.api.md +++ b/sdk/quantum/quantum-jobs/review/quantum-jobs.api.md @@ -189,7 +189,7 @@ export interface ProviderStatusList { // @public (undocumented) export class QuantumJobClient extends QuantumJobClientContext { - constructor(subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams); + constructor(credentials: coreHttp.TokenCredential | coreHttp.ServiceClientCredentials, subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams); // (undocumented) jobs: Jobs; // (undocumented) @@ -204,7 +204,7 @@ export class QuantumJobClient extends QuantumJobClientContext { export class QuantumJobClientContext extends coreHttp.ServiceClient { // (undocumented) $host: string; - constructor(subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams); + constructor(credentials: coreHttp.TokenCredential | coreHttp.ServiceClientCredentials, subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams); // (undocumented) resourceGroupName: string; // (undocumented) diff --git a/sdk/quantum/quantum-jobs/rollup.base.config.js b/sdk/quantum/quantum-jobs/rollup.base.config.js index 8863248170f6..871ac6ed9f53 100644 --- a/sdk/quantum/quantum-jobs/rollup.base.config.js +++ b/sdk/quantum/quantum-jobs/rollup.base.config.js @@ -2,90 +2,59 @@ * Copyright (c) Microsoft Corporation. * Licensed under the MIT License. */ +import path from "path"; import nodeResolve from "@rollup/plugin-node-resolve"; import multiEntry from "@rollup/plugin-multi-entry"; import cjs from "@rollup/plugin-commonjs"; +import json from "@rollup/plugin-json"; import replace from "@rollup/plugin-replace"; +import shim from "rollup-plugin-shim"; import { terser } from "rollup-plugin-terser"; import sourcemaps from "rollup-plugin-sourcemaps"; -import shim from "rollup-plugin-shim"; -import json from "@rollup/plugin-json"; -import * as path from "path"; -import inject from "@rollup/plugin-inject"; +import viz from "rollup-plugin-visualizer"; const pkg = require("./package.json"); const depNames = Object.keys(pkg.dependencies); +const devDepNames = Object.keys(pkg.devDependencies); const input = "dist-esm/src/index.js"; const production = process.env.NODE_ENV === "production"; -const version = pkg.version; -const banner = [ - "/*!", - " * Copyright (c) Microsoft and contributors. All rights reserved.", - " * Licensed under the MIT License. See License.txt in the project root for", - " * license information.", - " * ", - ` * Azure Quantum Jobs SDK for JavaScript - ${version}`, - " */" -].join("\n"); - -const ignoreKnownWarnings = (warning) => { - if (warning.code === "THIS_IS_UNDEFINED") { - // This error happens frequently due to TypeScript emitting `this` at the - // top-level of a module. In this case its fine if it gets rewritten to - // undefined, so ignore this error. - return; - } - - if ( - warning.code === "CIRCULAR_DEPENDENCY" && - warning.importer.indexOf(path.normalize("node_modules/chai/lib") === 0) - ) { - // Chai contains circular references, but they are not fatal and can be ignored. - return; - } - - console.error(`(!) ${warning.message}`); -}; - export function nodeConfig(test = false) { - const externalNodeBuiltins = ["events", "crypto", "path"]; + const externalNodeBuiltins = ["events", "path"]; const baseConfig = { input: input, external: depNames.concat(externalNodeBuiltins), - output: { - file: "dist/index.js", - format: "cjs", - sourcemap: true, - banner: banner, - name: "azurequantumjobs" - }, + output: { file: "dist/index.js", format: "cjs", sourcemap: true }, preserveSymlinks: false, plugins: [ sourcemaps(), replace({ - delimiters: ["", ""] + delimiters: ["", ""], + // replace dynamic checks with if (true) since this is for node only. + // Allows rollup's dead code elimination to be more aggressive. + "if (isNode)": "if (true)" }), nodeResolve({ preferBuiltins: true }), + json(), cjs() ] }; if (test) { // Entry points - test files under the `test` folder(common for both browser and node), node specific test files - baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/**/*.spec.js"]; - baseConfig.plugins.unshift( - multiEntry({ exports: false }), - json() // This allows us to import/require the package.json file, to get the version and test it against the user agent. - ); + baseConfig.input = [ + "dist-esm/test/public/*.spec.js", + "dist-esm/test/internal/*.spec.js", + "dist-esm/test/public/node/*.spec.js", + "dist-esm/test/internal/node/*.spec.js" + ]; + baseConfig.plugins.unshift(multiEntry({ exports: false })); // different output file - baseConfig.output.file = "test-dist/index.node.js"; - - // mark assert packages we use as external - baseConfig.external.push("assert"); + baseConfig.output.file = "dist-test/index.node.js"; - baseConfig.external.push(...Object.keys(pkg.dependencies), ...Object.keys(pkg.devDependencies)); + // mark devdeps as external + baseConfig.external.push(...devDepNames); // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also @@ -102,59 +71,67 @@ export function browserConfig(test = false) { const baseConfig = { input: input, output: { - file: "dist-browser/quantumjobs.js", + file: "dist-browser/azure-quantum.js", format: "umd", - name: "Azure.QuantumJobs", - globals: { - "@azure/core-http": "Azure.Core.HTTP" - }, + name: "azquantumjobs", sourcemap: true }, - external: ["fs-extra"], preserveSymlinks: false, plugins: [ sourcemaps(), replace({ - delimiters: ["", ""] + delimiters: ["", ""], + // replace dynamic checks with if (false) since this is for + // browser only. Rollup's dead code elimination will remove + // any code guarded by if (isNode) { ... } + "if (isNode)": "if (false)" + }), + shim({ + constants: `export default {}`, + fs: `export default {}`, + os: `export default {}`, + dotenv: `export function config() { }`, + path: `export default {}` }), - nodeResolve({ mainFields: ["module", "browser"], preferBuiltins: false }), + json(), cjs({ namedExports: { - chai: ["assert", "expect", "use"], - assert: ["ok", "equal", "strictEqual", "deepEqual", "fail", "throws", "notEqual"], events: ["EventEmitter"], + chai: ["assert"], "@opentelemetry/api": ["CanonicalCode", "SpanKind", "TraceFlags"] } }), - - inject({ - modules: { - process: "process" - }, - exclude: ["./**/package.json"] - }), - - json() + // disable the plugin in the rollup config to cut-out errors + viz({ filename: "dist-browser/browser-stats.html", sourcemap: false }) ] }; - baseConfig.onwarn = ignoreKnownWarnings; - if (test) { - baseConfig.input = ["dist-esm/test/public/*.spec.js", "dist-esm/test/internal/*.spec.js"]; - - baseConfig.external.unshift(...["process"]); - + // Entry points - test files under the `test` folder(common for both browser and node), browser specific test files + baseConfig.input = [ + "dist-esm/test/public/*.spec.js", + "dist-esm/test/internal/*.spec.js", + "dist-esm/test/public/browser/*.spec.js", + "dist-esm/test/internal/browser/*.spec.js" + ]; baseConfig.plugins.unshift(multiEntry({ exports: false })); - baseConfig.plugins.unshift( - ...[shim({ path: `export function join() {}`, dotenv: `export function config() { }` })] - ); - - baseConfig.output.file = "test-browser/index.js"; + baseConfig.output.file = "dist-test/index.browser.js"; + + baseConfig.onwarn = (warning) => { + if ( + warning.code === "CIRCULAR_DEPENDENCY" && + warning.importer.indexOf(path.normalize("node_modules/chai/lib") === 0) + ) { + // Chai contains circular references, but they are not fatal and can be ignored. + return; + } + + console.error(`(!) ${warning.message}`); + }; // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also diff --git a/sdk/quantum/quantum-jobs/rollup.test.config.js b/sdk/quantum/quantum-jobs/rollup.test.config.js index 4551b61a6025..a1a09aafafbe 100644 --- a/sdk/quantum/quantum-jobs/rollup.test.config.js +++ b/sdk/quantum/quantum-jobs/rollup.test.config.js @@ -8,11 +8,11 @@ import * as base from "./rollup.base.config"; const inputs = []; if (!process.env.ONLY_BROWSER) { - inputs.push(base.nodeConfig({ test: true })); + inputs.push(base.nodeConfig(true)); } if (!process.env.ONLY_NODE) { - inputs.push(base.browserConfig({ test: true })); + inputs.push(base.browserConfig(true)); } export default inputs; diff --git a/sdk/quantum/quantum-jobs/samples/package.json b/sdk/quantum/quantum-jobs/samples/package.json new file mode 100644 index 000000000000..d25ddd51ea9e --- /dev/null +++ b/sdk/quantum/quantum-jobs/samples/package.json @@ -0,0 +1,14 @@ +{ + "name": "azure-quantum-jobs-samples-js", + "private": true, + "version": "1.0.0-beta.1", + "description": "Samples for the azure/quantum-jobs client library for Javascript", + "author": "Microsoft Corporation", + "license": "MIT", + "main": "quantumJobs.js", + "dependencies": { + "@azure/core-http": "latest", + "@azure/storage-blob": "latest", + "@azure/identity": "latest" + } +} diff --git a/sdk/quantum/quantum-jobs/samples/problem.json b/sdk/quantum/quantum-jobs/samples/problem.json new file mode 100644 index 000000000000..fc3c499baed4 --- /dev/null +++ b/sdk/quantum/quantum-jobs/samples/problem.json @@ -0,0 +1,32 @@ +{ + "cost_function": { + "version": "1.0", + "type": "ising", + "terms": [ + { + "c": -3, + "ids": [ 1, 0 ] + }, + { + "c": 5, + "ids": [ 2, 0 ] + }, + { + "c": 9, + "ids": [ 2, 1 ] + }, + { + "c": 2, + "ids": [ 3, 0 ] + }, + { + "c": -4, + "ids": [ 3, 1 ] + }, + { + "c": 4, + "ids": [ 3, 2 ] + } + ] + } +} \ No newline at end of file diff --git a/sdk/quantum/quantum-jobs/samples/quantumJobs.js b/sdk/quantum/quantum-jobs/samples/quantumJobs.js new file mode 100644 index 000000000000..db86c625eab0 --- /dev/null +++ b/sdk/quantum/quantum-jobs/samples/quantumJobs.js @@ -0,0 +1,163 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +const { DefaultAzureCredential } = require("@azure/identity"); +const { ContainerClient, BlockBlobClient } = require("@azure/storage-blob"); +const { QuantumJobClient } = require("../dist-esm/src"); +const fs = require("fs"); + +class TestTokenCredential { + constructor(token, expiresOn) { + this.token = token; + this.expiresOn = expiresOn ? expiresOn.getTime() : Date.now() + 60 * 60 * 1000; + } + async getToken(_scopes, _options) { + return { + token: this.token, + expiresOnTimestamp: this.expiresOn + }; + } +} + +// Simple example of how to: +// - create a DigitalTwins Service Client using the DigitalTwinsClient constructor +async function main() { + // Environment variables have to be set + try { + // DefaultAzureCredential supports different authentication mechanisms and determines the appropriate credential type based of the environment it is executing in. + // It attempts to use multiple credential types in an order until it finds a working credential. + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new DefaultAzureCredential(); + + // Create a QuantumJobClient + const subscriptionId = "your_subscription_id"; + const resourceGroupName = "your_resource_group_name"; + const workspaceName = "your_quantum_workspace_name"; + const storageContainerName = "mycontainer"; + const location = "westus"; //"your_location"; + const endpoint = "https://" + location + ".quantum.azure.com"; + + const quantumJobClient = new QuantumJobClient( + credential, + subscriptionId, + resourceGroupName, + workspaceName, + { + endpoint: endpoint, + credentialScopes: "https://quantum.microsoft.com/.default" + } + ); + + console.log(`Created QuantumJobClient for: + SubscriptionId: ${subscriptionId} + ResourceGroup: ${resourceGroupName} + WorkspaceName: ${workspaceName} + Location: ${location} +`); + + console.log(`Getting Container Uri with SAS key...`); + + // Get container Uri with SAS key + const containerUri = ( + await quantumJobClient.storage.sasUri({ + containerName: storageContainerName + }) + ).sasUri; + + console.log(`Container Uri with SAS key: + ${containerUri} +`); + + console.log(`Creating Container if not exist...`); + + // Create container if not exists + const containerClient = new ContainerClient(containerUri); + containerClient.createIfNotExists(); + + console.log(`Uploading data into a blob...`); + + // Get input data blob Uri with SAS key + const blobName = "myjobinput.json"; + const inputDataUri = ( + await quantumJobClient.storage.sasUri({ + containerName: storageContainerName, + blobName: blobName + }) + ).sasUri; + + // Upload input data to blob + const blobClient = new BlockBlobClient(inputDataUri); + const problemFilename = "problem.json"; + const fileContent = fs.readFileSync(problemFilename, "utf8"); + await blobClient.upload(fileContent, Buffer.byteLength(fileContent)); + + console.log(`Input data Uri with SAS key: + ${inputDataUri} +`); + + console.log(`Creating Quantum job...`); + + const randomId = `${Math.floor(Math.random() * 10000 + 1)}`; + + // Submit job + const jobId = `job-${randomId}`; + const jobName = `jobName-${randomId}`; + const inputDataFormat = "microsoft.qio.v2"; + const outputDataFormat = "microsoft.qio-results.v2"; + const providerId = "microsoft"; + const target = "microsoft.paralleltempering-parameterfree.cpu"; + const createJobDetails = { + containerUri: containerUri, + inputDataFormat: inputDataFormat, + providerId: providerId, + target: target, + id: jobId, + inputDataUri: inputDataUri, + name: jobName, + outputDataFormat: outputDataFormat + }; + const createdJob = await quantumJobClient.jobs.create(jobId, createJobDetails); + + console.log(`Job created: + Id: ${createdJob.id} + Name: ${createdJob.name} + CreationTime: ${createdJob.creationTime} + Status: ${createdJob.status} +`); + + console.log(`Getting Quantum job...`); + + // Get the job that we've just created based on its jobId + const myJob = await quantumJobClient.jobs.get(jobId); + + console.log(`Job obtained: + Id: ${myJob.id} + Name: ${myJob.name} + CreationTime: ${myJob.creationTime} + Status: ${myJob.status} + BeginExecutionTime: ${myJob.beginExecutionTime} + EndExecutionTime: ${myJob.endExecutionTime} + CancellationTime: ${myJob.cancellationTime} + OutputDataFormat: ${myJob.outputDataFormat} + OutputDataUri: ${myJob.outputDataUri} +`); + + console.log(`Getting list of Quantum jobs...`); + let jobListResult = await quantumJobClient.jobs.list(); + let listOfJobs = await jobListResult.next(); + while (!listOfJobs.done) { + let job = listOfJobs.value; + console.log(` ${job.name}`); + listOfJobs = await jobListResult.next(); + } + + console.log(); + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/sdk/quantum/quantum-jobs/src/quantumJobClient.ts b/sdk/quantum/quantum-jobs/src/quantumJobClient.ts index 18bacf6e5d95..8f9580bfd2dd 100644 --- a/sdk/quantum/quantum-jobs/src/quantumJobClient.ts +++ b/sdk/quantum/quantum-jobs/src/quantumJobClient.ts @@ -6,6 +6,7 @@ * Changes may cause incorrect behavior and will be lost if the code is regenerated. */ +import * as coreHttp from "@azure/core-http"; import { Jobs, Providers, Storage, Quotas } from "./operations"; import { QuantumJobClientContext } from "./quantumJobClientContext"; import { QuantumJobClientOptionalParams } from "./models"; @@ -13,6 +14,7 @@ import { QuantumJobClientOptionalParams } from "./models"; export class QuantumJobClient extends QuantumJobClientContext { /** * Initializes a new instance of the QuantumJobClient class. + * @param credentials Subscription credentials which uniquely identify client subscription. * @param subscriptionId The Azure subscription ID. This is a GUID-formatted string (e.g. * 00000000-0000-0000-0000-000000000000) * @param resourceGroupName Name of an Azure resource group. @@ -20,12 +22,13 @@ export class QuantumJobClient extends QuantumJobClientContext { * @param options The parameter options */ constructor( + credentials: coreHttp.TokenCredential | coreHttp.ServiceClientCredentials, subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams ) { - super(subscriptionId, resourceGroupName, workspaceName, options); + super(credentials, subscriptionId, resourceGroupName, workspaceName, options); this.jobs = new Jobs(this); this.providers = new Providers(this); this.storage = new Storage(this); diff --git a/sdk/quantum/quantum-jobs/src/quantumJobClientContext.ts b/sdk/quantum/quantum-jobs/src/quantumJobClientContext.ts index 7cb940c8df4d..a72c6f9a9425 100644 --- a/sdk/quantum/quantum-jobs/src/quantumJobClientContext.ts +++ b/sdk/quantum/quantum-jobs/src/quantumJobClientContext.ts @@ -20,6 +20,7 @@ export class QuantumJobClientContext extends coreHttp.ServiceClient { /** * Initializes a new instance of the QuantumJobClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. * @param subscriptionId The Azure subscription ID. This is a GUID-formatted string (e.g. * 00000000-0000-0000-0000-000000000000) * @param resourceGroupName Name of an Azure resource group. @@ -27,11 +28,15 @@ export class QuantumJobClientContext extends coreHttp.ServiceClient { * @param options The parameter options */ constructor( + credentials: coreHttp.TokenCredential | coreHttp.ServiceClientCredentials, subscriptionId: string, resourceGroupName: string, workspaceName: string, options?: QuantumJobClientOptionalParams ) { + if (credentials === undefined) { + throw new Error("'credentials' cannot be null"); + } if (subscriptionId === undefined) { throw new Error("'subscriptionId' cannot be null"); } @@ -52,7 +57,7 @@ export class QuantumJobClientContext extends coreHttp.ServiceClient { options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`; } - super(undefined, options); + super(credentials, options); this.requestContentType = "application/json; charset=utf-8"; diff --git a/sdk/quantum/quantum-jobs/swagger/readme.md b/sdk/quantum/quantum-jobs/swagger/readme.md index 658886850143..f1399fc4822f 100644 --- a/sdk/quantum/quantum-jobs/swagger/readme.md +++ b/sdk/quantum/quantum-jobs/swagger/readme.md @@ -6,14 +6,16 @@ ```yaml package-name: "@azure/quantum-jobs" +package-version: "1.0.0-beta.1" generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../ source-code-folder-path: ./src/ input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/quantum/data-plane/Microsoft.Quantum/preview/2019-11-04-preview/quantum.json -add-credentials: false +add-credentials: true +credential-scopes: ["https://quantum.microsoft.com/.default"] title: QuantumJobClient v3: true use-extension: - "@autorest/typescript": "6.0.0-dev.20210121.2" + "@autorest/typescript": "6.0.0-dev.20210201.1" ``` diff --git a/sdk/quantum/quantum-jobs/test/problem.json b/sdk/quantum/quantum-jobs/test/problem.json new file mode 100644 index 000000000000..fc3c499baed4 --- /dev/null +++ b/sdk/quantum/quantum-jobs/test/problem.json @@ -0,0 +1,32 @@ +{ + "cost_function": { + "version": "1.0", + "type": "ising", + "terms": [ + { + "c": -3, + "ids": [ 1, 0 ] + }, + { + "c": 5, + "ids": [ 2, 0 ] + }, + { + "c": 9, + "ids": [ 2, 1 ] + }, + { + "c": 2, + "ids": [ 3, 0 ] + }, + { + "c": -4, + "ids": [ 3, 1 ] + }, + { + "c": 4, + "ids": [ 3, 2 ] + } + ] + } +} \ No newline at end of file diff --git a/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts b/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts index 4be9e7e2378a..10b0b88e605a 100644 --- a/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts +++ b/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts @@ -1,16 +1,160 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as assert from "assert"; +import { ContainerClient, BlockBlobClient } from "@azure/storage-blob"; import { QuantumJobClient } from "../../src"; +import { authenticate } from "../utils/testAuthentication"; +import { Recorder } from "@azure/test-utils-recorder"; +import chai from "chai"; +import * as fs from "fs"; +import { TokenCredential } from "@azure/identity"; +import { isPlaybackMode } from "@azure/test-utils-recorder"; +import { replaceStorageAccountInfo } from "../utils/recorderUtils"; -describe("Quantum Job Client tests", function() { - it("can create the client object successfully", () => { - const obj: QuantumJobClient = new QuantumJobClient( - "sample-subscription-id", - "sample-resource-group-name", - "sample-workspace-name" - ); - assert.notEqual(obj, null); +const assert = chai.assert; + +describe("Quantum job lifecycle", () => { + let client: QuantumJobClient; + let recorder: Recorder; + let credentials: TokenCredential; + + beforeEach(async function() { + const authentication = await authenticate(this); + client = authentication.client; + recorder = authentication.recorder; + credentials = authentication.credentials; + }); + + afterEach(async function() { + await recorder.stop(); + }); + + it("Test Get Providers Status", async function() { + let index = 0; + for await (const status of client.providers.listStatus()) { + assert.isNotEmpty(status.id); + assert.isNotNull(status.targets); + assert.isNotNull(status.currentAvailability); + ++index; + } + // Should have at least one in the list. + assert.isTrue(index >= 1); + }); + + it("Test Get Quotas", async function() { + let index = 0; + for await (const quota of client.quotas.list()) { + assert.isNotEmpty(quota.dimension); + assert.isNotNull(quota.scope); + assert.isNotEmpty(quota.providerId); + assert.isNotNull(quota.utilization); + assert.isNotNull(quota.holds); + assert.isNotNull(quota.period); + ++index; + } + // Should have at least one in the list. + assert.isTrue(index >= 1); + }); + + it("Test Quantum Job Lifecycle", async function() { + // Get container Uri with SAS key + const containerName = "testcontainer"; + let containerUri = + ( + await client.storage.sasUri({ + containerName: containerName + }) + ).sasUri ?? ""; + + if (isPlaybackMode()) { + containerUri = replaceStorageAccountInfo(containerUri); + } + + // Create container if not exists (if not in Playback mode) + if (!isPlaybackMode()) { + const containerClient = new ContainerClient(containerUri, credentials); + await containerClient.createIfNotExists(); + } + + // Get input data blob Uri with SAS key + const blobName = `${recorder.getUniqueName("input-")}.json`; + let inputDataUri = + ( + await client.storage.sasUri({ + containerName: containerName, + blobName: blobName + }) + ).sasUri ?? ""; + + if (isPlaybackMode()) { + inputDataUri = replaceStorageAccountInfo(inputDataUri); + } + + // Upload input data to blob (if not in Playback mode) + if (!isPlaybackMode()) { + const blobClient = new BlockBlobClient(inputDataUri, credentials); + const problemFilename = "./test/problem.json"; + const fileContent = fs.readFileSync(problemFilename, "utf8"); + await blobClient.upload(fileContent, Buffer.byteLength(fileContent)); + } + + // Submit job + const jobId = recorder.getUniqueName("job-"); + const jobName = recorder.getUniqueName("jobname-"); + const inputDataFormat = "microsoft.qio.v2"; + const outputDataFormat = "microsoft.qio-results.v2"; + const providerId = "microsoft"; + const target = "microsoft.paralleltempering-parameterfree.cpu"; + const createJobDetails = { + containerUri: containerUri, + inputDataFormat: inputDataFormat, + providerId: providerId, + target: target, + id: jobId, + inputDataUri: inputDataUri, + name: jobName, + outputDataFormat: outputDataFormat + }; + const jobDetails = await client.jobs.create(jobId, createJobDetails); + + // Check if job was created correctly + assert.equal(inputDataFormat, jobDetails.inputDataFormat); + assert.equal(outputDataFormat, jobDetails.outputDataFormat); + assert.equal(providerId, jobDetails.providerId); + assert.equal(target, jobDetails.target); + assert.isNotEmpty(jobDetails.id); + assert.isNotEmpty(jobDetails.name); + assert.isNotEmpty(jobDetails.inputDataUri); + assert.equal(jobId, jobDetails.id); + assert.equal(jobName, jobDetails.name); + if (!isPlaybackMode()) { + assert.equal(inputDataUri, jobDetails.inputDataUri); + } else { + assert.equal(inputDataUri, replaceStorageAccountInfo(jobDetails.inputDataUri as string)); + } + + // Get the job that we've just created based on the jobId + const gotJob = await client.jobs.get(jobId); + assert.equal(jobDetails.inputDataFormat, gotJob.inputDataFormat); + assert.equal(jobDetails.outputDataFormat, gotJob.outputDataFormat); + assert.equal(jobDetails.providerId, gotJob.providerId); + assert.equal(jobDetails.target, gotJob.target); + assert.equal(jobDetails.id, gotJob.id); + assert.equal(jobDetails.name, gotJob.name); + + // Get all jobs and look for the job that we've just created + let jobFound = false; + const jobs = client.jobs.list(); + for await (const job of jobs) { + if (job.id == jobDetails.id) { + jobFound = true; + assert.equal(jobDetails.inputDataFormat, gotJob.inputDataFormat); + assert.equal(jobDetails.outputDataFormat, gotJob.outputDataFormat); + assert.equal(jobDetails.providerId, gotJob.providerId); + assert.equal(jobDetails.target, gotJob.target); + assert.equal(jobDetails.name, gotJob.name); + } + } + assert.isTrue(jobFound); }); }); diff --git a/sdk/quantum/quantum-jobs/test/utils/recorderUtils.ts b/sdk/quantum/quantum-jobs/test/utils/recorderUtils.ts new file mode 100644 index 000000000000..ba474036e86e --- /dev/null +++ b/sdk/quantum/quantum-jobs/test/utils/recorderUtils.ts @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { isPlaybackMode, isRecordMode } from "@azure/test-utils-recorder"; +import { isNode } from "@azure/core-http"; +import * as dotenv from "dotenv"; + +if (isNode) { + dotenv.config(); +} + +export function getUniqueString(defaultValue: string): string { + return isPlaybackMode() || isRecordMode() + ? defaultValue + : Math.random() + .toString() + .slice(2); +} + +export function replaceStorageAccountInfo(value: string): string { + return value + .replace( + /https\:\/\/(.*?).blob.core.windows.net/g, + "https://dummystorageaccount.blob.core.windows.net" + ) + .replace(/sig=[^&]*&/g, `sig=0000000000000000000000000000000000000000000000&`); +} diff --git a/sdk/quantum/quantum-jobs/test/utils/testAuthentication.ts b/sdk/quantum/quantum-jobs/test/utils/testAuthentication.ts new file mode 100644 index 000000000000..b4ba580052a7 --- /dev/null +++ b/sdk/quantum/quantum-jobs/test/utils/testAuthentication.ts @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { DefaultAzureCredential } from "@azure/identity"; +import { QuantumJobClient } from "../../src"; +import { env, record, RecorderEnvironmentSetup } from "@azure/test-utils-recorder"; +import TestClient from "./testClient"; +import { replaceStorageAccountInfo } from "./recorderUtils"; + +export async function authenticate(that: any): Promise { + const recorderEnvSetup: RecorderEnvironmentSetup = { + replaceableVariables: { + SUBSCRIPTION_ID: "677fc922-91d0-4bf6-0000-4274d319a0fa", + RESOURCE_GROUP: "resourcegroup", + WORKSPACE_NAME: "workspace", + AZURE_CLIENT_ID: "ce7bd34e-0000-0000-0000-000000000000", + AZURE_CLIENT_SECRET: "clientsecret", + AZURE_TENANT_ID: "88888888-8888-8888-8888-888888888888" //dummy + }, + customizationsOnRecordings: [ + (recording: any): any => + recording.replace(/"access_token":"[^"]*"/g, `"access_token":"access_token"`), + replaceStorageAccountInfo + ], + queryParametersToSkip: ["sr", "sig", "sp"] + }; + const recorder = record(that, recorderEnvSetup); + const credential = new DefaultAzureCredential(); + + const client = new QuantumJobClient( + credential, + env.SUBSCRIPTION_ID, + env.RESOURCE_GROUP, + env.WORKSPACE_NAME, + { + endpoint: "https://westus.quantum.azure.com", + credentialScopes: "https://quantum.microsoft.com/.default" + } + ); + const testClient = new TestClient(client); + + return { recorder, client, credential, testClient }; +} diff --git a/sdk/quantum/quantum-jobs/test/utils/testClient.ts b/sdk/quantum/quantum-jobs/test/utils/testClient.ts new file mode 100644 index 000000000000..fdcdbcb3ce93 --- /dev/null +++ b/sdk/quantum/quantum-jobs/test/utils/testClient.ts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { QuantumJobClient } from "../../src"; + +export default class TestClient { + public readonly client: QuantumJobClient; + constructor(client: QuantumJobClient) { + this.client = client; + } +} diff --git a/sdk/quantum/quantum-jobs/tsconfig.json b/sdk/quantum/quantum-jobs/tsconfig.json index 733a8ef32522..bf3fbe880e89 100644 --- a/sdk/quantum/quantum-jobs/tsconfig.json +++ b/sdk/quantum/quantum-jobs/tsconfig.json @@ -1,8 +1,28 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { + "strict": true, + "target": "es5", + "sourceMap": true, + "lib": [ + "es6", + "dom" + ], + "declaration": true, "outDir": "./dist-esm", "declarationDir": "./types" }, - "exclude": ["node_modules", "types", "temp", "browser", "dist", "dist-esm", "./samples/**/*.ts"] + "include": [ + "./src/**/*.ts", + "./test/**/*.ts" + ], + "exclude": [ + "node_modules", + "types", + "temp", + "browser", + "dist", + "dist-esm", + "./samples/**/*.ts" + ] } diff --git a/sdk/quantum/quantum-jobs/tsdoc.json b/sdk/quantum/quantum-jobs/tsdoc.json new file mode 100644 index 000000000000..81c5a8a2aa2f --- /dev/null +++ b/sdk/quantum/quantum-jobs/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["../../../tsdoc.json"] +}