diff --git a/.gitignore b/.gitignore index 4dca5f4d..04f653c0 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ test/module/test-dir test/module/test-file !test/module/node_modules !test/module/**/*.js -!test/transport-builtin-test.js !unittest/module/test-files/node_modules diff --git a/test/transport-builtin-test.js b/test/transport-builtin-test.js deleted file mode 100644 index bd999095..00000000 --- a/test/transport-builtin-test.js +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -const assert = require('assert'); -const napa = require('../lib/index'); -let zoneId = 'transport-test-zone'; -let zone = napa.zone.create(zoneId, { workers: 4 }); - -/// Construct an expected result string. -/// constructExpectedResult(5, 5, 255) returns '0,0,0,0,0' -/// constructExpectedResult(2, 5, 255) returns '0,0,255,255,255' -/// constructExpectedResult(0, 5, 255) returns '255,255,255,255,255' -global.constructExpectedResult = -function constructExpectedResult(i, length, value) { - const assert = require('assert'); - assert(i >= 0 && length >= i); - let expected = ''; - for (var t = 0; t < i; t++) { - if (t > 0) expected += ','; - expected += '0'; - } - for (var t = i; t < length; t++) { - if (t > 0) expected += ','; - expected += value.toString(); - } - return expected; -} -zone.broadcast("global.constructExpectedResult = " + constructExpectedResult.toString()); - -function transportSharedArrayBuffer() { - var promises = []; - var sab = new SharedArrayBuffer(4); - for (var i = 0; i < 4; i++) { - promises[i] = zone.execute((sab, i) => { - var ta = new Uint8Array(sab); - ta[i] = 100; - }, [sab, i]); - } - - return Promise.all(promises).then(values => { - var ta = new Uint8Array(sab); - assert.deepEqual(ta.toString(), '100,100,100,100'); - }); -} -exports.transportSharedArrayBuffer = transportSharedArrayBuffer; - -function transportCompositeObjectOfSharedArrayBuffer() { - let sab = new SharedArrayBuffer(4); - let ta1 = new Uint8Array(sab); - let ta2 = new Uint8Array(sab); - let obj = { sab: sab, tas: { ta1: ta1, ta2: ta2 }, ta22:ta2 }; - return zone.execute((obj) => { - var ta = new Uint8Array(obj.sab); - ta[0] = 99; - obj.tas.ta1[1] = 88; - obj.tas.ta2[2] = 77; - obj.ta22[3] = 66; - }, [obj]).then((result) => { - var ta_sab = new Uint8Array(sab); - assert.deepEqual(ta_sab.toString(), '99,88,77,66'); - }); -} -exports.transportCompositeObjectOfSharedArrayBuffer = transportCompositeObjectOfSharedArrayBuffer; - -function recursivelySetElementOfSharedArrayBuffer(zoneId, sab, i, value) { - if (i < 0) return; - let ta = new Uint8Array(sab); - ta[i] = value; - - const assert = require('assert'); - - // SharedArrayBuffer shares storage when it is transported, - // so elements with index > i have been set to {value} by those finished zone.executions. - let expected = global.constructExpectedResult(i, ta.length, value); - assert.equal(ta.toString(), expected); - - const napa = require('../lib/index'); - let zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; - zone.execute( - recursivelySetElementOfSharedArrayBuffer, - [zoneId, sab, i - 1, value] - ).then((result) => { - // SharedArrayBuffer shares storage when it is transported, - // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute, - // so ta.toString() should be larger than {expected} constructed before. - if (i > 0) assert(ta.toString() > expected); - else if (i === 0) assert.equal(ta.toString(), expected); - else assert(false); - }); -} - -function recursivelyTransportSharedArrayBuffer(length, timeout) { - let value = 255; - let sab = new SharedArrayBuffer(length); - let ta = new Uint8Array(sab); - recursivelySetElementOfSharedArrayBuffer(zoneId, sab, length - 1, value); - - return new Promise((resolve, reject) => { - setTimeout(() => { - // Because SharedArrayBuffer will share storage when it is transported, - // once the recursive process finished, all elements of - // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}. - let expected = global.constructExpectedResult(0, ta.length, value); - assert.equal(ta.toString(), expected); - resolve(); - }, timeout); - }); -} -exports.recursivelyTransportSharedArrayBuffer = recursivelyTransportSharedArrayBuffer; - - -function recursivelySetElementOfTypedArray_SAB(zoneId, ta, i, value) { - if (i < 0) return; - ta[i] = value; - - const assert = require('assert'); - - // SharedArrayBuffer shares storage when it is transported, - // so elements with index > i have been set to {value} by those finished zone.executions. - let expected = global.constructExpectedResult(i, ta.length, value); - assert.equal(ta.toString(), expected); - - const napa = require('../lib/index'); - let zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; - zone.execute( - recursivelySetElementOfTypedArray_SAB, - [zoneId, ta, i - 1, value] - ).then((result) => { - // SharedArrayBuffer shares storage when it is transported, - // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute, - // so ta.toString() should be larger than {expected} constructed before. - if (i > 0) assert(ta.toString() > expected); - else if (i === 0) assert.equal(ta.toString(), expected); - else assert(false); - }); -} - -function recursivelyTransportTypedArray_SAB(length, timeout) { - let value = 255; - let sab = new SharedArrayBuffer(length); - let ta = new Uint8Array(sab); - recursivelySetElementOfTypedArray_SAB(zoneId, ta, length - 1, value); - - return new Promise((resolve, reject) => { - setTimeout(() => { - // Because SharedArrayBuffer will share storage when it is transported, - // once the recursive process finished, all elements of - // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}. - let expected = global.constructExpectedResult(0, ta.length, value); - assert.equal(ta.toString(), expected); - resolve(); - }, timeout); - }); -} -exports.recursivelyTransportTypedArray_SAB = recursivelyTransportTypedArray_SAB; - - -function recursivelySetElementOfArrayBuffer(zoneId, ab, i, value) { - if (i < 0) { - return; - } - - let ta = new Uint8Array(ab); - ta[i] = value; - - const assert = require('assert'); - - // ArrayBuffer's storage will be copied when it is transported. - // Elements with index > i should all be {value}. - // They are copied from the previous zone.execution. - let expected = global.constructExpectedResult(i, ta.length, value); - assert.equal(ta.toString(), expected); - - const napa = require('../lib/index'); - let zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; - zone.execute( - recursivelySetElementOfArrayBuffer, - [zoneId, ab, i - 1, value] - ).then((result) => { - // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute. - assert.equal(ta.toString(), expected); - }); -} - -function recursivelyTransportArrayBuffer(length, timeout) { - let value = 255; - let ab = new ArrayBuffer(length); - let ta = new Uint8Array(ab); - recursivelySetElementOfArrayBuffer(zoneId, ab, length - 1, value); - - return new Promise((resolve, reject) => { - setTimeout(() => { - // Except ta[ta-length -1] was set to {value} before the 1st transportation, - // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution. - let expected = global.constructExpectedResult(ta.length - 1, ta.length, value); - assert.equal(ta.toString(), expected); - resolve(); - }, timeout); - }); -} -exports.recursivelyTransportArrayBuffer = recursivelyTransportArrayBuffer; - - -function recursivelySetElementOfTypeArray_AB(zoneId, ta, i, value) { - if (i < 0) { - return; - } - - ta[i] = value; - - const assert = require('assert'); - - // ArrayBuffer's storage will be copied when it is transported. - // Elements with index > i should all be {value}. - // They are copied from the previous zone.execution. - let expected = global.constructExpectedResult(i, ta.length, value); - assert.equal(ta.toString(), expected); - - const napa = require('../lib/index'); - let zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; - zone.execute( - recursivelySetElementOfTypeArray_AB, - [zoneId, ta, i - 1, value] - ).then((result) => { - // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute. - assert.equal(ta.toString(), expected); - }); -} - -function recursivelyTransportTypedArray_AB(length, timeout) { - let value = 255; - let ab = new ArrayBuffer(length); - let ta = new Uint8Array(ab); - recursivelySetElementOfTypeArray_AB(zoneId, ta, length - 1, value); - - return new Promise((resolve, reject) => { - setTimeout(() => { - // Except ta[ta-length -1] was set to {value} before the 1st transportation, - // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution. - let expected = global.constructExpectedResult(ta.length - 1, ta.length, value); - assert.equal(ta.toString(), expected); - resolve(); - }, timeout); - }); -} -exports.recursivelyTransportTypedArray_AB = recursivelyTransportTypedArray_AB; diff --git a/test/transport-test.ts b/test/transport-test.ts index 5c00b62d..7d3276cb 100644 --- a/test/transport-test.ts +++ b/test/transport-test.ts @@ -6,9 +6,6 @@ import * as assert from 'assert'; import * as path from 'path'; import * as t from './napa-zone/test'; -// TODO #150 (helloshuangzi): Update TypeScript version and convert './transport-builtin-test' to TypeScript. -var transportBuiltin = require('./transport-builtin-test'); - describe('napajs/transport', () => { let napaZone = napa.zone.create('zone10'); describe('TransportContext', () => { @@ -49,7 +46,7 @@ describe('napajs/transport', () => { it('@node: simple types', () => { t.simpleTypeTransportTest(); }); - + it('@napa: simple types', () => { napaZone.execute('./napa-zone/test', "simpleTypeTransportTest"); }).timeout(3000); @@ -96,40 +93,258 @@ describe('napajs/transport', () => { }); function transportBuiltinObjects() { + let zoneId: string = 'transport-built-in-test-zone'; + let transportTestZone: napa.zone.Zone = napa.zone.create(zoneId, { workers: 4 }); + + /// Construct an expected result string. + /// constructExpectedResult(5, 5, 255, 0) returns '0,0,0,0,0' + /// constructExpectedResult(2, 5, 255, 0) returns '0,0,255,255,255' + /// constructExpectedResult(0, 5, 255, 0) returns '255,255,255,255,255' + function constructExpectedResult(i: number, size: number, expectedValue: number, defaultValue: number = 0): string { + const assert = require('assert'); + assert(i >= 0 && size >= i); + let expected: string = ''; + for (let t: number = 0; t < i; t++) { + if (t > 0) expected += ','; + expected += defaultValue.toString(); + } + for (var t = i; t < size; t++) { + if (t > 0) expected += ','; + expected += expectedValue.toString(); + } + return expected; + } + (global).constructExpectedResult = constructExpectedResult; + transportTestZone.broadcast("global.constructExpectedResult = " + constructExpectedResult.toString()); + it('@node: transport SharedArrayBuffer (SAB)', () => { - return transportBuiltin.transportSharedArrayBuffer(); + let promises: Array> = []; + let sab: SharedArrayBuffer = new SharedArrayBuffer(4); + for (let i: number = 0; i < 4; i++) { + promises[i] = transportTestZone.execute((sab, i) => { + let ta: Uint8Array = new Uint8Array(sab); + ta[i] = 100; + }, [sab, i]); + } + + return Promise.all(promises).then((values: Array) => { + let ta: Uint8Array = new Uint8Array(sab); + assert.deepEqual(ta.toString(), '100,100,100,100'); + }); }); it('@node: transport composite object of SharedArrayBuffer', () => { - return transportBuiltin.transportCompositeObjectOfSharedArrayBuffer(); + let sab: SharedArrayBuffer = new SharedArrayBuffer(4); + let ta1: Uint8Array = new Uint8Array(sab); + let ta2: Uint8Array = new Uint8Array(sab); + let obj: Object = { sab: sab, tas: { ta1: ta1, ta2: ta2 }, ta22:ta2 }; + return transportTestZone.execute((obj) => { + let ta: Uint8Array = new Uint8Array(obj.sab); + ta[0] = 99; + obj.tas.ta1[1] = 88; + obj.tas.ta2[2] = 77; + obj.ta22[3] = 66; + }, [obj]).then((result: napa.zone.Result) => { + var ta_sab: Uint8Array = new Uint8Array(sab); + assert.deepEqual(ta_sab.toString(), '99,88,77,66'); + }); }); + function recursivelySetElementOfSharedArrayBuffer(zoneId: string, sab: SharedArrayBuffer, i: number, value: number) { + if (i < 0) return; + let ta: Uint8Array = new Uint8Array(sab); + ta[i] = value; + + const assert = require('assert'); + + // SharedArrayBuffer shares storage when it is transported, + // so elements with index > i have been set to {value} by those finished zone.executions. + let expected: string = (global).constructExpectedResult(i, ta.length, value); + assert.equal(ta.toString(), expected); + + const napa = require('../lib/index'); + let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; + zone.execute( + recursivelySetElementOfSharedArrayBuffer, + [zoneId, sab, i - 1, value] + ).then((result: napa.zone.Result) => { + // SharedArrayBuffer shares storage when it is transported, + // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute, + // so ta.toString() should be larger than {expected} constructed before. + if (i > 0) assert(ta.toString() > expected); + else if (i === 0) assert.equal(ta.toString(), expected); + else assert(false); + }); + } + // @node: node -> napa -> napa -> node -> node -> napa -> napa it('@node: recursively transport received SharedArrayBuffer (SAB)', () => { - return transportBuiltin.recursivelyTransportSharedArrayBuffer(8, 50); + let size: number = 8; + let timeout: number = 50; + let value: number = 255; + let sab: SharedArrayBuffer = new SharedArrayBuffer(size); + let ta: Uint8Array = new Uint8Array(sab); + recursivelySetElementOfSharedArrayBuffer(zoneId, sab, size - 1, value); + + return new Promise((resolve, reject) => { + setTimeout(() => { + // Because SharedArrayBuffer will share storage when it is transported, + // once the recursive process finished, all elements of + // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}. + let expected = (global).constructExpectedResult(0, ta.length, value); + assert.equal(ta.toString(), expected); + resolve(); + }, timeout); + }); }); + function recursivelySetElementOfTypedArray_SAB(zoneId: string, ta: Uint8Array, i: number, value: number) { + if (i < 0) return; + ta[i] = value; + + const assert = require('assert'); + + // SharedArrayBuffer shares storage when it is transported, + // so elements with index > i have been set to {value} by those finished zone.executions. + let expected: string = (global).constructExpectedResult(i, ta.length, value); + assert.equal(ta.toString(), expected); + + const napa = require('../lib/index'); + let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; + zone.execute( + recursivelySetElementOfTypedArray_SAB, + [zoneId, ta, i - 1, value] + ).then((result: napa.zone.Result) => { + // SharedArrayBuffer shares storage when it is transported, + // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute, + // so ta.toString() should be larger than {expected} constructed before. + if (i > 0) assert(ta.toString() > expected); + else if (i === 0) assert.equal(ta.toString(), expected); + else assert(false); + }); + } + // @node: node -> napa -> napa -> node -> node -> napa -> napa it('@node: recursively transport received TypedArray based on SAB', () => { - return transportBuiltin.recursivelyTransportTypedArray_SAB(8, 50); + let size: number = 8; + let timeout: number = 50; + let value: number = 255; + let sab: SharedArrayBuffer = new SharedArrayBuffer(size); + let ta: Uint8Array = new Uint8Array(sab); + recursivelySetElementOfTypedArray_SAB(zoneId, ta, size - 1, value); + + return new Promise((resolve, reject) => { + setTimeout(() => { + // Because SharedArrayBuffer will share storage when it is transported, + // once the recursive process finished, all elements of + // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}. + let expected: string = (global).constructExpectedResult(0, ta.length, value); + assert.equal(ta.toString(), expected); + resolve(); + }, timeout); + }); }); + function recursivelySetElementOfArrayBuffer(zoneId: string, ab: ArrayBuffer, i: number, value: number) { + if (i < 0) { + return; + } + + let ta: Uint8Array = new Uint8Array(ab); + ta[i] = value; + + const assert = require('assert'); + + // ArrayBuffer's storage will be copied when it is transported. + // Elements with index > i should all be {value}. + // They are copied from the previous zone.execution. + let expected: string = (global).constructExpectedResult(i, ta.length, value); + assert.equal(ta.toString(), expected); + + const napa = require('../lib/index'); + let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; + zone.execute( + recursivelySetElementOfArrayBuffer, + [zoneId, ab, i - 1, value] + ).then((result: napa.zone.Result) => { + // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute. + assert.equal(ta.toString(), expected); + }); + } + // @node: node -> napa -> napa -> node -> node -> napa -> napa it('@node: recursively transport received ArrayBuffer (AB)', () => { - return transportBuiltin.recursivelyTransportArrayBuffer(8, 50); + let size: number = 8; + let timeout: number = 50; + let value: number = 255; + let ab: ArrayBuffer = new ArrayBuffer(size); + let ta: Uint8Array = new Uint8Array(ab); + recursivelySetElementOfArrayBuffer(zoneId, ab, size - 1, value); + + return new Promise((resolve, reject) => { + setTimeout(() => { + // Except ta[ta-length -1] was set to {value} before the 1st transportation, + // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution. + let expected: string = (global).constructExpectedResult(ta.length - 1, ta.length, value); + assert.equal(ta.toString(), expected); + resolve(); + }, timeout); + }); }); + function recursivelySetElementOfTypeArray_AB(zoneId: string, ta: Uint8Array, i: number, value: number) { + if (i < 0) { + return; + } + + ta[i] = value; + + const assert = require('assert'); + + // ArrayBuffer's storage will be copied when it is transported. + // Elements with index > i should all be {value}. + // They are copied from the previous zone.execution. + let expected: string = (global).constructExpectedResult(i, ta.length, value); + assert.equal(ta.toString(), expected); + + const napa = require('../lib/index'); + let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node; + zone.execute( + recursivelySetElementOfTypeArray_AB, + [zoneId, ta, i - 1, value] + ).then((result: napa.zone.Result) => { + // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute. + assert.equal(ta.toString(), expected); + }); + } + // @node: node -> napa -> napa -> node -> node -> napa -> napa it('@node: recursively transport received TypedArray based on AB', () => { - return transportBuiltin.recursivelyTransportTypedArray_AB(8, 50); + let size: number = 8; + let timeout: number = 50; + let value: number = 255; + let ab: ArrayBuffer = new ArrayBuffer(size); + let ta: Uint8Array = new Uint8Array(ab); + recursivelySetElementOfTypeArray_AB(zoneId, ta, size - 1, value); + + return new Promise((resolve, reject) => { + setTimeout(() => { + // Except ta[ta-length -1] was set to {value} before the 1st transportation, + // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution. + let expected: string = (global).constructExpectedResult(ta.length - 1, ta.length, value); + assert.equal(ta.toString(), expected); + resolve(); + }, timeout); + }); }); } - var builtinTestGroup = 'Transport built-in objects'; - if (process.version >= 'v9.0.0' || process.version.indexOf('.') > 2) { + let builtinTestGroup = 'Transport built-in objects'; + let nodeVersionMajor = parseInt(process.versions.node.split('.')[0]); + if (nodeVersionMajor >= 9) { describe(builtinTestGroup, transportBuiltinObjects); } else { describe.skip(builtinTestGroup, transportBuiltinObjects); - require('npmlog').warn(builtinTestGroup, 'This test group is skipped since it requires node newer than v9.0.0'); + require('npmlog').warn(builtinTestGroup, 'This test group is skipped since it requires node v9.0.0 or above.'); } -}); \ No newline at end of file +}); diff --git a/test/tsconfig.json b/test/tsconfig.json index 7de6990a..feda6f82 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -6,6 +6,6 @@ "noImplicitAny": true, "declaration": false, "preserveConstEnums": true, - "lib": [ "es2015" ] + "lib": [ "es2017" ] } } \ No newline at end of file