Skip to content

Commit 539d108

Browse files
[JS] Refactor tests (openvinotoolkit#3245)
<!-- Keep your pull requests (PRs) as atomic as possible. That increases the likelihood that an individual PR won't be stuck because of adjacent problems, merge conflicts, or code review. Your merged PR is going to appear in the automatically generated release notes on GitHub. So the clearer the title the better. --> ## Description - Downloading the test model has changed. It now uses the utils from the Python tests to convert models with optimum-cli. - GH workflows have been updated to require a new environment. - The deprecated startChat/finishChat has been removed from the LLMPipeline tests. - The StructuredOutput and Parsers tests have been modified to work with any LLM model. Instruct models are no longer required. - Instructions for running the JavaScript tests have been added. <!-- Jira ticket number (e.g., 123). Delete if there's no ticket. --> CVS-180128 ## Checklist: - [x] Tests have been updated or added to cover the new code. <!-- If the change isn't maintenance related, update the tests at https://github.com/openvinotoolkit/openvino.genai/tree/master/tests or explain in the description why the tests don't need an update. --> - [x] This patch fully addresses the ticket. <!--- If follow-up pull requests are needed, specify in description. --> - [x] I have made corresponding changes to the documentation. <!-- Run github.com/\<username>/openvino.genai/actions/workflows/deploy_gh_pages.yml on your fork with your branch as a parameter to deploy a test version with the updated content. Replace this comment with the link to the built docs. --> --------- Signed-off-by: Kirill Suvorov <kirill.suvorov@intel.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent ed2130d commit 539d108

20 files changed

+534
-442
lines changed

.github/workflows/linux.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ jobs:
896896

897897
genai_nodejs_tests:
898898
name: Node.js bindings tests
899-
needs: [ smart_ci, openvino_download, genai_build_nodejs ]
899+
needs: [ smart_ci, openvino_download, genai_build_wheels, genai_build_genai_wheel, genai_build_nodejs ]
900900
if: ${{ fromJSON(needs.smart_ci.outputs.affected_components).JS_API }}
901901
timeout-minutes: 20
902902
defaults:
@@ -914,6 +914,7 @@ jobs:
914914
OV_INSTALL_DIR: ${{ github.workspace }}/ov
915915
SRC_DIR: ${{ github.workspace }}/openvino.genai
916916
INSTALL_DIR: ${{ github.workspace }}/openvino.genai/src/js/bin
917+
PY_INSTALL_DIR: ${{ github.workspace }}/install
917918
NODE_VERSION: 21
918919

919920
steps:
@@ -942,6 +943,20 @@ jobs:
942943
with:
943944
node-version: ${{ env.NODE_VERSION }}
944945

946+
- name: Download Python wheels for JS tests
947+
uses: akashchi/download-artifact@d59a9c15fec3fdb7c9adf09464124d00f9c11415
948+
with:
949+
pattern: "{${{ needs.openvino_download.outputs.ov_artifact_name }},genai_wheels,genai_wheel_python_*}"
950+
path: ${{ env.PY_INSTALL_DIR }}
951+
merge-multiple: true
952+
953+
- name: Install OpenVINO GenAI Python packages (from wheels)
954+
uses: ./openvino.genai/.github/actions/install_wheel
955+
with:
956+
packages: "openvino;openvino_tokenizers[transformers];openvino_genai"
957+
requirements_files: "${{ env.SRC_DIR }}/tests/python_tests/requirements.txt"
958+
local_wheel_dir: ${{ env.PY_INSTALL_DIR }}/wheels
959+
945960
# JS pacakges uses the OpenVINO and OpenVINO GenAI libraries from the bin directory.
946961
# Here we emulate the installation of the openvino-node package from NPM. The latest
947962
# release of the openvino-node package is installed, and we need to update the binaries

.github/workflows/mac.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ jobs:
699699

700700
genai_nodejs_tests:
701701
name: Node.js bindings tests
702-
needs: [ smart_ci, openvino_download, genai_build_nodejs ]
702+
needs: [ smart_ci, openvino_download, genai_build_wheel, genai_build_nodejs ]
703703
# if: ${{ fromJSON(needs.smart_ci.outputs.affected_components).JS_API }}
704704
# nodejs tests fails on mac with: "mutex lock failed: Invalid argument"
705705
# ticket: 179949
@@ -725,7 +725,7 @@ jobs:
725725
- name: Download OpenVINO Artifacts
726726
uses: akashchi/download-artifact@d59a9c15fec3fdb7c9adf09464124d00f9c11415
727727
with:
728-
name: ${{ needs.openvino_download.outputs.ov_artifact_name }}
728+
pattern: "{${{ needs.openvino_download.outputs.ov_artifact_name }},genai_wheels,genai_wheel_python_*}"
729729
path: ${{ env.INSTALL_DIR }}
730730
merge-multiple: true
731731

@@ -741,6 +741,12 @@ jobs:
741741
with:
742742
node-version: ${{ env.NODE_VERSION }}
743743

744+
- name: Setup Python ${{ env.PYTHON_VERSION }}
745+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
746+
with:
747+
python-version: ${{ env.PYTHON_VERSION }}
748+
cache: 'pip'
749+
744750
# JS pacakges uses the OpenVINO and OpenVINO GenAI libraries from the bin directory.
745751
# Here we emulate the installation of the openvino-node package from NPM. The latest
746752
# release of the openvino-node package is installed, and we need to update the binaries
@@ -752,6 +758,13 @@ jobs:
752758
cp -R ${{ env.INSTALL_DIR }}/openvino_node_npm_package/bin node_modules/openvino-node/bin
753759
npm install --verbose
754760
761+
- name: Install OpenVINO GenAI Python packages (from wheels)
762+
uses: ./openvino.genai/.github/actions/install_wheel
763+
with:
764+
packages: "openvino;openvino_tokenizers[transformers];openvino_genai"
765+
requirements_files: "${{ env.SRC_DIR }}/tests/python_tests/requirements.txt"
766+
local_wheel_dir: ${{ env.INSTALL_DIR }}/wheels
767+
755768
- name: Run npm package tests
756769
working-directory: ${{ env.SRC_DIR }}/src/js
757770
run: npm test

.github/workflows/manylinux_2_28.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ jobs:
599599

600600
genai_nodejs_tests:
601601
name: Node.js bindings tests
602-
needs: [ smart_ci, openvino_download, genai_build_nodejs ]
602+
needs: [ smart_ci, openvino_download, genai_build_wheels, genai_build_genai_wheel, genai_build_nodejs ]
603603
if: ${{ fromJSON(needs.smart_ci.outputs.affected_components).JS_API }}
604604
timeout-minutes: 20
605605
defaults:
@@ -617,6 +617,7 @@ jobs:
617617
OV_INSTALL_DIR: ${{ github.workspace }}/ov
618618
SRC_DIR: ${{ github.workspace }}/src
619619
NODE_VERSION: 22
620+
PY_INSTALL_DIR: ${{ github.workspace }}/install
620621

621622
steps:
622623
- name: Clone openvino.genai
@@ -644,6 +645,20 @@ jobs:
644645
with:
645646
node-version: ${{ env.NODE_VERSION }}
646647

648+
- name: Download Python wheels for JS tests
649+
uses: akashchi/download-artifact@d59a9c15fec3fdb7c9adf09464124d00f9c11415
650+
with:
651+
pattern: "{${{ needs.openvino_download.outputs.ov_artifact_name }},genai_wheels,genai_wheel_python_*}"
652+
path: ${{ env.PY_INSTALL_DIR }}
653+
merge-multiple: true
654+
655+
- name: Install OpenVINO GenAI Python packages (from wheels)
656+
uses: ./src/.github/actions/install_wheel
657+
with:
658+
packages: "openvino;openvino_tokenizers[transformers];openvino_genai"
659+
requirements_files: "${{ env.SRC_DIR }}/tests/python_tests/requirements.txt"
660+
local_wheel_dir: ${{ env.PY_INSTALL_DIR }}/wheels
661+
647662
# JS packages uses the OpenVINO and OpenVINO GenAI libraries from the bin directory.
648663
# Here we emulate the installation of the openvino-node package from NPM. The latest
649664
# release of the openvino-node package is installed, and we need to update the binaries

.github/workflows/windows.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ jobs:
950950

951951
genai_nodejs_tests:
952952
name: Node.js bindings tests
953-
needs: [ smart_ci, openvino_download, genai_build_nodejs ]
953+
needs: [ smart_ci, openvino_download, genai_build_wheels, genai_build_genai_wheel, genai_build_nodejs ]
954954
if: ${{ fromJSON(needs.smart_ci.outputs.affected_components).JS_API }}
955955
timeout-minutes: 20
956956
defaults:
@@ -970,10 +970,10 @@ jobs:
970970
path: ${{ env.SRC_DIR }}
971971
submodules: recursive
972972

973-
- name: Download OpenVINO Artifacts
973+
- name: Download build artifacts (OpenVINO + wheels)
974974
uses: akashchi/download-artifact@d59a9c15fec3fdb7c9adf09464124d00f9c11415
975975
with:
976-
name: ${{ needs.openvino_download.outputs.ov_artifact_name }}
976+
pattern: "{${{ needs.openvino_download.outputs.ov_artifact_name }},genai_wheels,genai_wheel_python_*}"
977977
path: ${{ env.INSTALL_DIR }}
978978
merge-multiple: true
979979

@@ -989,6 +989,12 @@ jobs:
989989
with:
990990
node-version: ${{ env.NODE_VERSION }}
991991

992+
- name: Setup Python
993+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
994+
with:
995+
python-version: '3.11'
996+
cache: 'pip'
997+
992998
# JS pacakges uses the OpenVINO and OpenVINO GenAI libraries from the bin directory.
993999
# Here we emulate the installation of the openvino-node package from NPM. The latest
9941000
# release of the openvino-node package is installed, and we need to update the binaries
@@ -1000,6 +1006,13 @@ jobs:
10001006
Copy-Item -Recurse ${{ env.INSTALL_DIR }}/openvino_node_npm_package/bin node_modules/openvino-node/bin
10011007
npm install --verbose
10021008
1009+
- name: Install OpenVINO GenAI Python packages (from wheels)
1010+
uses: ./openvino.genai/.github/actions/install_wheel
1011+
with:
1012+
packages: "openvino;openvino_tokenizers[transformers];openvino_genai"
1013+
requirements_files: "${{ env.SRC_DIR }}/tests/python_tests/requirements.txt"
1014+
local_wheel_dir: ${{ env.INSTALL_DIR }}/wheels
1015+
10031016
- name: Run npm package tests
10041017
working-directory: ${{ env.SRC_DIR }}/src/js
10051018
run: npm test

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ temp/
2424
.repo/
2525
CMakeLists.txt.user
2626
CMakeUserPresets.json
27-
.env
27+
*.env
28+
ov_cache/
2829

2930
*.project
3031
*.cproject

src/js/BUILD.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,45 @@ your `package.json`:
122122
```sh
123123
node -e "const { LLMPipeline } = require('openvino-genai-node'); console.log(LLMPipeline);"
124124
```
125+
126+
## Running Tests
127+
128+
### Set Up the Python Environment
129+
130+
To run the JavaScript tests, you need Python 3.10+ and the following Python packages:
131+
132+
- `openvino-genai`
133+
- `optimum-intel` — for model conversion
134+
135+
Install the required Python dependencies:
136+
```sh
137+
python -m pip install openvino-genai optimum-intel
138+
```
139+
140+
### Running the Tests
141+
142+
Run the following npm script to prepare models and run all JavaScript tests:
143+
```sh
144+
npm test
145+
```
146+
147+
## Running Tests Manually
148+
149+
If you don't want to set up the Python environment, or you would like to run the JavaScript tests manually, follow these steps:
150+
151+
1. Obtain a model (for example, export a model to the OpenVINO IR format from Hugging Face). See the
152+
[Model Preparation Guide](https://openvinotoolkit.github.io/openvino.genai/docs/category/model-preparation) for more details.
153+
154+
2. Set the environment variables with paths to the converted models.
155+
156+
**Test Environment Variables**
157+
158+
- `LLM_PATH` - Path to the LLM model
159+
- `VLM_PATH` - Path to the vision-language model
160+
- `EMBEDDING_MODEL_PATH` - Path to the text embedding model
161+
- `RERANK_MODEL_PATH` - Path to the reranking model
162+
163+
3. Run the tests:
164+
```sh
165+
node --test ./tests/*.test.js
166+
```

src/js/package-lock.json

Lines changed: 0 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/js/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@
3131
"lint": "eslint .",
3232
"postinstall": "node ./scripts/download-runtime.cjs --ignore-if-exists",
3333
"prepare": "npm run build",
34-
"test": "npm run test_setup && node --test ./tests/*.test.js",
35-
"test_setup": "node ./tests/setup.js"
34+
"test": "python ./tests/setup.py --to-env-file test.env && node --env-file=test.env --test ./tests/*.test.js"
3635
},
3736
"dependencies": {
3837
"openvino-node": "2026.0.0"
3938
},
4039
"devDependencies": {
4140
"@eslint/js": "^9.39.1",
42-
"@huggingface/hub": "^0.21.0",
4341
"@types/node": "^24.10.1",
4442
"eslint": "^9.39.1",
4543
"eslint-config-prettier": "^10.1.8",

src/js/tests/bindings.test.js

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,25 @@
11
import { LLMPipeline } from "../dist/addon.js";
22

33
import assert from "node:assert";
4-
import { describe, it, before, after } from "node:test";
5-
import { models } from "./models.js";
4+
import { describe, it, before } from "node:test";
65

7-
const MODEL_PATH = process.env.MODEL_PATH || `./tests/models/${models.LLM.split("/")[1]}`;
6+
const { LLM_PATH } = process.env;
87

9-
describe("bindings", () => {
8+
if (!LLM_PATH) {
9+
throw new Error("Please set LLM_PATH environment variable to run the tests.");
10+
}
11+
12+
describe("LLMPipeline", () => {
1013
let pipeline = null;
1114

1215
before((_, done) => {
1316
pipeline = new LLMPipeline();
1417

15-
pipeline.init(MODEL_PATH, "CPU", {}, (err) => {
16-
if (err) {
17-
console.error(err);
18-
process.exit(1);
19-
}
20-
21-
pipeline.startChat("", (err) => {
22-
if (err) {
23-
console.error(err);
24-
process.exit(1);
25-
}
26-
27-
done();
28-
});
29-
});
30-
});
31-
32-
after((_, done) => {
33-
pipeline.finishChat((err) => {
18+
pipeline.init(LLM_PATH, "CPU", {}, (err) => {
3419
if (err) {
3520
console.error(err);
3621
process.exit(1);
3722
}
38-
3923
done();
4024
});
4125
});
@@ -45,7 +29,7 @@ describe("bindings", () => {
4529

4630
pipeline.generate(
4731
"Continue: 1 2 3",
48-
{ temperature: "0", max_new_tokens: "4" },
32+
{ temperature: 0, max_new_tokens: 4 },
4933
(chunk) => {
5034
output += chunk;
5135
},

0 commit comments

Comments
 (0)