Update tests, CI and expose SASQueryParameters only in node platform.

This commit is contained in:
FAREAST\jiacfan 2018-12-28 10:24:18 +08:00 коммит произвёл Vincent Jiang (LEI)
Родитель b8738de066
Коммит 48453b9698
11 изменённых файлов: 250 добавлений и 10 удалений

Просмотреть файл

@ -15,7 +15,8 @@
],
"reporter": [
"text-summary",
"html"
"html",
"cobertura"
],
"sourceMap": true,
"instrument": true,

Просмотреть файл

@ -1 +1,6 @@
# Breaking Changes
2019.1 Version 10.1.0
* Updated convenience layer methods enum type parameters into typescript union types, this will help to reduce bundle footprint.
* `SASQueryParameters` is not going to be exported in browser bundle, and will be exported in Node.js runtime.
* IE11 needs `Array.prototype.includes` and `Object.keys` polyfills loaded.

Просмотреть файл

@ -1,5 +1,16 @@
# Changelog
2019.1 Version 10.1.0
* [Breaking] Updated convenience layer methods enum type parameters into typescript union types, this will help to reduce bundle footprint.
* [Breaking] `SASQueryParameters` is not going to be exported in browser bundle, and will be exported in Node.js runtime.
* [Breaking] IE11 needs `Array.prototype.includes` and `Object.keys` polyfills loaded.
* Updated dependency `ms-rest-js` to `@azure/ms-rest-js`.
* Updated server timeout value for retry options `tryTimeoutInMs` to 30 seconds.
* Fixed `Aborter.timeout()` misleading scale description.
* Fixed an issue that enqueue/dequeue/peek fail to work with some utf8 characters.
2018.12 Version 10.0.0-preview
* Initial Release. API version 2018-03-28 supported. Please see the README for information on the new design.

Просмотреть файл

@ -27,13 +27,16 @@ This SDK is compatible with Node.js and browsers, and validated against LTS Node
You need polyfills to make this library work with IE11. The easiest way is to use [@babel/polyfill](https://babeljs.io/docs/en/babel-polyfill), or [polyfill service](https://polyfill.io/v2/docs/).
Or you can load separate polyfills for missed ES feature(s).
This library depends on following ES6 features which need external polyfills loaded.
This library depends on following ES features which need external polyfills loaded.
* `Promise`
* `String.prototype.startsWith`
* `String.prototype.endsWith`
* `String.prototype.repeat`
* `String.prototype.includes`
* `Array.prototype.includes`
* `Object.keys` (Override IE11's `Object.keys` with ES6 polyfill forcely to enable [ES6 behavior](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Notes))
#### Differences between Node.js and browsers

Просмотреть файл

@ -26,7 +26,8 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: [
// polyfill service supporting IE11 missing features
"https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes",
// 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",
"dist-test/index.browser.js"
],
@ -57,7 +58,8 @@ module.exports = function(config) {
// Coverage report settings
remapCoverageReporter: {
"text-summary": null, // to show summary in console
html: "./coverage-browser"
html: "./coverage-browser",
cobertura: "./coverage-browser/cobertura-coverage.xml"
},
// Exclude coverage calculation for following files
@ -102,6 +104,8 @@ module.exports = function(config) {
concurrency: 1,
browserNoActivityTimeout: 600000,
browserDisconnectTimeout: 10000,
browserDisconnectTolerance: 3,
client: {
mocha: {

Просмотреть файл

@ -19,7 +19,6 @@ export * from "./policies/TokenCredentialPolicy";
export * from "./QueueURL"
export * from "./QueueSASPermissions";
export * from "./UniqueRequestIDPolicyFactory";
export * from "./SASQueryParameters";
export * from "./ServiceURL";
export * from "./StorageURL";
export { Models, RestError };

Просмотреть файл

@ -28,4 +28,5 @@ export * from "./IQueueSASSignatureValues"
export * from "./UniqueRequestIDPolicyFactory";
export * from "./ServiceURL";
export * from "./StorageURL";
export * from "./SASQueryParameters";
export { Models, RestError };

10
queue/package-lock.json сгенерированный
Просмотреть файл

@ -489,7 +489,7 @@
"resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
"requires": {
"follow-redirects": "1.5.10",
"follow-redirects": "1.6.0",
"is-buffer": "1.1.6"
}
},
@ -1942,9 +1942,9 @@
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.0.tgz",
"integrity": "sha512-4Oh4eI3S9OueVV41AgJ1oLjpaJUhbJ7JDGOMhe0AFqoSejl5Q2nn3eGglAzRUKVKZE8jG5MNn66TjCJMAnpsWA==",
"requires": {
"debug": "3.1.0"
}
@ -2947,7 +2947,7 @@
"dev": true,
"requires": {
"eventemitter3": "3.1.0",
"follow-redirects": "1.5.10",
"follow-redirects": "1.6.0",
"requires-port": "1.0.0"
}
},

Просмотреть файл

@ -0,0 +1,129 @@
import { URLBuilder } from "@azure/ms-rest-js";
import * as assert from "assert";
import { RestError, StorageURL } from "../lib";
import { Aborter } from "../lib/Aborter";
import { QueueURL } from "../lib/QueueURL";
import { Pipeline } from "../lib/Pipeline";
import { getQSU, getUniqueName } from "./utils";
import { InjectorPolicyFactory } from "./utils/InjectorPolicyFactory";
describe("RetryPolicy", () => {
const serviceURL = getQSU();
let queueName: string = getUniqueName("queue");
let queueURL = QueueURL.fromServiceURL(serviceURL, queueName);
beforeEach(async () => {
queueName = getUniqueName("queue");
queueURL = QueueURL.fromServiceURL(serviceURL, queueName);
await queueURL.create(Aborter.none);
});
afterEach(async () => {
await queueURL.delete(Aborter.none);
});
it("Retry policy should work when first request fails with 500", async () => {
let injectCounter = 0;
const injector = new InjectorPolicyFactory(() => {
if (injectCounter === 0) {
injectCounter++;
return new RestError(
"Server Internal Error",
"ServerInternalError",
500
);
}
});
const factories = queueURL.pipeline.factories.slice(); // clone factories array
factories.push(injector);
const pipeline = new Pipeline(factories);
const injectqueueURL = queueURL.withPipeline(pipeline);
const metadata = {
key0: "val0",
keya: "vala",
keyb: "valb"
};
await injectqueueURL.setMetadata(Aborter.none, metadata);
const result = await queueURL.getProperties(Aborter.none);
assert.deepEqual(result.metadata, metadata);
});
it("Retry policy should failed when requests always fail with 500", async () => {
const injector = new InjectorPolicyFactory(() => {
return new RestError("Server Internal Error", "ServerInternalError", 500);
});
const credential =
queueURL.pipeline.factories[
queueURL.pipeline.factories.length - 1
];
const factories = StorageURL.newPipeline(credential, {
retryOptions: { maxTries: 3 }
}).factories;
factories.push(injector);
const pipeline = new Pipeline(factories);
const injectqueueURL = queueURL.withPipeline(pipeline);
let hasError = false;
try {
const metadata = {
key0: "val0",
keya: "vala",
keyb: "valb"
};
await injectqueueURL.setMetadata(Aborter.none, metadata);
} catch (err) {
hasError = true;
}
assert.ok(hasError);
});
it("Retry policy should work for secondary endpoint", async () => {
let injectCounter = 0;
const injector = new InjectorPolicyFactory(() => {
if (injectCounter++ < 1) {
return new RestError(
"Server Internal Error",
"ServerInternalError",
500
);
}
});
const url = serviceURL.url;
const urlParsed = URLBuilder.parse(url);
const host = urlParsed.getHost()!;
const hostParts = host.split(".");
const account = hostParts.shift();
const secondaryAccount = `${account}-secondary`;
hostParts.unshift(secondaryAccount);
const secondaryHost = hostParts.join(".");
const credential =
queueURL.pipeline.factories[
queueURL.pipeline.factories.length - 1
];
const factories = StorageURL.newPipeline(credential, {
retryOptions: { maxTries: 2, secondaryHost }
}).factories;
factories.push(injector);
const pipeline = new Pipeline(factories);
const injectqueueURL = queueURL.withPipeline(pipeline);
let finalRequestURL = "";
try {
const response = await injectqueueURL.getProperties(Aborter.none);
finalRequestURL = response._response.request.url;
} catch (err) {
finalRequestURL = err.request ? err.request.url : "";
}
assert.deepStrictEqual(
URLBuilder.parse(finalRequestURL).getHost(),
secondaryHost
);
});
});

Просмотреть файл

@ -0,0 +1,58 @@
import {
BaseRequestPolicy,
HttpOperationResponse,
RequestPolicy,
RequestPolicyOptions,
WebResource,
RestError
} from "../../lib";
export interface INextInjectErrorHolder {
nextInjectError?: RestError;
}
export type Injector = () => RestError | undefined;
/**
* InjectorPolicy will inject a customized error before next HTTP request.
*
* @class InjectorPolicy
* @extends {BaseRequestPolicy}
*/
export class InjectorPolicy extends BaseRequestPolicy {
/**
* Creates an instance of InjectorPolicy.
*
* @param {RequestPolicy} nextPolicy
* @param {RequestPolicyOptions} options
* @memberof InjectorPolicy
*/
public constructor(
nextPolicy: RequestPolicy,
options: RequestPolicyOptions,
injector: Injector
) {
super(nextPolicy, options);
this.injector = injector;
}
/**
* Sends request.
*
* @param {WebResource} request
* @returns {Promise<HttpOperationResponse>}
* @memberof InjectorPolicy
*/
public async sendRequest(
request: WebResource
): Promise<HttpOperationResponse> {
const error = this.injector();
if (error) {
throw error;
}
return this._nextPolicy.sendRequest(request);
}
private injector: Injector;
}

Просмотреть файл

@ -0,0 +1,29 @@
import {
RequestPolicy,
RequestPolicyFactory,
RequestPolicyOptions
} from "../../lib";
import { InjectorPolicy, Injector } from "./InjectorPolicy";
/**
* InjectorPolicyFactory is a factory class injects customized errors for retry policy testing.
*
* @export
* @class InjectorPolicyFactory
* @implements {RequestPolicyFactory}
*/
export class InjectorPolicyFactory implements RequestPolicyFactory {
public readonly injector: Injector;
public constructor(injector: Injector) {
this.injector = injector;
}
public create(
nextPolicy: RequestPolicy,
options: RequestPolicyOptions
): InjectorPolicy {
return new InjectorPolicy(nextPolicy, options, this.injector);
}
}