From b34ff7dc0d1077346eca9268e74a8f959db1211d Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Fri, 24 Jan 2025 12:55:23 +0100 Subject: [PATCH 1/6] [JS API] Refactoring test utils Signed-off-by: Kirill Suvorov --- src/bindings/js/node/package.json | 2 +- src/bindings/js/node/scripts/lib/utils.js | 15 +++----- .../node/tests/e2e/demo-electron-app/index.js | 9 +++-- .../js/node/tests/e2e/electron-app.test.js | 2 +- .../js/node/tests/{unit => }/setup.js | 0 src/bindings/js/node/tests/unit/basic.test.js | 16 ++++---- .../js/node/tests/unit/compiled_model.test.js | 7 ++-- src/bindings/js/node/tests/unit/core.test.js | 9 +++-- .../js/node/tests/unit/infer_request.test.js | 22 +++++------ src/bindings/js/node/tests/unit/model.test.js | 9 ++--- .../tests/unit/pre_post_processor.test.js | 9 ++--- .../js/node/tests/unit/read_model.test.js | 21 +++++------ .../js/node/tests/unit/tensor.test.js | 3 +- .../js/node/tests/{unit => }/utils.js | 37 ++++++++----------- 14 files changed, 77 insertions(+), 84 deletions(-) rename src/bindings/js/node/tests/{unit => }/setup.js (100%) rename src/bindings/js/node/tests/{unit => }/utils.js (73%) 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/scripts/lib/utils.js b/src/bindings/js/node/scripts/lib/utils.js index 9658ec504fa0d9..a1f5816dad134f 100644 --- a/src/bindings/js/node/scripts/lib/utils.js +++ b/src/bindings/js/node/scripts/lib/utils.js @@ -57,18 +57,15 @@ async function checkIfPathExists(path) { * * @function downloadFile * @param {string} url - The file URL. - * @param {string} filename - The filename of result file. - * @param {string} destination - The destination path of result file. + * @param {string} filePath - Path to downloaded file. * @param {string} [proxy=null] - (Optional) The proxy URL. * @returns {Promise} - Path to downloaded file. */ -function downloadFile(url, destination, filename, proxy = null) { - console.log(`Downloading file by link: ${url} to ${destination}` - + `with filename: ${filename}`); +function downloadFile(url, filePath, proxy = null) { + console.log(`Downloading file by link: ${url} to ${filePath}.`); const timeout = 5000; - const fullPath = path.resolve(destination, filename); - const file = createWriteStream(fullPath); + const file = createWriteStream(filePath); if (new URL(url).protocol === 'http:') throw new Error('Http link doesn\'t support'); @@ -98,8 +95,8 @@ function downloadFile(url, destination, filename, proxy = null) { file.on('finish', () => { file.close(); - console.log(`File was successfully downloaded to '${fullPath}'.`); - resolve(fullPath); + console.log(`File was successfully downloaded to '${filePath}'.`); + resolve(filePath); }); }); diff --git a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js index 58cc6b3b3cf450..c3c2dca230d319 100644 --- a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js +++ b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js @@ -1,8 +1,9 @@ const { app } = require('electron'); const { addon: ov } = require('openvino-node'); +const { testModels, lengthFromShape } = require('../../utils.js'); const epsilon = 0.5; // To avoid very small numbers -const pathToModel = '../tests/unit/test_models/test_model_fp32.xml'; +const testModelFP32 = testModels.testModelFP32; main(); @@ -15,17 +16,17 @@ async function main() { const core = new ov.Core(); console.log('Created OpenVINO Runtime Core'); - const model = await core.readModel(pathToModel); + const model = await core.readModel(testModelFP32.xml); console.log('Model read successfully:', model); const compiledModel = await core.compileModel(model, 'CPU'); const inferRequest = compiledModel.createInferRequest(); console.log('Infer request created:', inferRequest); const tensorData = Float32Array.from( - { length: 3072 }, + { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); - const tensor = new ov.Tensor(ov.element.f32, [1, 3, 32, 32], tensorData); + const tensor = new ov.Tensor(ov.element.f32, testModelFP32.inputShape, tensorData); console.log('Tensor created:', tensor); const result = await inferRequest.inferAsync([tensor]); 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..a52d0359aef099 100644 --- a/src/bindings/js/node/tests/unit/basic.test.js +++ b/src/bindings/js/node/tests/unit/basic.test.js @@ -11,14 +11,15 @@ 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.testModelFP32 + const testXml = testModelFP32.xml; let core = null; let model = null; let compiledModel = null; @@ -27,8 +28,7 @@ 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(() => { @@ -277,8 +277,8 @@ 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,7 +290,7 @@ describe('ov basic tests.', () => { before(() => { tensor = Float32Array.from( - { length: 3072 }, + { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); const core = new ov.Core(); 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..e0e4e33e5c264f 100644 --- a/src/bindings/js/node/tests/unit/compiled_model.test.js +++ b/src/bindings/js/node/tests/unit/compiled_model.test.js @@ -5,7 +5,7 @@ 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; @@ -13,8 +13,9 @@ describe('ov.CompiledModel tests', () => { let compiledModel = null; before(async () => { - await isModelAvailable(testModels.testModelFP32); - testXml = getModelPath().xml; + const testModelFP32 = testModels.testModelFP32; + await isModelAvailable(testModelFP32); + testXml = testModelFP32.xml; core = new ov.Core(); }); diff --git a/src/bindings/js/node/tests/unit/core.test.js b/src/bindings/js/node/tests/unit/core.test.js index f62adda9f90f9c..4e280d0b71dd96 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.testModelFP32; 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..1887ff50f00b48 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,12 @@ 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.testModelFP32; let compiledModel = null; let tensorData = null; let tensor = null; @@ -18,18 +18,18 @@ 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 +43,7 @@ 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 +51,7 @@ 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 +102,7 @@ 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 +110,7 @@ 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..8726d4cf0e5d03 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.testModelFP32; 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..10738effe7c7e4 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.testModelFP32; 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..647f193695bf2b 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.testModelFP32; 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 73% rename from src/bindings/js/node/tests/unit/utils.js rename to src/bindings/js/node/tests/utils.js index 232e4939f421c9..5b7e0c13532b7d 100644 --- a/src/bindings/js/node/tests/unit/utils.js +++ b/src/bindings/js/node/tests/utils.js @@ -7,13 +7,15 @@ const fs = require('node:fs/promises'); const { downloadFile, checkIfPathExists, -} = require('../../scripts/lib/utils'); +} = require('../scripts/lib/utils'); const modelDir = 'tests/unit/test_models/'; const testModels = { testModelFP32: { - xml: 'test_model_fp32.xml', - bin: 'test_model_fp32.bin', + xml: path.join(modelDir, 'test_model_fp32.xml'), + bin: path.join(modelDir, '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 +26,10 @@ const testModels = { module.exports = { compareModels, sleep, - getModelPath, downloadTestModel, isModelAvailable, testModels, + lengthFromShape, }; function compareModels(model1, model2) { @@ -59,32 +61,26 @@ 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, model.xml, proxyUrl); + + const weightsExists = await checkIfPathExists(model.bin); + if (!weightsExists) await downloadFile(model.binURL, model.bin, proxyUrl); + } catch(error) { console.error(`Failed to download the model: ${error}.`); throw error; @@ -93,8 +89,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( From de8c7069941b7ef8348e20e9111a21202ffd9d38 Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Mon, 27 Jan 2025 10:59:35 +0100 Subject: [PATCH 2/6] fix model path for electorn test --- src/bindings/js/node/tests/e2e/demo-electron-app/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js index c3c2dca230d319..ee98f7df1ab243 100644 --- a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js +++ b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js @@ -1,9 +1,10 @@ const { app } = require('electron'); const { addon: ov } = require('openvino-node'); const { testModels, lengthFromShape } = require('../../utils.js'); +const path = require('path'); const epsilon = 0.5; // To avoid very small numbers -const testModelFP32 = testModels.testModelFP32; +const testModelFP32 = path.join('..', testModels.testModelFP32); main(); From e1f17758060fead377e7e591a72c7ab75484af5b Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Mon, 27 Jan 2025 13:03:55 +0100 Subject: [PATCH 3/6] fix lint --- src/bindings/js/node/scripts/lib/utils.js | 1 - .../node/tests/e2e/demo-electron-app/index.js | 6 ++- src/bindings/js/node/tests/unit/basic.test.js | 7 +++- .../js/node/tests/unit/infer_request.test.js | 38 +++++++++++++++---- src/bindings/js/node/tests/utils.js | 17 ++++++--- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/bindings/js/node/scripts/lib/utils.js b/src/bindings/js/node/scripts/lib/utils.js index a1f5816dad134f..35a144872921d8 100644 --- a/src/bindings/js/node/scripts/lib/utils.js +++ b/src/bindings/js/node/scripts/lib/utils.js @@ -1,4 +1,3 @@ -const path = require('node:path'); const https = require('node:https'); const fs = require('node:fs/promises'); const { createWriteStream } = require('node:fs'); diff --git a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js index ee98f7df1ab243..6ffd1f63cb36b9 100644 --- a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js +++ b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js @@ -27,7 +27,11 @@ async function main() { { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); - const tensor = new ov.Tensor(ov.element.f32, testModelFP32.inputShape, tensorData); + const tensor = new ov.Tensor( + ov.element.f32, + testModelFP32.inputShape, + tensorData, + ); console.log('Tensor created:', tensor); const result = await inferRequest.inferAsync([tensor]); diff --git a/src/bindings/js/node/tests/unit/basic.test.js b/src/bindings/js/node/tests/unit/basic.test.js index a52d0359aef099..f511da59923bf1 100644 --- a/src/bindings/js/node/tests/unit/basic.test.js +++ b/src/bindings/js/node/tests/unit/basic.test.js @@ -18,7 +18,7 @@ const { const epsilon = 0.5; describe('ov basic tests.', () => { - const testModelFP32 = testModels.testModelFP32 + const { testModelFP32 } = testModels; const testXml = testModelFP32.xml; let core = null; let model = null; @@ -278,7 +278,10 @@ describe('ov basic tests.', () => { assert.strictEqual(obj.input().anyName, 'data'); assert.deepStrictEqual(obj.input(0).shape, testModelFP32.inputShape); - assert.deepStrictEqual(obj.input(0).getShape(), testModelFP32.inputShape); + assert.deepStrictEqual( + obj.input(0).getShape(), + testModelFP32.inputShape, + ); }); }); }); 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 1887ff50f00b48..c2bb0ece634e64 100644 --- a/src/bindings/js/node/tests/unit/infer_request.test.js +++ b/src/bindings/js/node/tests/unit/infer_request.test.js @@ -5,7 +5,11 @@ const { addon: ov } = require('../..'); const assert = require('assert'); const { describe, it, before, beforeEach } = require('node:test'); -const { testModels, isModelAvailable, lengthFromShape } = require('../utils.js'); +const { + testModels, + isModelAvailable, + lengthFromShape, +} = require('../utils.js'); const epsilon = 0.5; // To avoid very small numbers @@ -28,8 +32,16 @@ describe('ov.InferRequest tests', () => { { length: lengthFromShape(testModelFP32.inputShape) }, () => Math.random() + epsilon, ); - tensor = new ov.Tensor(ov.element.f32, testModelFP32.inputShape, tensorData); - resTensor = new ov.Tensor(ov.element.f32, testModelFP32.outputShape, 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, lengthFromShape(testModelFP32.outputShape)); + 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, lengthFromShape(testModelFP32.outputShape)); + 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, lengthFromShape(testModelFP32.outputShape)); + 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, lengthFromShape(testModelFP32.outputShape)); + assert.deepStrictEqual( + result['fc_out'].data.length, + lengthFromShape(testModelFP32.outputShape), + ); }); }); diff --git a/src/bindings/js/node/tests/utils.js b/src/bindings/js/node/tests/utils.js index 5b7e0c13532b7d..2832c9fbd55669 100644 --- a/src/bindings/js/node/tests/utils.js +++ b/src/bindings/js/node/tests/utils.js @@ -10,10 +10,15 @@ const { } = require('../scripts/lib/utils'); const modelDir = 'tests/unit/test_models/'; + +function getModelPath(fileName) { + return path.join(modelDir, fileName); +} + const testModels = { testModelFP32: { - xml: path.join(modelDir, 'test_model_fp32.xml'), - bin: path.join(modelDir, '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: @@ -62,7 +67,10 @@ function sleep(ms) { } function lengthFromShape(shape) { - return shape.reduce((accumulator, currentValue) => accumulator * currentValue, 1); + return shape.reduce( + (accumulator, currentValue) => accumulator * currentValue, + 1 + ); } async function downloadTestModel(model) { @@ -80,7 +88,7 @@ async function downloadTestModel(model) { const weightsExists = await checkIfPathExists(model.bin); if (!weightsExists) await downloadFile(model.binURL, model.bin, proxyUrl); - + } catch(error) { console.error(`Failed to download the model: ${error}.`); throw error; @@ -88,7 +96,6 @@ async function downloadTestModel(model) { } async function isModelAvailable(model) { - const baseArtifactsDir = './tests/unit/test_models'; const modelExists = await checkIfPathExists(model.xml); if (modelExists) return; From 3d2917ce9d06197dbb344120532ee57374210b5d Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Mon, 27 Jan 2025 18:03:03 +0100 Subject: [PATCH 4/6] use destructuring --- src/bindings/js/.eslintrc-global.js | 1 + src/bindings/js/node/tests/unit/compiled_model.test.js | 2 +- src/bindings/js/node/tests/unit/core.test.js | 2 +- src/bindings/js/node/tests/unit/infer_request.test.js | 2 +- src/bindings/js/node/tests/unit/model.test.js | 2 +- src/bindings/js/node/tests/unit/pre_post_processor.test.js | 2 +- src/bindings/js/node/tests/unit/read_model.test.js | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) 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/tests/unit/compiled_model.test.js b/src/bindings/js/node/tests/unit/compiled_model.test.js index e0e4e33e5c264f..a12fbeddf85c85 100644 --- a/src/bindings/js/node/tests/unit/compiled_model.test.js +++ b/src/bindings/js/node/tests/unit/compiled_model.test.js @@ -13,7 +13,7 @@ describe('ov.CompiledModel tests', () => { let compiledModel = null; before(async () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; await isModelAvailable(testModelFP32); testXml = testModelFP32.xml; core = new ov.Core(); diff --git a/src/bindings/js/node/tests/unit/core.test.js b/src/bindings/js/node/tests/unit/core.test.js index 4e280d0b71dd96..02fa13c90f1b94 100644 --- a/src/bindings/js/node/tests/unit/core.test.js +++ b/src/bindings/js/node/tests/unit/core.test.js @@ -8,7 +8,7 @@ const { describe, it, before, beforeEach } = require('node:test'); const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.Core tests', () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; let core = null; before(async () => { await isModelAvailable(testModelFP32); 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 c2bb0ece634e64..b324630d08d6d2 100644 --- a/src/bindings/js/node/tests/unit/infer_request.test.js +++ b/src/bindings/js/node/tests/unit/infer_request.test.js @@ -14,7 +14,7 @@ const { const epsilon = 0.5; // To avoid very small numbers describe('ov.InferRequest tests', () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; let compiledModel = null; let tensorData = null; let tensor = null; diff --git a/src/bindings/js/node/tests/unit/model.test.js b/src/bindings/js/node/tests/unit/model.test.js index 8726d4cf0e5d03..ff34141a15154f 100644 --- a/src/bindings/js/node/tests/unit/model.test.js +++ b/src/bindings/js/node/tests/unit/model.test.js @@ -8,7 +8,7 @@ const { describe, it, before, beforeEach } = require('node:test'); const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.Model tests', () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; let core = null; let model = null; 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 10738effe7c7e4..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 @@ -8,7 +8,7 @@ const { describe, it, before, beforeEach } = require('node:test'); const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.preprocess.PrePostProcessor tests', () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; let core = null; let model = null; 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 647f193695bf2b..dbfa70566dab1e 100644 --- a/src/bindings/js/node/tests/unit/read_model.test.js +++ b/src/bindings/js/node/tests/unit/read_model.test.js @@ -9,7 +9,7 @@ const { describe, it, before, beforeEach } = require('node:test'); const { testModels, isModelAvailable } = require('../utils.js'); describe('Tests for reading model.', () => { - const testModelFP32 = testModels.testModelFP32; + const { testModelFP32 } = testModels; let modelFile = null; let modelStr = null; let weightsFile = null; From 8899e7dfca3c2f93174f968a4da6f80a83f67d9e Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Mon, 27 Jan 2025 18:19:04 +0100 Subject: [PATCH 5/6] Leave the previous readFile params --- src/bindings/js/node/scripts/lib/utils.js | 16 ++++++++++------ src/bindings/js/node/tests/utils.js | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/bindings/js/node/scripts/lib/utils.js b/src/bindings/js/node/scripts/lib/utils.js index 35a144872921d8..9658ec504fa0d9 100644 --- a/src/bindings/js/node/scripts/lib/utils.js +++ b/src/bindings/js/node/scripts/lib/utils.js @@ -1,3 +1,4 @@ +const path = require('node:path'); const https = require('node:https'); const fs = require('node:fs/promises'); const { createWriteStream } = require('node:fs'); @@ -56,15 +57,18 @@ async function checkIfPathExists(path) { * * @function downloadFile * @param {string} url - The file URL. - * @param {string} filePath - Path to downloaded file. + * @param {string} filename - The filename of result file. + * @param {string} destination - The destination path of result file. * @param {string} [proxy=null] - (Optional) The proxy URL. * @returns {Promise} - Path to downloaded file. */ -function downloadFile(url, filePath, proxy = null) { - console.log(`Downloading file by link: ${url} to ${filePath}.`); +function downloadFile(url, destination, filename, proxy = null) { + console.log(`Downloading file by link: ${url} to ${destination}` + + `with filename: ${filename}`); const timeout = 5000; - const file = createWriteStream(filePath); + const fullPath = path.resolve(destination, filename); + const file = createWriteStream(fullPath); if (new URL(url).protocol === 'http:') throw new Error('Http link doesn\'t support'); @@ -94,8 +98,8 @@ function downloadFile(url, filePath, proxy = null) { file.on('finish', () => { file.close(); - console.log(`File was successfully downloaded to '${filePath}'.`); - resolve(filePath); + console.log(`File was successfully downloaded to '${fullPath}'.`); + resolve(fullPath); }); }); diff --git a/src/bindings/js/node/tests/utils.js b/src/bindings/js/node/tests/utils.js index 2832c9fbd55669..8fd852af6da086 100644 --- a/src/bindings/js/node/tests/utils.js +++ b/src/bindings/js/node/tests/utils.js @@ -83,11 +83,21 @@ async function downloadTestModel(model) { const { env } = process; const proxyUrl = env.http_proxy || env.HTTP_PROXY || env.npm_config_proxy; - const modelExists = await checkIfPathExists(model.xml); - if (!modelExists) await downloadFile(model.xmlURL, model.xml, 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, model.bin, proxyUrl); + 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}.`); From 6fffea0a2ecb3eaccebdbc042ba876fbb8744876 Mon Sep 17 00:00:00 2001 From: Kirill Suvorov Date: Tue, 28 Jan 2025 15:23:02 +0100 Subject: [PATCH 6/6] some extra fixes --- .../js/node/tests/e2e/demo-electron-app/index.js | 14 ++++---------- src/bindings/js/node/tests/unit/basic.test.js | 13 ++++++------- .../js/node/tests/unit/compiled_model.test.js | 10 ++++++---- src/bindings/js/node/tests/utils.js | 2 +- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js index 6ffd1f63cb36b9..58cc6b3b3cf450 100644 --- a/src/bindings/js/node/tests/e2e/demo-electron-app/index.js +++ b/src/bindings/js/node/tests/e2e/demo-electron-app/index.js @@ -1,10 +1,8 @@ const { app } = require('electron'); const { addon: ov } = require('openvino-node'); -const { testModels, lengthFromShape } = require('../../utils.js'); -const path = require('path'); const epsilon = 0.5; // To avoid very small numbers -const testModelFP32 = path.join('..', testModels.testModelFP32); +const pathToModel = '../tests/unit/test_models/test_model_fp32.xml'; main(); @@ -17,21 +15,17 @@ async function main() { const core = new ov.Core(); console.log('Created OpenVINO Runtime Core'); - const model = await core.readModel(testModelFP32.xml); + const model = await core.readModel(pathToModel); console.log('Model read successfully:', model); const compiledModel = await core.compileModel(model, 'CPU'); const inferRequest = compiledModel.createInferRequest(); console.log('Infer request created:', inferRequest); const tensorData = Float32Array.from( - { length: lengthFromShape(testModelFP32.inputShape) }, + { length: 3072 }, () => Math.random() + epsilon, ); - const tensor = new ov.Tensor( - ov.element.f32, - testModelFP32.inputShape, - tensorData, - ); + const tensor = new ov.Tensor(ov.element.f32, [1, 3, 32, 32], tensorData); console.log('Tensor created:', tensor); const result = await inferRequest.inferAsync([tensor]); diff --git a/src/bindings/js/node/tests/unit/basic.test.js b/src/bindings/js/node/tests/unit/basic.test.js index f511da59923bf1..eb57e29583db45 100644 --- a/src/bindings/js/node/tests/unit/basic.test.js +++ b/src/bindings/js/node/tests/unit/basic.test.js @@ -19,7 +19,6 @@ const epsilon = 0.5; describe('ov basic tests.', () => { const { testModelFP32 } = testModels; - const testXml = testModelFP32.xml; let core = null; let model = null; let compiledModel = null; @@ -33,7 +32,7 @@ describe('ov basic tests.', () => { 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]); }); }); @@ -297,7 +296,7 @@ describe('ov basic tests.', () => { () => 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 a12fbeddf85c85..4f41636371893a 100644 --- a/src/bindings/js/node/tests/unit/compiled_model.test.js +++ b/src/bindings/js/node/tests/unit/compiled_model.test.js @@ -8,14 +8,12 @@ const { describe, it, before, beforeEach } = require('node:test'); const { testModels, isModelAvailable } = require('../utils.js'); describe('ov.CompiledModel tests', () => { - let testXml = null; + const { testModelFP32 } = testModels; let core = null; let compiledModel = null; before(async () => { - const { testModelFP32 } = testModels; await isModelAvailable(testModelFP32); - testXml = testModelFP32.xml; core = new ov.Core(); }); @@ -23,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/utils.js b/src/bindings/js/node/tests/utils.js index 8fd852af6da086..88f48066d1abf2 100644 --- a/src/bindings/js/node/tests/utils.js +++ b/src/bindings/js/node/tests/utils.js @@ -83,7 +83,7 @@ async function downloadTestModel(model) { const { env } = process; const proxyUrl = env.http_proxy || env.HTTP_PROXY || env.npm_config_proxy; - const modelExists = await checkIfPathExists(model.xml); + const modelExists = await checkIfPathExists(model.xml); if (!modelExists) await downloadFile( model.xmlURL, path.dirname(model.xml),