Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a6df150
add integration test for nemo2+triton deployment
marta-sd Sep 23, 2025
b405090
use full flags for better readibility
marta-sd Sep 23, 2025
3466df3
add integration test for nemo2+ray deployment
marta-sd Sep 23, 2025
9f21a5d
reuse duplicated code + use tmp_path fixture
marta-sd Sep 23, 2025
fdf5460
add integration test for hf+ray deployment
marta-sd Sep 23, 2025
296763e
set autouse=true for deployment
marta-sd Sep 23, 2025
8974ffe
comment out logprob test for HF - not supported
marta-sd Sep 24, 2025
f587764
add test for notebooks
marta-sd Sep 24, 2025
a430324
update for new export-deploy version
marta-sd Sep 29, 2025
ef186cc
move e2e EF testing to functional tests
marta-sd Sep 30, 2025
dcaf409
add cp headers
marta-sd Oct 1, 2025
524305f
update uv.lock
marta-sd Oct 1, 2025
720c9e6
fix for uv
marta-sd Oct 1, 2025
11ddd69
mock sys.modules instead of actually removing the package
marta-sd Oct 2, 2025
0430632
add script for launching the test
marta-sd Oct 2, 2025
25d15bd
remove obsolete set_env_vars fixture
marta-sd Oct 2, 2025
8819978
ci: Extend for integration tests
ko3n1g Oct 2, 2025
1876f37
fix
ko3n1g Oct 2, 2025
883000a
fix dependency
ko3n1g Oct 2, 2025
624264e
fix
ko3n1g Oct 2, 2025
2c3690f
test
ko3n1g Oct 2, 2025
e6c6b54
fix
ko3n1g Oct 2, 2025
7c116bc
fix
ko3n1g Oct 2, 2025
7b8388b
fix action
ko3n1g Oct 2, 2025
f65065e
fix
ko3n1g Oct 2, 2025
b7f39ab
test
ko3n1g Oct 2, 2025
7a06c22
fix
ko3n1g Oct 2, 2025
f62fcf0
self-hosted-azure
ko3n1g Oct 2, 2025
05ab271
fix
ko3n1g Oct 2, 2025
14c3ed4
ffix
ko3n1g Oct 2, 2025
6c8e72d
fix
ko3n1g Oct 2, 2025
7be8849
fix
ko3n1g Oct 2, 2025
6284d6e
Merge branch 'martas/nemo-fw-tests' of github.com:NVIDIA-NeMo/Evaluat…
ko3n1g Oct 3, 2025
094752f
Merge branch 'main' of github.com:NVIDIA-NeMo/Evaluator into ko3n1g/c…
ko3n1g Oct 3, 2025
6ba902c
fix
ko3n1g Oct 3, 2025
1ed64c9
type_of_test
ko3n1g Oct 3, 2025
bbf4de7
set TRANSFORMERS_OFFLINE=1 and create symlink needed to run notebooks
marta-sd Oct 3, 2025
5bffef0
Fix coverage file name
marta-sd Oct 3, 2025
de47a88
Merge branch 'main' into martas/nemo-fw-tests
marta-sd Oct 3, 2025
f7b4923
Merge branch 'martas/nemo-fw-tests' of github.com:NVIDIA-NeMo/Evaluat…
ko3n1g Oct 3, 2025
e25dee1
fix
ko3n1g Oct 3, 2025
7af0b41
add hub
ko3n1g Oct 3, 2025
78fa6fa
set env vars for all test scripts (HF offline)
marta-sd Oct 6, 2025
06c57d9
don't capture output for easier debugging
marta-sd Oct 6, 2025
d0a6aae
Merge branch 'martas/nemo-fw-tests' into ko3n1g/ci/ngc-nightly
marta-sd Oct 6, 2025
4f99f56
Merge branch 'main' into martas/nemo-fw-tests
marta-sd Oct 8, 2025
89ecc92
Merge branch 'martas/nemo-fw-tests' into ko3n1g/ci/ngc-nightly
marta-sd Oct 8, 2025
ab3b1a3
ci(fix): Mount FS for functional_tests
ko3n1g Oct 8, 2025
3a1dafc
add azure credentials to functional tests
ko3n1g Oct 8, 2025
c2258d5
fix
ko3n1g Oct 8, 2025
b41aa0c
fix
ko3n1g Oct 8, 2025
336829d
login
ko3n1g Oct 8, 2025
084316a
fix
ko3n1g Oct 8, 2025
f5043e9
test
ko3n1g Oct 8, 2025
9e3e7ed
tmp changes for testing deployment alone
marta-sd Oct 9, 2025
8701696
fix typo
marta-sd Oct 9, 2025
f183306
fix gpu mount
ko3n1g Oct 9, 2025
b0f24af
test
ko3n1g Oct 9, 2025
0bd7b71
fix
ko3n1g Oct 9, 2025
35d9b31
fix
ko3n1g Oct 9, 2025
2c0a001
fix
ko3n1g Oct 9, 2025
5464683
heredoc fix
ko3n1g Oct 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 157 additions & 12 deletions .github/actions/test-template/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,45 @@ inputs:
description: "Failure will cancel all other tests if set to true"
required: false
default: "false"
is_unit_test:
description: "Upload coverage as unit test"
type_of_test:
description: "Type of test to run"
required: false
default: "false"
default: "unit_tests"
package:
description: "Package to test"
required: true
description: "Package to test. Only required for unit and functional tests."
required: false
use-credentials:
description: "Use credentials for test"
required: false
default: "false"
ngc-api-user:
description: "NGC API user"
required: false
default: "false"
ngc-api-key:
description: "NGC API key"
required: false
default: "false"
cpu-only:
description: "CPU only"
required: false
default: "true"
has-azure-credentials:
description: "Has Azure credentials"
required: false
default: "false"
azure-client-id:
description: "Azure client ID"
required: false
default: "false"
azure-tenant-id:
description: "Azure tenant ID"
required: false
default: "false"
azure-subscription-id:
description: "Azure subscription ID"
required: false
default: "false"

runs:
using: "composite"
Expand All @@ -42,30 +74,139 @@ runs:
with:
path: Eval

- name: Build container
- name: Validate type of test
shell: bash
run: |
echo ::group::Validate type of test
if [[ "${{ inputs.type_of_test }}" != "unit_tests" && "${{ inputs.type_of_test }}" != "functional_tests" && "${{ inputs.type_of_test }}" != "integration_tests" ]]; then
echo "Invalid type of test: ${{ inputs.type_of_test }}"
exit 1
fi
echo ::endgroup::

- name: Use credentials
shell: bash
if: ${{ inputs.use-credentials == 'true' }}
run: |
echo ::group::Use credentials
echo ${{ inputs.ngc-api-key }} | docker login -u '${{ inputs.ngc-api-user }}' --password-stdin nvcr.io
echo ::endgroup::

- name: Build container for unit and functional tests
shell: bash
if: ${{ inputs.type_of_test != 'integration_tests' }}
run: |
echo ::group::Build test container
docker build -f docker/Dockerfile.ci --build-arg PACKAGE=${{ inputs.package }} -t eval .
docker build -f docker/Dockerfile.ci \
--build-arg PACKAGE=${{ inputs.package }} \
-t eval .
echo ::endgroup::

- name: Build container for integration tests
shell: bash
if: ${{ inputs.type_of_test == 'integration_tests' }}
run: |
echo ::group::Build test container
docker build -f docker/Dockerfile.ci-integration \
-t eval .
echo ::endgroup::

- name: Azure Login
if: ${{ inputs.has-azure-credentials == 'true' }}
uses: azure/login@v2
with:
client-id: ${{ inputs.azure-client-id }}
tenant-id: ${{ inputs.azure-tenant-id }}
subscription-id: ${{ inputs.azure-subscription-id }}

- name: Azure Fileshare
if: ${{ inputs.has-azure-credentials == 'true' && inputs.type_of_test != 'unit-tests' }}
shell: bash
id: azure-fileshare
run: |
echo "::group::Mount SMB drive"
sudo apt update
sudo apt install -y cifs-utils

RESOURCE_GROUP_NAME="azure-gpu-vm-runner_group"
STORAGE_ACCOUNT_NAME="nemocistorageaccount2"
FILE_SHARE_NAME="fileshare"

MNT_PATH="/mnt/datadrive"

sudo mkdir -p $MNT_PATH

# Create a folder to store the credentials for this storage account and
# any other that you might set up.
CREDENTIAL_ROOT="/etc/smbcredentials"
sudo mkdir -p "/etc/smbcredentials"

# Get the storage account key for the indicated storage account.
# You must be logged in with az login and your user identity must have
# permissions to list the storage account keys for this command to work.
STORAGE_ACCOUNT_KEY=$(az storage account keys list \
--resource-group $RESOURCE_GROUP_NAME \
--account-name $STORAGE_ACCOUNT_NAME \
--query "[0].value" --output tsv | tr -d '"')

# Create the credential file for this individual storage account
SMB_CREDENTIAL_FILE="$CREDENTIAL_ROOT/$STORAGE_ACCOUNT_NAME.cred"
if [ ! -f $SMB_CREDENTIAL_FILE ]; then
echo "username=$STORAGE_ACCOUNT_NAME" | sudo tee $SMB_CREDENTIAL_FILE > /dev/null
echo "password=$STORAGE_ACCOUNT_KEY" | sudo tee -a $SMB_CREDENTIAL_FILE > /dev/null
else
echo "The credential file $SMB_CREDENTIAL_FILE already exists, and was not modified."
fi

# Change permissions on the credential file so only root can read or modify the password file.
sudo chmod 600 $SMB_CREDENTIAL_FILE

# This command assumes you have logged in with az login
HTTP_ENDPOINT=$(az storage account show --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --query "primaryEndpoints.file" --output tsv | tr -d '"')
SMB_PATH=$(echo $HTTP_ENDPOINT | cut -c7-${#HTTP_ENDPOINT})$FILE_SHARE_NAME

STORAGE_ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query "[0].value" --output tsv | tr -d '"')

sudo mount -t cifs $SMB_PATH $MNT_PATH -o credentials=$SMB_CREDENTIAL_FILE,serverino,nosharesock,actimeo=30,mfsymlinks,fsc,cache=strict

ls -al $MNT_PATH/TestData
echo "::endgroup::"

- name: Start container
shell: bash
env:
MOUNT_FS: ${{ inputs.type_of_test == 'integration_tests' || inputs.type_of_test == 'functional_tests' }}
run: |
echo ::group::Start test container
echo "::group::Start test container"
if [[ "$MOUNT_FS" == "true" ]]; then
ls -al /mnt/datadrive/TestData
VOLUME_ARGS="--volume /mnt/datadrive/TestData:/home/TestData"
else
VOLUME_ARGS=""
fi

ARG=("")
if [[ "${{ inputs.type_of_test }}" == "integration_tests" ]]; then
ARG=("--runtime=nvidia --gpus all")
fi

cmd=$(cat <<RUN_TEST_EOF
#!/bin/bash
docker container rm -f nemo_container_${{ github.run_id }} || true

docker run \
--rm \
-d \
--name nemo_container_${{ github.run_id }} \
${ARG[@]} \
--shm-size=64g \
--env TRANSFORMERS_OFFLINE=0 \
--env TRANSFORMERS_OFFLINE=1 \
--env HYDRA_FULL_ERROR=1 \
--env HF_HUB_CACHE_PATH=/home/TestData/HF_HOME/hub \
--env HF_HOME=/home/TestData/HF_HOME \
--env RUN_ID=${{ github.run_id }} \
--volume $(pwd)/Eval:/workspace \
$VOLUME_ARGS \
eval \
bash -c "sleep $(( ${{ inputs.timeout }} * 60 + 60 ))"
RUN_TEST_EOF
Expand All @@ -80,16 +221,20 @@ runs:
shell: bash
run: |
echo ::group::Create run-script
COVERAGE_PREFIX=$([[ "${{ inputs.is_unit_test }}" == "true" ]] && echo "unit-test" || echo "e2e")
COVERAGE_PREFIX=$([[ "${{ inputs.type_of_test }}" == "unit_tests" ]] && echo "unit-test" || echo "e2e")
echo "coverage-prefix=$COVERAGE_PREFIX" | tee -a "$GITHUB_OUTPUT"

cmd=$(cat <<'RUN_TEST_EOF'
#!/bin/bash

docker exec -t nemo_container_${{ github.run_id }} bash -c '
set -e
cd packages/${{ inputs.package }}
bash tests/${{ inputs.is_unit_test == 'true' && 'unit_tests' || 'functional_tests' }}/${{ inputs.script }}.sh
if [[ "${{ inputs.type_of_test }}" != "integration_tests" ]]; then
cd packages/${{ inputs.package }}
bash tests/${{ inputs.type_of_test == 'unit_tests' && 'unit_tests' || 'functional_tests' }}/${{ inputs.script }}.sh
else
bash tests/integration_tests/Launch_Integration_Tests.sh
fi
'

RUN_TEST_EOF
Expand Down
55 changes: 49 additions & 6 deletions .github/workflows/cicd-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,19 @@ permissions:
contents: read

jobs:
# pre-flight:
# uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/[email protected]

pre-flight:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/[email protected]
runs-on: ubuntu-latest
outputs:
is_ci_workload: "true"
force_run_all: "false"
docs_only: "false"
is_deployment_workflow: "false"
steps:
- name: Checkout
uses: actions/checkout@v4

linting:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -95,7 +106,7 @@ jobs:
with:
script: Launch_Unit_Tests
timeout: 10
is_unit_test: "true"
type_of_test: "unit_tests"
cpu-only: true
package: nemo-evaluator

Expand All @@ -119,7 +130,7 @@ jobs:
with:
script: Launch_Unit_Tests
timeout: 10
is_unit_test: "true"
type_of_test: "unit_tests"
cpu-only: true
package: nemo-evaluator-launcher

Expand All @@ -143,16 +154,44 @@ jobs:
with:
script: Launch_Functional_Tests
timeout: ${{ matrix.timeout || 10 }}
is_unit_test: "false"
type_of_test: "functional_tests"
cpu-only: true
package: nemo-evaluator
has-azure-credentials: true
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

cicd-integration-tests:
needs:
- cicd-unit-tests-nemo-evaluator
environment: main
runs-on: self-hosted-azure
if: |
needs.pre-flight.outputs.is_ci_workload == 'true'
&& !cancelled()
name: integration-tests
steps:
- name: Checkout
uses: actions/checkout@v4
- name: main
uses: ./.github/actions/test-template
with:
script: Launch_Integration_Tests
timeout: 60
type_of_test: "integration_tests"
cpu-only: false
use-credentials: true
ngc-api-user: ${{ secrets.NGC_API_USER }}
ngc-api-key: ${{ secrets.NGC_API_KEY }}

Nemo_CICD_Test:
needs:
- pre-flight
- cicd-unit-tests-nemo-evaluator
- cicd-unit-tests-nemo-evaluator-launcher
- cicd-e2e-tests-nemo-evaluator
- cicd-integration-tests
if: |
(
needs.pre-flight.outputs.docs_only == 'true'
Expand All @@ -173,10 +212,14 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
RUN_ID: ${{ github.run_id }}
IS_CI_WORKLOAD: ${{ needs.pre-flight.outputs.is_ci_workload == 'true' }}
SKIPPING_IS_ALLOWED: ${{ needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true' || needs.pre-flight.outputs.is_ci_workload == 'true' }}
run: |
FAILED_JOBS=$(gh run view $GITHUB_RUN_ID --json jobs --jq '[.jobs[] | select(.status == "completed" and .conclusion != "success")] | length') || echo 0

if [ "$IS_CI_WORKLOAD" == "true" ]; then
FAILED_JOBS=$(gh run view $GITHUB_RUN_ID --json jobs --jq '[.jobs[] | select(.status == "completed" and .conclusion != "success")] | length') || echo 0
else
FAILED_JOBS=$(gh run view $GITHUB_RUN_ID --json jobs --jq '[.jobs[] | select(.status == "completed" and .conclusion != "success" and .name != "integration-tests")] | length') || echo 0
fi
if [ "${FAILED_JOBS:-0}" -eq 0 ] || [ "$SKIPPING_IS_ALLOWED" == "true" ]; then
echo "✅ All previous jobs completed successfully"
exit 0
Expand Down
17 changes: 17 additions & 0 deletions docker/Dockerfile.ci-integration
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# 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.

FROM nvcr.io/nvidian/nemo:nightly
COPY . /opt/Evaluator/
RUN cd /opt/Evaluator/packages/nemo-evaluator && uv pip install -e .
2 changes: 1 addition & 1 deletion packages/nemo-evaluator/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ repository = "https://github.com/NVIDIA-NeMo/Evaluator/packages/nemo-evaluator"
# END(if-changed)

[dependency-groups]
test = ["pytest", "pytest-cov", "pytest-subtests", "pytest-httpserver"]
test = ["pytest", "pytest-cov", "pytest-subtests", "pytest-httpserver", "nvidia-simple-evals"]

docs = [
"sphinx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
set -xeuo pipefail # Exit immediately if a command exits with a non-zero status

export CUDA_VISIBLE_DEVICES=""
export HF_HOME="/home/TestData/HF_HOME"
export HF_DATASETS_OFFLINE="1"
export TRANSFORMERS_OFFLINE="1"
export HF_DATASETS_CACHE="${HF_HOME}/datasets"

SCRIPT_DIR=$(dirname "$0")
PROJECT_DIR=$SCRIPT_DIR/../../
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import pytest
import requests
from flask import Flask, jsonify, request

from nemo_evaluator.logging.utils import logger


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""End-to-end tests for eval-factory using fake endpoint."""

import pytest

from nemo_evaluator.logging.utils import logger


Expand Down
Loading
Loading