diff --git a/ci/build_test_OnCommit.groovy b/ci/build_test_OnCommit.groovy index e68487d636..6b1032cee9 100644 --- a/ci/build_test_OnCommit.groovy +++ b/ci/build_test_OnCommit.groovy @@ -2,9 +2,29 @@ def image_build_needed = "false" def win_image_build_needed = "false" def client_test_needed = "false" def export_models_changed = "false" +def test_doc_files_linux = "" +def test_doc_files_windows = "" def shortCommit = "" def agent_name_windows = "" +def test_agent_windows = "ovms_win_ptl" def agent_name_linux = "" +def test_agent_linux = "ovms_ptl" +def disable_doc_tests_linux = false +def disable_doc_tests_windows = false + +// Documentation test commit message overrides: +// +// Disable tests: +// [disable_doc_tests_linux] - Skip the Linux documentation tests stage +// [disable_doc_tests_windows] - Skip the Windows documentation tests stage +// +// Override agent node: +// [test_agent_linux=] - Run Linux doc tests on (default: ovms_ptl) +// [test_agent_windows=] - Run Windows doc tests on (default: ovms_win_ptl) +// +// Override file list (space-separated, converted to pytest -k filter joined with ' or '): +// [test_doc_files_linux=] - Use instead of auto-detected list (Linux) +// [test_doc_files_windows=] - Use instead of auto-detected list (Windows) pipeline { agent { @@ -26,29 +46,100 @@ pipeline { echo shortCommit echo sh(script: 'env|sort', returnStdout: true) def git_diff = "" + def diffBase = "" if (env.CHANGE_ID){ // PR - check changes between target branch sh 'git fetch origin ${CHANGE_TARGET}' - git_diff = sh (script: "git diff --name-only \$(git merge-base FETCH_HEAD HEAD)", returnStdout: true).trim() + diffBase = sh(script: 'git merge-base FETCH_HEAD HEAD', returnStdout: true).trim() + git_diff = sh (script: "git diff --name-only ${diffBase}", returnStdout: true).trim() println("git diff:\n${git_diff}") } else { // branches without PR - check changes in last commit + diffBase = 'HEAD^' git_diff = sh (script: "git diff --name-only HEAD^..HEAD", returnStdout: true).trim() } - def matched = (git_diff =~ /src|third_party|external|(\n|^)Dockerfile|(\n|^)Makefile|\.c|\.h|\.bazel|\.bzl|\.groovy|BUILD|create_package\.sh|WORKSPACE|(\n|^)run_unit_tests\.sh|versions\.mk/) - if (matched){ + + if (git_diff =~ /src|third_party|external|(\n|^)Dockerfile|(\n|^)Makefile|\.c|\.h|\.bazel|\.bzl|\.groovy|BUILD|create_package\.sh|WORKSPACE|(\n|^)run_unit_tests\.sh|versions\.mk/) { image_build_needed = "true" } - matched = (git_diff =~ /(\n|^)client/) - if (matched){ + if (git_diff =~ /(\n|^)client/) { client_test_needed = "true" } - def export_models_matched = (git_diff =~ /(\n|^)(demos\/common\/export_models\/|prepare_llm_models\.sh$)/) - if (export_models_matched){ + if (git_diff =~ /(\n|^)(demos\/common\/export_models\/|prepare_llm_models\.sh$)/) { export_models_changed = "true" - } - def win_matched = (git_diff =~ /src|third_party|external|ci|test_install_ovms_service_windows\\.py|\.c|\.h|\.bazel|\.bzl|BUILD|WORKSPACE|\.bat|\.groovy/) - if (win_matched){ + } + if (git_diff =~ /src|third_party|external|ci|test_install_ovms_service_windows\\.py|\.c|\.h|\.bazel|\.bzl|BUILD|WORKSPACE|\.bat|\.groovy/) { win_image_build_needed = "true" } + + // Override flags from commit message, e.g. [disable_doc_tests_linux] + def commitMsg = sh(returnStdout: true, script: "git log -1 --pretty=format:'%B'").trim() + if (commitMsg =~ /\[disable_doc_tests_linux\]/) { + disable_doc_tests_linux = true + println "Commit override: disable_doc_tests_linux = true" + } + if (commitMsg =~ /\[disable_doc_tests_windows\]/) { + disable_doc_tests_windows = true + println "Commit override: disable_doc_tests_windows = true" + } + def agentLinuxDocMatcher = (commitMsg =~ /\[test_agent_linux=([^\]]+)\]/) + def agentLinuxDocValue = agentLinuxDocMatcher ? agentLinuxDocMatcher[0][1] : null + agentLinuxDocMatcher = null // Matcher is not serializable; null it before CPS checkpoint + if (agentLinuxDocValue) { + if (!(agentLinuxDocValue ==~ /[a-zA-Z0-9_-]+/)) { + error "Invalid test_agent_linux override: '${agentLinuxDocValue}'. Only alphanumeric, hyphens and underscores allowed." + } + test_agent_linux = agentLinuxDocValue + println "Commit override: test_agent_linux = ${test_agent_linux}" + } + def agentWindowsDocMatcher = (commitMsg =~ /\[test_agent_windows=([^\]]+)\]/) + def agentWindowsDocValue = agentWindowsDocMatcher ? agentWindowsDocMatcher[0][1] : null + agentWindowsDocMatcher = null // Matcher is not serializable; null it before CPS checkpoint + if (agentWindowsDocValue) { + if (!(agentWindowsDocValue ==~ /[a-zA-Z0-9_-]+/)) { + error "Invalid test_agent_windows override: '${agentWindowsDocValue}'. Only alphanumeric, hyphens and underscores allowed." + } + test_agent_windows = agentWindowsDocValue + println "Commit override: test_agent_windows = ${test_agent_windows}" + } + def docChangedFilesLinuxMatcher = (commitMsg =~ /\[test_doc_files_linux=([^\]]+)\]/) + def docChangedFilesLinuxValue = docChangedFilesLinuxMatcher ? docChangedFilesLinuxMatcher[0][1] : null + docChangedFilesLinuxMatcher = null // Matcher is not serializable; null it before CPS checkpoint + if (docChangedFilesLinuxValue) { + // Validate each entry is a safe .md path (no shell metacharacters) + docChangedFilesLinuxValue.split(' ').each { entry -> + if (!(entry ==~ /[a-zA-Z0-9_\/.\-]+\.md/)) { + error "Invalid test_doc_files_linux entry: '${entry}'. Must be a .md file path with no special characters." + } + } + test_doc_files_linux = docChangedFilesLinuxValue.replaceAll(' ', '\n') + println "Commit override: test_doc_files_linux = ${test_doc_files_linux}" + } else { + test_doc_files_linux = sh (script: "./ci/check_md_code_changes.sh linux ${diffBase}", returnStdout: true).trim() + if (test_doc_files_linux) { + println "test_doc_files_linux = ${test_doc_files_linux}" + } else { + println "No documentation files changed for linux" + } + } + def docChangedFilesWindowsMatcher = (commitMsg =~ /\[test_doc_files_windows=([^\]]+)\]/) + def docChangedFilesWindowsValue = docChangedFilesWindowsMatcher ? docChangedFilesWindowsMatcher[0][1] : null + docChangedFilesWindowsMatcher = null // Matcher is not serializable; null it before CPS checkpoint + if (docChangedFilesWindowsValue) { + // Validate each entry is a safe .md path (no shell metacharacters) + docChangedFilesWindowsValue.split(' ').each { entry -> + if (!(entry ==~ /[a-zA-Z0-9_\/.\-]+\.md/)) { + error "Invalid test_doc_files_windows entry: '${entry}'. Must be a .md file path with no special characters." + } + } + test_doc_files_windows = docChangedFilesWindowsValue.replaceAll(' ', '\n') + println "Commit override: test_doc_files_windows = ${test_doc_files_windows}" + } else { + test_doc_files_windows = sh (script: "./ci/check_md_code_changes.sh windows ${diffBase}", returnStdout: true).trim() + if (test_doc_files_windows) { + println "test_doc_files_windows = ${test_doc_files_windows}" + } else { + println "No documentation files changed for windows" + } + } } } } @@ -108,15 +199,24 @@ pipeline { OVMS_BAZEL_REMOTE_CACHE_URL = "${env.OVMS_BAZEL_REMOTE_CACHE_URL ?: 'http://mclx-23.sclab.intel.com:8666'}" } steps { - script { - def runTestsFlag = export_models_changed == "true" ? "1" : "0" - sh "echo 'Build linux RUN_TESTS=${runTestsFlag} (export_models_changed=${export_models_changed})'" - sh "echo build --remote_cache=${env.OVMS_BAZEL_REMOTE_CACHE_URL} > .user.bazelrc" - sh "echo test:linux --test_env https_proxy=${env.HTTPS_PROXY} >> .user.bazelrc" - sh "echo test:linux --test_env http_proxy=${env.HTTP_PROXY} >> .user.bazelrc" - sh "make ovms_builder_image RUN_TESTS=${runTestsFlag} OPTIMIZE_BUILDING_TESTS=1 OV_USE_BINARY=0 BASE_OS=redhat OVMS_CPP_IMAGE_TAG=${shortCommit} BUILD_IMAGE=openvino/model_server-build:${shortCommit}" - } + script { + def runTestsFlag = export_models_changed == "true" ? "1" : "0" + sh "echo 'Build linux RUN_TESTS=${runTestsFlag} (export_models_changed=${export_models_changed})'" + sh "echo build --remote_cache=${env.OVMS_BAZEL_REMOTE_CACHE_URL} > .user.bazelrc" + sh "echo test:linux --test_env https_proxy=${env.HTTPS_PROXY} >> .user.bazelrc" + sh "echo test:linux --test_env http_proxy=${env.HTTP_PROXY} >> .user.bazelrc" + sh "make ovms_builder_image RUN_TESTS=${runTestsFlag} OPTIMIZE_BUILDING_TESTS=1 OVMS_CPP_IMAGE_TAG=${shortCommit} BUILD_IMAGE=openvino/model_server-build:${shortCommit}" + + // release_image + sh "make release_image RUN_TESTS=0 GPU=1 NPU=1 OVMS_CPP_IMAGE_TAG=${shortCommit} BUILD_IMAGE=openvino/model_server-build:${shortCommit}" + sh "make run_lib_files_test OVMS_CPP_IMAGE_TAG=${shortCommit}" + if ( test_doc_files_linux ) { + sh "docker save openvino/model_server:${shortCommit} | gzip > ovms_release_image.tar.gz" + stash name: 'ovms-release-image', includes: 'ovms_release_image.tar.gz' + sh "rm -f ovms_release_image.tar.gz" } + } + } } stage('Build windows') { agent { @@ -141,6 +241,9 @@ pipeline { windows.install_dependencies() windows.clean() windows.build() + if ( test_doc_files_windows ) { + stash name: 'ovms-windows-package', includes: 'dist\\windows\\ovms.zip' + } } finally { windows.archive_build_artifacts() } @@ -152,8 +255,7 @@ pipeline { } } } - stage("Release image and tests in parallel") { - when { expression { image_build_needed == "true" } } + stage("Tests in parallel") { options { timeout(time: 120, unit: 'MINUTES') } @@ -162,11 +264,12 @@ pipeline { agent { label "${agent_name_linux}" } + when { expression { image_build_needed == "true" } } steps { script { println "Running unit tests: NODE_NAME = ${env.NODE_NAME}" try { - sh "make run_unit_tests TEST_LLM_PATH=${HOME}/ovms_models/llm_models_ovms/OVMS_C BASE_OS=redhat OVMS_CPP_IMAGE_TAG=${shortCommit}" + sh "make run_unit_tests TEST_LLM_PATH=${HOME}/ovms_models/llm_models_ovms/OVMS_C OVMS_CPP_IMAGE_TAG=${shortCommit}" } finally { archiveArtifacts allowEmptyArchive: true, artifacts: "test_logs.tar.gz" @@ -179,22 +282,60 @@ pipeline { agent { label "${agent_name_linux}" } + when { expression { image_build_needed == "true" } } steps { - sh "make release_image RUN_TESTS=0 OV_USE_BINARY=0 BASE_OS=redhat OVMS_CPP_IMAGE_TAG=${shortCommit} BUILD_IMAGE=openvino/model_server-build:${shortCommit}" - sh "make run_lib_files_test BASE_OS=redhat OVMS_CPP_IMAGE_TAG=${shortCommit}" script { - dir ('internal_tests'){ - checkout scmGit( - branches: [[name: 'develop']], - userRemoteConfigs: [[credentialsId: 'workflow-lab', - url: 'https://github.com/intel-innersource/frameworks.ai.openvino.model-server.tests.git']]) + dir ('internal_tests'){ + checkout scmGit(branches: [[name: 'develop']], userRemoteConfigs: [[credentialsId: 'workflow-lab', url: 'https://github.com/intel-innersource/frameworks.ai.openvino.model-server.tests.git']]) sh "pwd" - pwd = sh(returnStdout:true, script: "pwd").strip() - sh "make create-venv && rm -f tests/functional && ln -s ${pwd}/../tests/functional tests/functional && TT_ON_COMMIT_TESTS=True TT_XDIST_WORKERS=10 TT_BASE_OS=redhat TT_OVMS_IMAGE_NAME=openvino/model_server:${shortCommit} TT_OVMS_IMAGE_LOCAL=True make tests" + def pwd = sh(returnStdout:true, script: "pwd").strip() + sh "make create-venv && rm -f tests/functional && ln -s ${pwd}/../tests/functional tests/functional && TT_ON_COMMIT_TESTS=True TT_XDIST_WORKERS=10 TT_OVMS_IMAGE_NAME=openvino/model_server:${shortCommit} TT_OVMS_IMAGE_LOCAL=True make tests" } } } } + stage("Documentation tests") { + agent none + when { + expression { test_doc_files_linux && !disable_doc_tests_linux } + beforeAgent true + } + steps { + node(test_agent_linux) { + checkout scm + script { + dir ('documentation_tests') { + checkout scmGit(branches: [[name: 'develop']], userRemoteConfigs: [[credentialsId: 'workflow-lab', url: 'https://github.com/intel-innersource/frameworks.ai.openvino.model-server.tests.git']]) + sh "pwd" + def pwd = sh(returnStdout:true, script: "pwd").strip() + def ovms_c_repo_path = sh(returnStdout:true, script: "cd .. && pwd").strip() + def test_doc_files_str = test_doc_files_linux.split('\n').join(' or ') + sh "make create-venv && rm -f tests/functional && ln -s ${pwd}/../tests/functional tests/functional" + def cmd_venv_activate = ". .venv/bin/activate" + def cmd_export = "export TT_RUN_REGRESSION_TESTS=True && export TT_REGRESSION_WEEKLY_TESTS=True && export TT_TARGET_DEVICE=CPU,GPU,NPU && export TT_ENABLE_UAT_TESTS=True && export TT_ENABLE_SMOKE_TESTS=False && export TT_OVMS_C_REPO_PATH=${ovms_c_repo_path} && export TT_WAIT_FOR_MESSAGES_TIMEOUT=1500" + def cmd_pytest = "pytest tests/non_functional/documentation -k '${test_doc_files_str}' -n 0 --dist loadgroup" + def cmd = "" + if ( image_build_needed == "true" ) { + unstash 'ovms-release-image' + sh "gunzip -c ovms_release_image.tar.gz | docker load" + sh "rm -f ovms_release_image.tar.gz" + + cmd = "${cmd_venv_activate} && ${cmd_export} && export TT_OVMS_IMAGE_NAME=openvino/model_server:${shortCommit} && export TT_OVMS_IMAGE_LOCAL=True && export TT_FORCE_USE_OVMS_IMAGE=True && ${cmd_pytest}" + } else { + cmd = "${cmd_venv_activate} && ${cmd_export} && ${cmd_pytest}" + } + try { + sh cmd + } finally { + // Always save artifacts + zip zipFile: 'documentation_tests_linux_logs.zip', glob: 'test_log/**,test_log_build/**', overwrite: true + archiveArtifacts(artifacts: 'documentation_tests_linux_logs.zip', allowEmptyArchive: true) + } + } + } + } + } + } stage('Test windows') { agent { label "${agent_name_windows}" @@ -220,6 +361,47 @@ pipeline { } } } + stage("Documentation tests windows") { + agent none + when { + expression { test_doc_files_windows && !disable_doc_tests_windows } + beforeAgent true + } + steps { + node(test_agent_windows) { + checkout scm + script { + dir ('documentation_tests') { + checkout scmGit(branches: [[name: 'develop']], userRemoteConfigs: [[credentialsId: 'workflow-lab', url: 'https://github.com/intel-innersource/frameworks.ai.openvino.model-server.tests.git']]) + def test_doc_files_str = test_doc_files_windows.split('\n').join(' or ') + def current_path = bat(returnStdout: true, script: 'cd').trim().split('\n').last().trim() + def ovms_c_repo_path = bat(returnStdout: true, script: 'cd .. && cd').trim().split('\n').last().trim() + def cmd_link_ovms = "(if exist ${current_path}\\tests\\functional rmdir ${current_path}\\tests\\functional) && mklink /D ${current_path}\\tests\\functional ${ovms_c_repo_path}\\tests\\functional" + def cmd_requirements = "(if not exist .venv virtualenv .venv --python=python3.12) && call .venv\\Scripts\\activate.bat && pip install -r requirements.txt" + def cmd_export = "set \"TT_RUN_REGRESSION_TESTS=True\" && set \"TT_REGRESSION_WEEKLY_TESTS=True\" && set \"TT_TARGET_DEVICE=CPU,GPU,NPU\" && set \"TT_BASE_OS=windows\" && set \"TT_OVMS_TYPE=BINARY\" && set \"TT_ENABLE_UAT_TESTS=True\" && set \"TT_ENABLE_SMOKE_TESTS=False\" && set \"TT_DISABLE_DMESG_LOG_MONITOR=True\" && set \"TT_OVMS_C_REPO_PATH=${ovms_c_repo_path}\" && set \"TT_WAIT_FOR_MESSAGES_TIMEOUT=1500\" && set \"PYTHONUTF8=1\" && set \"PYTHONIOENCODING=utf-8\"" + def cmd_pytest = "pytest tests/non_functional/documentation -k \"${test_doc_files_str}\" -n 0 --dist loadgroup --basetemp=\"C:\\tmp\\pytest-${BRANCH_NAME}-${BUILD_NUMBER}\"" + def cmd = "" + if ( win_image_build_needed == "true" ) { + unstash 'ovms-windows-package' + cmd = "${cmd_link_ovms} && ${cmd_requirements} && ${cmd_export} && set \"TT_OVMS_C_RELEASE_ARTIFACTS_PATH=dist\\windows\\ovms.zip\" && ${cmd_pytest}" + } else { + cmd = "${cmd_link_ovms} && ${cmd_requirements} && ${cmd_export} && ${cmd_pytest}" + } + try { + def exitCode = bat(returnStatus: true, script: cmd) + if (exitCode != 0) { + error "Documentation tests windows command failed with exit code ${exitCode}" + } + } finally { + // Always save artifacts + zip zipFile: 'documentation_tests_windows_logs.zip', glob: 'test_log/**,test_log_build/**', overwrite: true + archiveArtifacts(artifacts: 'documentation_tests_windows_logs.zip', allowEmptyArchive: true) + } + } + } + } + } + } } } } diff --git a/ci/check_md_code_changes.sh b/ci/check_md_code_changes.sh new file mode 100755 index 0000000000..e1d45a4828 --- /dev/null +++ b/ci/check_md_code_changes.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# +# Copyright (c) 2026 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Checks git diff for .md files and reports those where changes +# fall inside fenced code blocks. +# Usage: ./check_md_code_changes.sh [base_ref] +# platform: "linux" (checks bash+console) or "windows" (checks bat+console) +# base_ref: optional git ref to diff against (default: HEAD~1) + +set -euo pipefail + +PLATFORM="${1:-linux}" +BASE_REF="${2:-HEAD~1}" + +case "$PLATFORM" in + linux) BLOCK_PATTERN='^```(bash|console)' ; FENCE_LANGS='bash|console' ;; + windows) BLOCK_PATTERN='^```(bat|console)' ; FENCE_LANGS='bat|console' ;; + *) echo "Error: platform must be 'linux' or 'windows'" >&2; exit 1 ;; +esac + +# Get list of changed .md files +changed_md_files=$(git diff --name-only "$BASE_REF" HEAD -- '*.md') + +if [ -z "$changed_md_files" ]; then + exit 0 +fi + +matched_files=() + +while IFS= read -r file; do + [ -z "$file" ] && continue + + # Extract changed line numbers in the new version from hunk headers + changed_lines=$(git diff --unified=0 "$BASE_REF" HEAD -- "$file" \ + | awk '/^@@/ { + match($0, /\+([0-9]+)(,([0-9]+))?/, arr) + start = arr[1] + count = (arr[3] != "") ? arr[3] : 1 + for (i = start; i < start + count; i++) print i + }') + + if [ -z "$changed_lines" ]; then + continue + fi + + # Check if a code block fence was added, removed, or changed type in the diff + # (e.g. ```->```bash, ```console->```, or entirely new/deleted fence) + fence_changed=$(git diff --unified=0 "$BASE_REF" HEAD -- "$file" \ + | grep -qE "^[+-]\`\`\`($FENCE_LANGS)" && echo 1 || true) + + if [ -n "$fence_changed" ]; then + matched_files+=("$file") + continue + fi + + # Use awk to find which lines are inside ```bash/bat/console blocks, + # then check if any of those overlap with changed lines + hit=$(awk -v lines="$changed_lines" -v pattern="$BLOCK_PATTERN" ' + BEGIN { + n = split(lines, arr, "\n") + for (i = 1; i <= n; i++) changed[arr[i]] = 1 + } + $0 ~ pattern { in_block = 1; next } + /^```/ { in_block = 0; next } + in_block && (NR in changed) { print FILENAME; exit } + ' "$file") + + if [ -n "$hit" ]; then + matched_files+=("$file") + fi +done <<< "$changed_md_files" + +if [ ${#matched_files[@]} -gt 0 ]; then + printf '%s\n' "${matched_files[@]}" +fi diff --git a/tests/file_lists/lib_files.txt b/tests/file_lists/lib_files.txt index c7740691ff..8c3468c5bc 100644 --- a/tests/file_lists/lib_files.txt +++ b/tests/file_lists/lib_files.txt @@ -1,43 +1,47 @@ custom_nodes +libOpenCL.so->libOpenCL.so.1.0.0 +libOpenCL.so.1->libOpenCL.so.1.0.0 +libOpenCL.so.1.0.0 libazurestorage.so libazurestorage.so.7->libazurestorage.so libazurestorage.so.7.5->libazurestorage.so libcpprest.so libcpprest.so.2.10->libcpprest.so -libopencv_calib3d.so->libopencv_calib3d.so.410 -libopencv_calib3d.so.4.10.0 -libopencv_calib3d.so.410->libopencv_calib3d.so.4.10.0 -libopencv_core.so->libopencv_core.so.410 -libopencv_core.so.4.10.0 -libopencv_core.so.410->libopencv_core.so.4.10.0 -libopencv_features2d.so->libopencv_features2d.so.410 -libopencv_features2d.so.4.10.0 -libopencv_features2d.so.410->libopencv_features2d.so.4.10.0 -libopencv_flann.so->libopencv_flann.so.410 -libopencv_flann.so.4.10.0 -libopencv_flann.so.410->libopencv_flann.so.4.10.0 -libopencv_highgui.so->libopencv_highgui.so.410 -libopencv_highgui.so.4.10.0 -libopencv_highgui.so.410->libopencv_highgui.so.4.10.0 -libopencv_imgcodecs.so->libopencv_imgcodecs.so.410 -libopencv_imgcodecs.so.4.10.0 -libopencv_imgcodecs.so.410->libopencv_imgcodecs.so.4.10.0 -libopencv_imgproc.so->libopencv_imgproc.so.410 -libopencv_imgproc.so.4.10.0 -libopencv_imgproc.so.410->libopencv_imgproc.so.4.10.0 -libopencv_optflow.so->libopencv_optflow.so.410 -libopencv_optflow.so.4.10.0 -libopencv_optflow.so.410->libopencv_optflow.so.4.10.0 -libopencv_video.so->libopencv_video.so.410 -libopencv_video.so.4.10.0 -libopencv_video.so.410->libopencv_video.so.4.10.0 -libopencv_videoio.so->libopencv_videoio.so.410 -libopencv_videoio.so.4.10.0 -libopencv_videoio.so.410->libopencv_videoio.so.4.10.0 -libopencv_ximgproc.so->libopencv_ximgproc.so.410 -libopencv_ximgproc.so.4.10.0 -libopencv_ximgproc.so.410->libopencv_ximgproc.so.4.10.0 +libgit2.so +libopencv_calib3d.so->libopencv_calib3d.so.413 +libopencv_calib3d.so.4.13.0 +libopencv_calib3d.so.413->libopencv_calib3d.so.4.13.0 +libopencv_core.so->libopencv_core.so.413 +libopencv_core.so.4.13.0 +libopencv_core.so.413->libopencv_core.so.4.13.0 +libopencv_features2d.so->libopencv_features2d.so.413 +libopencv_features2d.so.4.13.0 +libopencv_features2d.so.413->libopencv_features2d.so.4.13.0 +libopencv_flann.so->libopencv_flann.so.413 +libopencv_flann.so.4.13.0 +libopencv_flann.so.413->libopencv_flann.so.4.13.0 +libopencv_highgui.so->libopencv_highgui.so.413 +libopencv_highgui.so.4.13.0 +libopencv_highgui.so.413->libopencv_highgui.so.4.13.0 +libopencv_imgcodecs.so->libopencv_imgcodecs.so.413 +libopencv_imgcodecs.so.4.13.0 +libopencv_imgcodecs.so.413->libopencv_imgcodecs.so.4.13.0 +libopencv_imgproc.so->libopencv_imgproc.so.413 +libopencv_imgproc.so.4.13.0 +libopencv_imgproc.so.413->libopencv_imgproc.so.4.13.0 +libopencv_optflow.so->libopencv_optflow.so.413 +libopencv_optflow.so.4.13.0 +libopencv_optflow.so.413->libopencv_optflow.so.4.13.0 +libopencv_video.so->libopencv_video.so.413 +libopencv_video.so.4.13.0 +libopencv_video.so.413->libopencv_video.so.4.13.0 +libopencv_videoio.so->libopencv_videoio.so.413 +libopencv_videoio.so.4.13.0 +libopencv_videoio.so.413->libopencv_videoio.so.4.13.0 +libopencv_ximgproc.so->libopencv_ximgproc.so.413 +libopencv_ximgproc.so.4.13.0 +libopencv_ximgproc.so.413->libopencv_ximgproc.so.4.13.0 libopenvino.so->libopenvino.so.2630 libopenvino.so.2026.3.0 libopenvino.so.2630->libopenvino.so.2026.3.0 @@ -46,15 +50,17 @@ libopenvino_auto_plugin.so libopenvino_c.so->libopenvino_c.so.2630 libopenvino_c.so.2026.3.0 libopenvino_c.so.2630->libopenvino_c.so.2026.3.0 +libopenvino_genai.so->libopenvino_genai.so.2630 +libopenvino_genai.so.2026.3.0.0 +libopenvino_genai.so.2630->libopenvino_genai.so.2026.3.0.0 libopenvino_hetero_plugin.so libopenvino_intel_cpu_plugin.so libopenvino_intel_gpu_plugin.so +libopenvino_intel_npu_compiler.so +libopenvino_intel_npu_compiler_loader.so libopenvino_intel_npu_plugin.so libopenvino_ir_frontend.so.2026.3.0 libopenvino_ir_frontend.so.2630->libopenvino_ir_frontend.so.2026.3.0 -libopenvino_jax_frontend.so->libopenvino_jax_frontend.so.2630 -libopenvino_jax_frontend.so.2026.3.0 -libopenvino_jax_frontend.so.2630->libopenvino_jax_frontend.so.2026.3.0 libopenvino_onnx_frontend.so->libopenvino_onnx_frontend.so.2630 libopenvino_onnx_frontend.so.2026.3.0 libopenvino_onnx_frontend.so.2630->libopenvino_onnx_frontend.so.2026.3.0 @@ -74,3 +80,4 @@ libopenvino_tokenizers.so libtbb.so->libtbb.so.12 libtbb.so.12->libtbb.so.12.13 libtbb.so.12.13 +python