CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
591 lines
26 KiB
Python
591 lines
26 KiB
Python
################################################################################
|
|
#
|
|
# Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
################################################################################
|
|
|
|
import pytest
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import Mock, patch, MagicMock, call, mock_open
|
|
|
|
from Tensile.TensileBenchmarkCluster import (
|
|
BenchmarkImplSLURM,
|
|
TensileBenchmarkCluster,
|
|
)
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestBenchmarkImplSLURM:
|
|
"""Test suite for BenchmarkImplSLURM class."""
|
|
|
|
def test_initialize_config_creates_slurm_section(self):
|
|
"""BenchmarkImplSLURM.initializeConfig creates SLURM configuration section."""
|
|
mock_config = MagicMock()
|
|
mock_config.__getitem__ = Mock(return_value="/fake/tensile/dir")
|
|
mock_slurm_section = MagicMock()
|
|
mock_config.createSection = Mock(return_value=mock_slurm_section)
|
|
|
|
BenchmarkImplSLURM.initializeConfig(mock_config)
|
|
|
|
mock_config.createSection.assert_called_with("SLURM")
|
|
|
|
def test_initialize_config_creates_scripts_section(self):
|
|
"""BenchmarkImplSLURM.initializeConfig creates SCRIPTS subsection."""
|
|
mock_config = MagicMock()
|
|
mock_config.__getitem__ = Mock(return_value="/fake/tensile/dir")
|
|
mock_slurm_section = MagicMock()
|
|
mock_scripts_section = MagicMock()
|
|
mock_config.createSection = Mock(return_value=mock_slurm_section)
|
|
mock_slurm_section.createSection = Mock(return_value=mock_scripts_section)
|
|
|
|
BenchmarkImplSLURM.initializeConfig(mock_config)
|
|
|
|
# Should create both SCRIPTS and DOCKER sections
|
|
assert mock_slurm_section.createSection.call_count == 2
|
|
calls = [str(c) for c in mock_slurm_section.createSection.call_args_list]
|
|
assert any("SCRIPTS" in str(c) for c in calls)
|
|
assert any("DOCKER" in str(c) for c in calls)
|
|
|
|
def test_initialize_config_sets_script_names(self):
|
|
"""BenchmarkImplSLURM.initializeConfig sets default script names."""
|
|
mock_config = MagicMock()
|
|
mock_config.__getitem__ = Mock(return_value="/fake/tensile/dir")
|
|
mock_slurm_section = MagicMock()
|
|
mock_scripts_section = MagicMock()
|
|
mock_config.createSection = Mock(return_value=mock_slurm_section)
|
|
mock_slurm_section.createSection = Mock(return_value=mock_scripts_section)
|
|
|
|
BenchmarkImplSLURM.initializeConfig(mock_config)
|
|
|
|
# Check that script names are set
|
|
script_calls = mock_scripts_section.createValue.call_args_list
|
|
assert any("JobScriptName" in str(c) and "runBenchmark.sh" in str(c) for c in script_calls)
|
|
assert any("TaskScriptName" in str(c) and "enqueueTask.sh" in str(c) for c in script_calls)
|
|
|
|
def test_initialize_config_sets_docker_values(self):
|
|
"""BenchmarkImplSLURM.initializeConfig sets Docker configuration values."""
|
|
mock_config = MagicMock()
|
|
mock_config.__getitem__ = Mock(return_value="/fake/tensile/dir")
|
|
mock_slurm_section = MagicMock()
|
|
mock_docker_section = MagicMock()
|
|
|
|
# Return DOCKER section on second createSection call
|
|
mock_slurm_section.createSection = Mock(side_effect=[MagicMock(), mock_docker_section])
|
|
mock_config.createSection = Mock(return_value=mock_slurm_section)
|
|
|
|
BenchmarkImplSLURM.initializeConfig(mock_config)
|
|
|
|
# Check that Docker values are set
|
|
docker_calls = mock_docker_section.createValue.call_args_list
|
|
assert len(docker_calls) > 0
|
|
assert any("DockerImageName" in str(c) for c in docker_calls)
|
|
assert any("TensileFork" in str(c) for c in docker_calls)
|
|
|
|
@patch("os.listdir")
|
|
@patch("Tensile.TensileBenchmarkCluster.ScriptWriter")
|
|
def test_generate_benchmark_creates_scripts(self, mock_script_writer, mock_listdir):
|
|
"""BenchmarkImplSLURM.generateBenchmark creates cluster scripts."""
|
|
# Mock os.listdir to return empty list (no config files in tasks dir)
|
|
mock_listdir.return_value = []
|
|
|
|
mock_config = {
|
|
"BenchmarkBaseDir": "/fake/base",
|
|
"BenchmarkTasksDir": "/fake/tasks",
|
|
"BenchmarkImageDir": "/fake/image",
|
|
"BenchmarkLogsDir": "/fake/logs",
|
|
"SLURM": {
|
|
"DOCKER": {
|
|
"DockerBaseImage": "fake:image",
|
|
"DockerBuildFile": "/fake/dockerfile",
|
|
"DockerImageName": "tensile-test",
|
|
"DockerImageTag": "TEST",
|
|
"TensileFork": "test-fork",
|
|
"TensileBranch": "test-branch",
|
|
"TensileCommit": "abc123",
|
|
},
|
|
"SCRIPTS": {
|
|
"TaskScriptName": "task.sh",
|
|
"JobScriptName": "job.sh",
|
|
}
|
|
}
|
|
}
|
|
|
|
with patch.object(BenchmarkImplSLURM, '_BenchmarkImplSLURM__createTensileBenchmarkContainer'):
|
|
BenchmarkImplSLURM.generateBenchmark(mock_config)
|
|
|
|
mock_script_writer.writeBenchmarkJobScript.assert_called_once()
|
|
mock_script_writer.writeBenchmarkTaskScript.assert_called_once()
|
|
|
|
@patch("os.rename")
|
|
@patch("os.makedirs")
|
|
@patch("os.path.isfile")
|
|
@patch("os.listdir")
|
|
@patch("Tensile.TensileBenchmarkCluster.ScriptWriter")
|
|
def test_generate_benchmark_processes_config_files(self, mock_script_writer, mock_listdir,
|
|
mock_isfile, mock_makedirs, mock_rename):
|
|
"""BenchmarkImplSLURM.generateBenchmark processes config files in tasks directory."""
|
|
# Mock os.listdir to return config files
|
|
mock_listdir.return_value = ["config_0001.yaml", "config_0002.yaml"]
|
|
mock_isfile.return_value = True
|
|
|
|
mock_config = {
|
|
"BenchmarkBaseDir": "/fake/base",
|
|
"BenchmarkTasksDir": "/fake/tasks",
|
|
"BenchmarkImageDir": "/fake/image",
|
|
"BenchmarkLogsDir": "/fake/logs",
|
|
"SLURM": {
|
|
"DOCKER": {
|
|
"DockerBaseImage": "fake:image",
|
|
"DockerBuildFile": "/fake/dockerfile",
|
|
"DockerImageName": "tensile-test",
|
|
"DockerImageTag": "TEST",
|
|
"TensileFork": "test-fork",
|
|
"TensileBranch": "test-branch",
|
|
"TensileCommit": "abc123",
|
|
},
|
|
"SCRIPTS": {
|
|
"TaskScriptName": "task.sh",
|
|
"JobScriptName": "job.sh",
|
|
}
|
|
}
|
|
}
|
|
|
|
with patch.object(BenchmarkImplSLURM, '_BenchmarkImplSLURM__createTensileBenchmarkContainer'):
|
|
BenchmarkImplSLURM.generateBenchmark(mock_config)
|
|
|
|
# Should create subdirectories for each config file
|
|
assert mock_makedirs.call_count == 2
|
|
# Should rename/move config files into subdirectories
|
|
assert mock_rename.call_count == 2
|
|
# Should create node scripts for each config
|
|
assert mock_script_writer.writeBenchmarkNodeScript.call_count == 2
|
|
|
|
@patch("subprocess.check_call")
|
|
@patch("builtins.open", new_callable=mock_open)
|
|
def test_invoke_benchmark_runs_script(self, mock_file, mock_subprocess):
|
|
"""BenchmarkImplSLURM.invokeBenchmark runs the job script."""
|
|
mock_config = {
|
|
"BenchmarkBaseDir": "/fake/base",
|
|
"BenchmarkTasksDir": "/fake/tasks",
|
|
"BenchmarkImageDir": "/fake/image",
|
|
"BenchmarkResultsDir": "/fake/results",
|
|
"BenchmarkLogsDir": "/fake/logs",
|
|
"SLURM": {
|
|
"SCRIPTS": {
|
|
"TaskScriptName": "task.sh",
|
|
"JobScriptName": "job.sh",
|
|
}
|
|
}
|
|
}
|
|
|
|
BenchmarkImplSLURM.invokeBenchmark(mock_config)
|
|
|
|
# Should open log file
|
|
mock_file.assert_called_once()
|
|
assert "job.log" in str(mock_file.call_args)
|
|
# Should call subprocess to run script
|
|
mock_subprocess.assert_called_once()
|
|
|
|
def test_pre_invoke_benchmark_does_nothing(self):
|
|
"""BenchmarkImplSLURM.preInvokeBenchmark is a no-op."""
|
|
result = BenchmarkImplSLURM.preInvokeBenchmark({})
|
|
assert result is None
|
|
|
|
def test_post_invoke_benchmark_does_nothing(self):
|
|
"""BenchmarkImplSLURM.postInvokeBenchmark is a no-op."""
|
|
result = BenchmarkImplSLURM.postInvokeBenchmark({})
|
|
assert result is None
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestTensileBenchmarkCluster:
|
|
"""Test suite for TensileBenchmarkCluster class."""
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_init_creates_config(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.__init__ creates configuration."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
cluster = TensileBenchmarkCluster(args)
|
|
|
|
mock_project_config.assert_called_once()
|
|
assert cluster._config is not None
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_init_with_slurm_backend(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster uses SLURM backend by default."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
|
|
assert cluster._backendImpl == BenchmarkImplSLURM
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path", "--cluster-backend", "unknown"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_init_raises_on_unknown_backend(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster raises on unknown backend."""
|
|
args = ["logic.yaml", "/deploy/path", "--cluster-backend", "unknown"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
with pytest.raises(NotImplementedError, match="Cluster backend not recognized"):
|
|
TensileBenchmarkCluster(args)
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_workflow_steps_returns_tuple(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.workflowSteps returns tuple of workflow flags."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(side_effect=lambda k: {
|
|
"RunDeployStep": True,
|
|
"RunBenchmarkStep": False,
|
|
"RunResultsStep": True,
|
|
}.get(k))
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
steps = cluster.workflowSteps()
|
|
|
|
assert steps == (True, False, True)
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_config_returns_config_object(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.config returns configuration object."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
config = cluster.config()
|
|
|
|
assert config == mock_config_instance
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_base_dir_returns_base_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.baseDir returns base directory from config."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/base/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
base_dir = cluster.baseDir()
|
|
|
|
assert base_dir == "/fake/base/dir"
|
|
mock_config_instance.__getitem__.assert_called_with("BenchmarkBaseDir")
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_tasks_dir_returns_tasks_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.tasksDir returns tasks directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/tasks/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
tasks_dir = cluster.tasksDir()
|
|
|
|
assert tasks_dir == "/fake/tasks/dir"
|
|
mock_config_instance.__getitem__.assert_called_with("BenchmarkTasksDir")
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_image_dir_returns_image_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.imageDir returns image directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/image/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
image_dir = cluster.imageDir()
|
|
|
|
assert image_dir == "/fake/image/dir"
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_results_dir_returns_results_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.resultsDir returns results directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/results/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
results_dir = cluster.resultsDir()
|
|
|
|
assert results_dir == "/fake/results/dir"
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_final_logic_dir_returns_final_logic_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.finalLogicDir returns final logic directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/final/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
final_dir = cluster.finalLogicDir()
|
|
|
|
assert final_dir == "/fake/final/dir"
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_logs_dir_returns_logs_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.logsDir returns logs directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/logs/dir")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
logs_dir = cluster.logsDir()
|
|
|
|
assert logs_dir == "/fake/logs/dir"
|
|
|
|
@patch("os.makedirs")
|
|
def test_ensure_path_creates_directory(self, mock_makedirs):
|
|
"""TensileBenchmarkCluster.ensurePath creates directory."""
|
|
path = "/fake/new/path"
|
|
result = TensileBenchmarkCluster.ensurePath(path)
|
|
|
|
mock_makedirs.assert_called_once_with(path)
|
|
assert result == path
|
|
|
|
@patch("os.makedirs", side_effect=OSError("Directory exists"))
|
|
def test_ensure_path_ignores_os_error(self, mock_makedirs):
|
|
"""TensileBenchmarkCluster.ensurePath ignores OSError."""
|
|
path = "/existing/path"
|
|
result = TensileBenchmarkCluster.ensurePath(path)
|
|
|
|
mock_makedirs.assert_called_once_with(path)
|
|
assert result == path # Should still return path even on error
|
|
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_root_tensile_dir_returns_root_directory(self, mock_project_config, mock_init):
|
|
"""TensileBenchmarkCluster.rootTensileDir returns root Tensile directory."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(return_value="/fake/root/tensile")
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
root_dir = cluster.rootTensileDir()
|
|
|
|
assert root_dir == "/fake/root/tensile"
|
|
mock_config_instance.__getitem__.assert_called_with("RootTensileDir")
|
|
|
|
@patch("os.path.isdir")
|
|
@patch("os.listdir")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkSplitter")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.generateBenchmark")
|
|
@patch("os.makedirs")
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path", "--deploy-only"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_generate_cluster_benchmark_creates_directories(self, mock_project_config, mock_init,
|
|
mock_makedirs, mock_generate, mock_splitter,
|
|
mock_listdir, mock_isdir):
|
|
"""TensileBenchmarkCluster generate workflow creates necessary directories."""
|
|
args = ["logic.yaml", "/deploy/path", "--deploy-only"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(side_effect=lambda k: {
|
|
"BenchmarkBaseDir": "/fake/base",
|
|
"BenchmarkTasksDir": "/fake/tasks",
|
|
"BenchmarkImageDir": "/fake/image",
|
|
"BenchmarkResultsDir": "/fake/results",
|
|
"BenchmarkFinalLogicDir": "/fake/final",
|
|
"BenchmarkLogsDir": "/fake/logs",
|
|
"BenchmarkLogicPath": "logic.yaml",
|
|
"BenchmarkTaskSize": 10,
|
|
"RunDeployStep": True,
|
|
"RunBenchmarkStep": False,
|
|
"RunResultsStep": False,
|
|
}.get(k))
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
cluster.main()
|
|
|
|
# Should create all necessary directories
|
|
assert mock_makedirs.call_count >= 6
|
|
# Should split benchmark
|
|
mock_splitter.splitBenchmarkBySizes.assert_called_once()
|
|
# Should generate benchmark
|
|
mock_generate.assert_called_once()
|
|
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.postInvokeBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.invokeBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.preInvokeBenchmark")
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path", "--run-only"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_run_cluster_benchmark_invokes_backend(self, mock_project_config, mock_init,
|
|
mock_pre, mock_invoke, mock_post):
|
|
"""TensileBenchmarkCluster run workflow invokes backend methods."""
|
|
args = ["logic.yaml", "/deploy/path", "--run-only"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(side_effect=lambda k: {
|
|
"RunDeployStep": False,
|
|
"RunBenchmarkStep": True,
|
|
"RunResultsStep": False,
|
|
}.get(k))
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
cluster.main()
|
|
|
|
# Should call all three backend methods in order
|
|
mock_pre.assert_called_once()
|
|
mock_invoke.assert_called_once()
|
|
mock_post.assert_called_once()
|
|
|
|
@patch("Tensile.TensileBenchmarkCluster.mergePartialLogics")
|
|
@patch("os.path.isfile")
|
|
@patch("os.path.isdir")
|
|
@patch("os.listdir")
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path", "--results-only"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_combine_results_merges_partial_logics(self, mock_project_config, mock_init,
|
|
mock_listdir, mock_isdir, mock_isfile, mock_merge):
|
|
"""TensileBenchmarkCluster combine workflow merges partial results."""
|
|
args = ["logic.yaml", "/deploy/path", "--results-only"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(side_effect=lambda k: {
|
|
"BenchmarkResultsDir": "/fake/results",
|
|
"BenchmarkFinalLogicDir": "/fake/final",
|
|
"FinalLogicForceMerge": False,
|
|
"FinalLogicTrim": True,
|
|
"RunDeployStep": False,
|
|
"RunBenchmarkStep": False,
|
|
"RunResultsStep": True,
|
|
}.get(k))
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
# Mock directory structure with results
|
|
mock_listdir.side_effect = [
|
|
["result_0001", "result_0002"], # First call: list results subdirs
|
|
["logic.yaml"], # Second call: files in first subdir
|
|
["logic.yaml"], # Third call: files in second subdir
|
|
]
|
|
mock_isdir.return_value = True
|
|
mock_isfile.return_value = True
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
cluster.main()
|
|
|
|
# Should merge partial logics
|
|
mock_merge.assert_called_once()
|
|
|
|
@patch("Tensile.TensileBenchmarkCluster.mergePartialLogics")
|
|
@patch("os.path.isfile")
|
|
@patch("os.path.isdir")
|
|
@patch("os.listdir")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.postInvokeBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.invokeBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.preInvokeBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.generateBenchmark")
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkSplitter")
|
|
@patch("os.makedirs")
|
|
@patch("sys.argv", ["script.py", "logic.yaml", "/deploy/path"])
|
|
@patch("Tensile.TensileBenchmarkCluster.BenchmarkImplSLURM.initializeConfig")
|
|
@patch("Tensile.TensileBenchmarkCluster.ProjectConfig")
|
|
def test_main_runs_all_workflow_steps(self, mock_project_config, mock_init,
|
|
mock_makedirs, mock_splitter, mock_generate,
|
|
mock_pre, mock_invoke, mock_post,
|
|
mock_listdir, mock_isdir, mock_isfile, mock_merge):
|
|
"""TensileBenchmarkCluster.main runs all workflow steps."""
|
|
args = ["logic.yaml", "/deploy/path"]
|
|
|
|
mock_config_instance = MagicMock()
|
|
mock_config_instance.__getitem__ = Mock(side_effect=lambda k: {
|
|
"RunDeployStep": True,
|
|
"RunBenchmarkStep": True,
|
|
"RunResultsStep": True,
|
|
"BenchmarkBaseDir": "/fake/base",
|
|
"BenchmarkTasksDir": "/fake/tasks",
|
|
"BenchmarkImageDir": "/fake/image",
|
|
"BenchmarkResultsDir": "/fake/results",
|
|
"BenchmarkFinalLogicDir": "/fake/final",
|
|
"BenchmarkLogsDir": "/fake/logs",
|
|
"BenchmarkLogicPath": "logic.yaml",
|
|
"BenchmarkTaskSize": 10,
|
|
"FinalLogicForceMerge": False,
|
|
"FinalLogicTrim": True,
|
|
}.get(k))
|
|
mock_project_config.return_value = mock_config_instance
|
|
|
|
# Mock directory structure
|
|
mock_listdir.side_effect = [
|
|
["result_0001"],
|
|
["logic.yaml"],
|
|
]
|
|
mock_isdir.return_value = True
|
|
mock_isfile.return_value = True
|
|
|
|
cluster = TensileBenchmarkCluster(args)
|
|
cluster.main()
|
|
|
|
# Should run all three steps
|
|
mock_generate.assert_called_once()
|
|
mock_invoke.assert_called_once()
|
|
mock_merge.assert_called_once()
|