diff --git a/src/bindings/js/.eslintrc-global.js b/src/bindings/js/.eslintrc-global.js index 7f4abc54561495..49fac29db5f69f 100644 --- a/src/bindings/js/.eslintrc-global.js +++ b/src/bindings/js/.eslintrc-global.js @@ -23,6 +23,7 @@ module.exports = { 'key-spacing': ['error', { beforeColon: false }], 'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }], 'keyword-spacing': ['error', { overrides: { catch: { after: false } } }], + 'prefer-destructuring': ["error", { "object": true, "array": false }], '@typescript-eslint/no-var-requires': 0, } }; diff --git a/src/bindings/js/node/package.json b/src/bindings/js/node/package.json index 0dab709718ae9b..832d46f031bfa8 100644 --- a/src/bindings/js/node/package.json +++ b/src/bindings/js/node/package.json @@ -18,7 +18,7 @@ "build": "npm run tsc", "prepare": "npm run build", "lint": "eslint .", - "test_setup": "node ./tests/unit/setup.js", + "test_setup": "node ./tests/setup.js", "test": "npm run test_setup && node --test ./tests/unit/*.test.js", "test:e2e": "mocha ./tests/e2e/electron-app.test.js", "tsc": "tsc", diff --git a/src/bindings/js/node/tests/e2e/electron-app.test.js b/src/bindings/js/node/tests/e2e/electron-app.test.js index 98982a5f941263..9cd900d7705a6c 100644 --- a/src/bindings/js/node/tests/e2e/electron-app.test.js +++ b/src/bindings/js/node/tests/e2e/electron-app.test.js @@ -4,7 +4,7 @@ const util = require('node:util'); const assert = require('node:assert'); const { exec } = require('child_process'); const execPromise = util.promisify(exec); -const { testModels, downloadTestModel } = require('../unit/utils.js'); +const { testModels, downloadTestModel } = require('../utils.js'); describe('E2E testing for OpenVINO as an Electron dependency.', function() { this.timeout(50000); diff --git a/src/bindings/js/node/tests/unit/setup.js b/src/bindings/js/node/tests/setup.js similarity index 100% rename from src/bindings/js/node/tests/unit/setup.js rename to src/bindings/js/node/tests/setup.js diff --git a/src/bindings/js/node/tests/unit/basic.test.js b/src/bindings/js/node/tests/unit/basic.test.js index bdafca9260f39b..eb57e29583db45 100644 --- a/src/bindings/js/node/tests/unit/basic.test.js +++ b/src/bindings/js/node/tests/unit/basic.test.js @@ -11,14 +11,14 @@ const { after, describe, it, before, beforeEach } = require('node:test'); const { testModels, compareModels, - getModelPath, isModelAvailable, sleep, -} = require('./utils.js'); + lengthFromShape, +} = require('../utils.js'); const epsilon = 0.5; describe('ov basic tests.', () => { - let testXml = null; + const { testModelFP32 } = testModels; let core = null; let model = null; let compiledModel = null; @@ -27,13 +27,12 @@ describe('ov basic tests.', () => { before(async () => { outDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'ov_js_out_')); - await isModelAvailable(testModels.testModelFP32); - testXml = getModelPath().xml; + await isModelAvailable(testModelFP32); }); beforeEach(() => { core = new ov.Core(); - model = core.readModelSync(testXml); + model = core.readModelSync(testModelFP32.xml); compiledModel = core.compileModelSync(model, 'CPU'); modelLike = [model, compiledModel]; }); @@ -139,12 +138,12 @@ describe('ov basic tests.', () => { }); it('compileModelSync(model_path, deviceName, config: {}) ', () => { - const cm = core.compileModelSync(testXml, 'CPU', tput); + const cm = core.compileModelSync(testModelFP32.xml, 'CPU', tput); assert.equal(cm.inputs.length, 1); }); it('compileModelSync(model:model_path, deviceName: string) ', () => { - const cm = core.compileModelSync(testXml, 'CPU'); + const cm = core.compileModelSync(testModelFP32.xml, 'CPU'); assert.deepStrictEqual(cm.output(0).shape, [1, 10]); }); @@ -200,13 +199,13 @@ describe('ov basic tests.', () => { }); it('compileModel(model_path, deviceName, config: {}) ', () => { - core.compileModel(testXml, 'CPU', tput).then((cm) => { + core.compileModel(testModelFP32.xml, 'CPU', tput).then((cm) => { assert.equal(cm.inputs.length, 1); }); }); it('compileModel(model:model_path, deviceName: string) ', () => { - core.compileModel(testXml, 'CPU').then((cm) => { + core.compileModel(testModelFP32.xml, 'CPU').then((cm) => { assert.deepStrictEqual(cm.output(0).shape, [1, 10]); }); }); @@ -277,8 +276,11 @@ describe('ov basic tests.', () => { assert.strictEqual(obj.input().getAnyName(), 'data'); assert.strictEqual(obj.input().anyName, 'data'); - assert.deepStrictEqual(obj.input(0).shape, [1, 3, 32, 32]); - assert.deepStrictEqual(obj.input(0).getShape(), [1, 3, 32, 32]); + assert.deepStrictEqual(obj.input(0).shape, testModelFP32.inputShape); + assert.deepStrictEqual( + obj.input(0).getShape(), + testModelFP32.inputShape, + ); }); }); }); @@ -290,11 +292,11 @@ describe('ov basic tests.', () => { before(() => { tensor = Float32Array.from( - { length: 3072 }, + { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); const core = new ov.Core(); - const model = core.readModelSync(testXml); + const model = core.readModelSync(testModelFP32.xml); const compiledModel = core.compileModelSync(model, 'CPU'); userStream = compiledModel.exportModelSync(); const inferRequest = compiledModel.createInferRequest(); diff --git a/src/bindings/js/node/tests/unit/compiled_model.test.js b/src/bindings/js/node/tests/unit/compiled_model.test.js index e88752512ec40a..4f41636371893a 100644 --- a/src/bindings/js/node/tests/unit/compiled_model.test.js +++ b/src/bindings/js/node/tests/unit/compiled_model.test.js @@ -5,16 +5,15 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, getModelPath, isModelAvailable } = require('./utils.js'); +const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.CompiledModel tests', () => { - let testXml = null; + const { testModelFP32 } = testModels; let core = null; let compiledModel = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); - testXml = getModelPath().xml; + await isModelAvailable(testModelFP32); core = new ov.Core(); }); @@ -22,7 +21,11 @@ describe('ov.CompiledModel tests', () => { const properties = { AUTO_BATCH_TIMEOUT: '1', }; - compiledModel = core.compileModelSync(testXml, 'BATCH:CPU', properties); + compiledModel = core.compileModelSync( + testModelFP32.xml, + 'BATCH:CPU', + properties + ); }); describe('getProperty()', () => { diff --git a/src/bindings/js/node/tests/unit/core.test.js b/src/bindings/js/node/tests/unit/core.test.js index f62adda9f90f9c..02fa13c90f1b94 100644 --- a/src/bindings/js/node/tests/unit/core.test.js +++ b/src/bindings/js/node/tests/unit/core.test.js @@ -5,12 +5,13 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, isModelAvailable, getModelPath } = require('./utils.js'); +const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.Core tests', () => { + const { testModelFP32 } = testModels; let core = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); + await isModelAvailable(testModelFP32); }); beforeEach(() => { @@ -95,7 +96,7 @@ describe('ov.Core tests', () => { }); it('Core.queryModel() with incorrect arguments should throw an error', () => { - const model = core.readModelSync(getModelPath().xml); + const model = core.readModelSync(testModelFP32.xml); assert.throws( () => core.queryModel(model, 'arg1', 'arg2').then(), /'queryModel' method called with incorrect parameters./, @@ -103,7 +104,7 @@ describe('ov.Core tests', () => { }); it('Core.queryModel() should have device in the result values', () => { - const model = core.readModelSync(getModelPath().xml); + const model = core.readModelSync(testModelFP32.xml); const device = 'CPU'; const queryModel = core.queryModel(model, device); assert(Object.values(queryModel).includes(device)); diff --git a/src/bindings/js/node/tests/unit/infer_request.test.js b/src/bindings/js/node/tests/unit/infer_request.test.js index 224781d4b80431..b324630d08d6d2 100644 --- a/src/bindings/js/node/tests/unit/infer_request.test.js +++ b/src/bindings/js/node/tests/unit/infer_request.test.js @@ -5,12 +5,16 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, isModelAvailable, getModelPath } = require('./utils.js'); +const { + testModels, + isModelAvailable, + lengthFromShape, +} = require('../utils.js'); const epsilon = 0.5; // To avoid very small numbers -const testXml = getModelPath().xml; describe('ov.InferRequest tests', () => { + const { testModelFP32 } = testModels; let compiledModel = null; let tensorData = null; let tensor = null; @@ -18,18 +22,26 @@ describe('ov.InferRequest tests', () => { let tensorLike = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); + await isModelAvailable(testModelFP32); const core = new ov.Core(); - const model = core.readModelSync(testXml); + const model = core.readModelSync(testModelFP32.xml); compiledModel = core.compileModelSync(model, 'CPU'); tensorData = Float32Array.from( - { length: 3072 }, + { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); - tensor = new ov.Tensor(ov.element.f32, [1, 3, 32, 32], tensorData); - resTensor = new ov.Tensor(ov.element.f32, [1, 10], tensorData.slice(-10)); + tensor = new ov.Tensor( + ov.element.f32, + testModelFP32.inputShape, + tensorData, + ); + resTensor = new ov.Tensor( + ov.element.f32, + testModelFP32.outputShape, + tensorData.slice(-10), + ); tensorLike = [tensor, tensorData]; }); @@ -43,7 +55,10 @@ describe('ov.InferRequest tests', () => { tensorLike.forEach((tl) => { const result = inferRequest.infer({ data: tl }); assert.deepStrictEqual(Object.keys(result), ['fc_out']); - assert.deepStrictEqual(result['fc_out'].data.length, 10); + assert.deepStrictEqual( + result['fc_out'].data.length, + lengthFromShape(testModelFP32.outputShape) + ); }); }); @@ -51,7 +66,10 @@ describe('ov.InferRequest tests', () => { tensorLike.forEach((tl) => { const result = inferRequest.infer([tl]); assert.deepStrictEqual(Object.keys(result), ['fc_out']); - assert.deepStrictEqual(result['fc_out'].data.length, 10); + assert.deepStrictEqual( + result['fc_out'].data.length, + lengthFromShape(testModelFP32.outputShape), + ); }); }); @@ -102,7 +120,10 @@ describe('ov.InferRequest tests', () => { inferRequest.inferAsync({ data: tensor }).then((result) => { assert.ok(result['fc_out'] instanceof ov.Tensor); assert.deepStrictEqual(Object.keys(result), ['fc_out']); - assert.deepStrictEqual(result['fc_out'].data.length, 10); + assert.deepStrictEqual( + result['fc_out'].data.length, + lengthFromShape(testModelFP32.outputShape), + ); }); }); @@ -110,7 +131,10 @@ describe('ov.InferRequest tests', () => { inferRequest.inferAsync([tensor]).then((result) => { assert.ok(result['fc_out'] instanceof ov.Tensor); assert.deepStrictEqual(Object.keys(result), ['fc_out']); - assert.deepStrictEqual(result['fc_out'].data.length, 10); + assert.deepStrictEqual( + result['fc_out'].data.length, + lengthFromShape(testModelFP32.outputShape), + ); }); }); diff --git a/src/bindings/js/node/tests/unit/model.test.js b/src/bindings/js/node/tests/unit/model.test.js index f4bf6bc78ccd6e..ff34141a15154f 100644 --- a/src/bindings/js/node/tests/unit/model.test.js +++ b/src/bindings/js/node/tests/unit/model.test.js @@ -5,21 +5,20 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, getModelPath, isModelAvailable } = require('./utils.js'); +const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.Model tests', () => { - let testXml = null; + const { testModelFP32 } = testModels; let core = null; let model = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); - testXml = getModelPath().xml; + await isModelAvailable(testModelFP32); core = new ov.Core(); }); beforeEach(() => { - model = core.readModelSync(testXml); + model = core.readModelSync(testModelFP32.xml); }); describe('Model.isDynamic()', () => { diff --git a/src/bindings/js/node/tests/unit/pre_post_processor.test.js b/src/bindings/js/node/tests/unit/pre_post_processor.test.js index c808d62f02887f..47781567dae130 100644 --- a/src/bindings/js/node/tests/unit/pre_post_processor.test.js +++ b/src/bindings/js/node/tests/unit/pre_post_processor.test.js @@ -5,21 +5,20 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, getModelPath, isModelAvailable } = require('./utils.js'); +const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.preprocess.PrePostProcessor tests', () => { - let testXml = null; + const { testModelFP32 } = testModels; let core = null; let model = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); - testXml = getModelPath().xml; + await isModelAvailable(testModelFP32); core = new ov.Core(); }); beforeEach(() => { - model = core.readModelSync(testXml); + model = core.readModelSync(testModelFP32.xml); }); describe('PrePostProcess', () => { diff --git a/src/bindings/js/node/tests/unit/read_model.test.js b/src/bindings/js/node/tests/unit/read_model.test.js index 46817c0c86152b..dbfa70566dab1e 100644 --- a/src/bindings/js/node/tests/unit/read_model.test.js +++ b/src/bindings/js/node/tests/unit/read_model.test.js @@ -6,11 +6,10 @@ const fs = require('node:fs'); const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, isModelAvailable, getModelPath } = require('./utils.js'); - -const { xml: modelPath, bin: weightsPath } = getModelPath(); +const { testModels, isModelAvailable } = require('../utils.js'); describe('Tests for reading model.', () => { + const { testModelFP32 } = testModels; let modelFile = null; let modelStr = null; let weightsFile = null; @@ -18,10 +17,10 @@ describe('Tests for reading model.', () => { let core = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); - modelFile = fs.readFileSync(modelPath); - modelStr = fs.readFileSync(modelPath, 'utf8'); - weightsFile = fs.readFileSync(weightsPath); + await isModelAvailable(testModelFP32); + modelFile = fs.readFileSync(testModelFP32.xml); + modelStr = fs.readFileSync(testModelFP32.xml, 'utf8'); + weightsFile = fs.readFileSync(testModelFP32.bin); }); beforeEach(() => { @@ -35,13 +34,13 @@ describe('Tests for reading model.', () => { describe('Core.readModeSync', () => { it('readModeSync(xmlPath) ', () => { - const model = core.readModelSync(modelPath); + const model = core.readModelSync(testModelFP32.xml); assert.ok(model instanceof ov.Model); assert.equal(model.inputs.length, 1); }); it('readModeSync(xmlPath, weightsPath) ', () => { - const model = core.readModelSync(modelPath, weightsPath); + const model = core.readModelSync(testModelFP32.xml, testModelFP32.bin); assert.ok(model instanceof ov.Model); assert.equal(model.inputs.length, 1); }); @@ -71,12 +70,12 @@ describe('Tests for reading model.', () => { describe('Core.readModel', () => { it('readModel(xmlPath) ', async () => { - const model = await core.readModel(modelPath); + const model = await core.readModel(testModelFP32.xml); assert.equal(model.inputs.length, 1); }); it('readModel(xmlPath, weightsPath) ', async () => { - const model = await core.readModel(modelPath, weightsPath); + const model = await core.readModel(testModelFP32.xml, testModelFP32.bin); assert.equal(model.inputs.length, 1); }); diff --git a/src/bindings/js/node/tests/unit/tensor.test.js b/src/bindings/js/node/tests/unit/tensor.test.js index bdd5d0c4821431..12d2e93733a43d 100644 --- a/src/bindings/js/node/tests/unit/tensor.test.js +++ b/src/bindings/js/node/tests/unit/tensor.test.js @@ -6,6 +6,7 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { test, describe, it, before } = require('node:test'); const getRandomBigInt = require('random-bigint'); +const { lengthFromShape } = require('../utils'); describe('ov.Tensor tests', () => { let shape = null; @@ -260,7 +261,7 @@ describe('ov.Tensor tests', () => { describe('Tensor getSize', () => { it('getSize returns the correct total number of elements', () => { const tensor = new ov.Tensor(ov.element.f32, shape, data); - const expectedSize = shape.reduce((acc, dim) => acc * dim, 1); + const expectedSize = lengthFromShape(shape); assert.strictEqual(tensor.getSize(), expectedSize); }); diff --git a/src/bindings/js/node/tests/unit/utils.js b/src/bindings/js/node/tests/utils.js similarity index 70% rename from src/bindings/js/node/tests/unit/utils.js rename to src/bindings/js/node/tests/utils.js index 232e4939f421c9..88f48066d1abf2 100644 --- a/src/bindings/js/node/tests/unit/utils.js +++ b/src/bindings/js/node/tests/utils.js @@ -7,13 +7,20 @@ const fs = require('node:fs/promises'); const { downloadFile, checkIfPathExists, -} = require('../../scripts/lib/utils'); +} = require('../scripts/lib/utils'); const modelDir = 'tests/unit/test_models/'; + +function getModelPath(fileName) { + return path.join(modelDir, fileName); +} + const testModels = { testModelFP32: { - xml: 'test_model_fp32.xml', - bin: 'test_model_fp32.bin', + xml: getModelPath('test_model_fp32.xml'), + bin: getModelPath('test_model_fp32.bin'), + inputShape: [1, 3, 32, 32], + outputShape: [1, 10], xmlURL: 'https://raw.githubusercontent.com/openvinotoolkit/testdata/master/models/test_model/test_model_fp32.xml', binURL: @@ -24,10 +31,10 @@ const testModels = { module.exports = { compareModels, sleep, - getModelPath, downloadTestModel, isModelAvailable, testModels, + lengthFromShape, }; function compareModels(model1, model2) { @@ -59,32 +66,39 @@ function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } -function getModelPath(isFP16 = false) { - const modelName = `test_model_fp${isFP16 ? 16 : 32}`; - - return { - xml: path.join(modelDir, `${modelName}.xml`), - bin: path.join(modelDir, `${modelName}.bin`), - }; +function lengthFromShape(shape) { + return shape.reduce( + (accumulator, currentValue) => accumulator * currentValue, + 1 + ); } async function downloadTestModel(model) { - const modelsDir = './tests/unit/test_models'; try { - const ifModelsDirectoryExists = await checkIfPathExists(modelsDir); + const ifModelsDirectoryExists = await checkIfPathExists(modelDir); if (!ifModelsDirectoryExists) { await fs.mkdir(modelDir); } - const modelPath = path.join(modelsDir, model.xml); - const modelExists = await checkIfPathExists(modelPath); - if (modelExists) return; - const { env } = process; const proxyUrl = env.http_proxy || env.HTTP_PROXY || env.npm_config_proxy; - await downloadFile(model.xmlURL, modelsDir, model.xml, proxyUrl); - await downloadFile(model.binURL, modelsDir, model.bin, proxyUrl); + const modelExists = await checkIfPathExists(model.xml); + if (!modelExists) await downloadFile( + model.xmlURL, + path.dirname(model.xml), + path.basename(model.xml), + proxyUrl, + ); + + const weightsExists = await checkIfPathExists(model.bin); + if (!weightsExists) await downloadFile( + model.binURL, + path.dirname(model.bin), + path.basename(model.bin), + proxyUrl, + ); + } catch(error) { console.error(`Failed to download the model: ${error}.`); throw error; @@ -92,9 +106,7 @@ async function downloadTestModel(model) { } async function isModelAvailable(model) { - const baseArtifactsDir = './tests/unit/test_models'; - const modelPath = path.join(baseArtifactsDir, model.xml); - const modelExists = await checkIfPathExists(modelPath); + const modelExists = await checkIfPathExists(model.xml); if (modelExists) return; console.log(