Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
cd8b88f
Start introducing MockScheduler for better Scheduler testing
bpkroth May 19, 2025
2c9c968
fixup scheduler schemas refactor
bpkroth May 19, 2025
2f4a82e
reorg optimizer fixtures for reuse
bpkroth May 19, 2025
24ccf5a
reorg files based storage fixture
bpkroth May 19, 2025
bdfd9b0
adding basic scheduler config example loader test
bpkroth May 19, 2025
b66e17a
Refactor Scheduler schema definitions to make it easier to add new ones.
bpkroth May 19, 2025
30191c0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 19, 2025
bc8dc8f
Refactor some test fixtures for better reuse so we can test loading S…
bpkroth May 19, 2025
ea7b3ff
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 19, 2025
7563b8a
fixup
bpkroth May 19, 2025
b03e31c
lint
bpkroth May 19, 2025
8eb14c0
apply suggestions
bpkroth May 19, 2025
8ad4c3d
revert
bpkroth May 19, 2025
d4d5153
load test configs too
bpkroth May 19, 2025
1eb1acb
format
bpkroth May 19, 2025
947b759
Merge branch 'refactor/tests' into refactor/mock-scheduler-and-tests
bpkroth May 19, 2025
0c3c805
Merge branch 'refactor/scheduler-schemas' into refactor/mock-schedule…
bpkroth May 19, 2025
1112af4
list in __all__ so we load it as a part of tests schemas checking
bpkroth May 19, 2025
973ad2b
Merge branch 'main' into refactor/mock-scheduler-and-tests
bpkroth May 19, 2025
7a0d087
new mock scheduler schema and test configs
bpkroth May 19, 2025
dded243
refactor to split steps for easier hooking
bpkroth May 20, 2025
c305196
Merge remote-tracking branch 'upstream/main' into refactor/mock-sched…
bpkroth May 20, 2025
b16db23
Merge branch 'main' into refactor/mock-scheduler-and-tests
bpkroth May 20, 2025
f1fe022
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2025
83ff70f
Update mlos_bench/mlos_bench/tests/config/schedulers/test_load_schedu…
bpkroth May 20, 2025
71420e6
fixup
bpkroth May 20, 2025
70130ba
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2025
0a440a1
ignore the build tree in vscode
bpkroth May 20, 2025
efafc6f
adding more accessors
bpkroth May 22, 2025
842d393
wip: enable mock env to report arbitrary data
bpkroth May 22, 2025
19cec78
spelling
bpkroth May 22, 2025
175f315
refactor status parsing a little bit again
bpkroth May 22, 2025
7904716
extra test too
bpkroth May 22, 2025
54a96e8
more links
bpkroth May 22, 2025
2e1c4db
start adding a mock trial runner
bpkroth May 22, 2025
626554d
Revert "start adding a mock trial runner"
bpkroth May 22, 2025
b87c02a
schema work on mock trial data
bpkroth May 22, 2025
b4e5640
remove mock scheduler
bpkroth May 22, 2025
80cf2fa
allow mock trial data to be in the global config as well
bpkroth May 22, 2025
8426621
comments as prompts in preparation to run a trial
bpkroth May 22, 2025
cdc614f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2025
b3f49e9
fixups
bpkroth May 22, 2025
a41e85f
revert
bpkroth May 22, 2025
63e0f88
remove
bpkroth May 22, 2025
44bdde2
refactor status parsing a little bit again
bpkroth May 22, 2025
607fffd
extra test too
bpkroth May 22, 2025
aaf0842
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2025
8f472bb
revert
bpkroth May 22, 2025
8a4aac2
comments
bpkroth May 22, 2025
50ffde4
add accessor for the mock_trial_data property
bpkroth May 22, 2025
b1e2a52
make it a property
bpkroth May 22, 2025
f0f7c4c
add some basic fixtures to get started with
bpkroth May 22, 2025
c27b3c2
add a method for creating schedulers, intended to be used with pytest…
bpkroth May 22, 2025
9813268
stubbing out a very basic test to get started
bpkroth May 22, 2025
3b92017
wip: testing
bpkroth May 22, 2025
341564e
wip
bpkroth May 22, 2025
5c06814
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2025
836dcd9
comments
bpkroth May 22, 2025
0072141
fixups
bpkroth May 22, 2025
5400bd6
more checks
bpkroth May 22, 2025
e62a378
Add more checks
bpkroth May 22, 2025
206bb77
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2025
abe412b
linting
bpkroth May 22, 2025
f5cb468
doc tweaks
bpkroth May 22, 2025
c047bc2
Merge branch 'refactor/parse-status' into refactor/mock-scheduler-and…
bpkroth May 22, 2025
dc7a7b2
fixup
bpkroth May 22, 2025
76e94ed
fixup
bpkroth May 22, 2025
7f8522a
fixups
bpkroth May 22, 2025
9e03e63
remove old files
bpkroth May 22, 2025
f9e3339
add some common globals
bpkroth May 22, 2025
a05b5ae
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2025
94e31b5
simplify
bpkroth May 27, 2025
21e49db
rename
bpkroth May 27, 2025
46be004
fixup
bpkroth May 27, 2025
01f7a02
always try and convert metrics back to numerics if possible
bpkroth May 27, 2025
b035e57
wip: tell mysql to use a datetime that can store fractional seconds
bpkroth May 27, 2025
ca101ef
add more trial data for testing
bpkroth May 27, 2025
98ec1cc
:type fixups
bpkroth May 27, 2025
82f602c
check the telemetry
bpkroth May 27, 2025
176480f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 27, 2025
22f4e79
revert the bulk conversion one
bpkroth May 27, 2025
aa9f728
debugging
bpkroth May 27, 2025
6289216
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 27, 2025
5be025e
Merge branch 'main' into refactor/mock-scheduler-and-tests
bpkroth Jun 5, 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
Prev Previous commit
Next Next commit
Refactor some test fixtures for better reuse so we can test loading S…
…cheduler config examples.
  • Loading branch information
bpkroth committed May 19, 2025
commit bc8dc8f3b4878f0aa52fbcdbd2d68430d56f4f0c
3 changes: 3 additions & 0 deletions mlos_bench/mlos_bench/tests/config/schedulers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Unit tests for the mlos_bench Scheduler configs.
"""
54 changes: 54 additions & 0 deletions mlos_bench/mlos_bench/tests/config/schedulers/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
"""
Pytest fixtures for Scheduler config tests.

Provides fixtures for creating multiple TrialRunner instances using the mock environment config.
"""

from importlib.resources import files

import pytest

from mlos_bench.services.config_persistence import ConfigPersistenceService
from mlos_bench.schedulers.trial_runner import TrialRunner
from mlos_bench.util import path_join

# pylint: disable=redefined-outer-name

TRIAL_RUNNERS_COUNT = 4

@pytest.fixture
def mock_env_config_path() -> str:
"""
Returns the absolute path to the mock environment configuration file.
This file is used to create TrialRunner instances for testing.
"""

# Use the files() routine to locate the file relative to this directory
return path_join(
str(files("mlos_bench.config").joinpath("environments", "mock", "mock_env.jsonc")),
abs_path=True,
)


@pytest.fixture
def trial_runners(
config_loader_service: ConfigPersistenceService,
mock_env_config_path: str,
) -> list[TrialRunner]:
"""
Fixture that returns a list of TrialRunner instances using the mock environment config.

Returns
-------
list[TrialRunner]
List of TrialRunner instances created from the mock environment config.
"""
return TrialRunner.create_from_json(
config_loader=config_loader_service,
env_json=mock_env_config_path,
num_trial_runners=TRIAL_RUNNERS_COUNT,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
"""Tests for loading scheduler config examples."""
import logging

import pytest

from mlos_bench.config.schemas.config_schemas import ConfigSchema
from mlos_bench.optimizers.mock_optimizer import MockOptimizer
from mlos_bench.schedulers.base_scheduler import Scheduler
from mlos_bench.schedulers.trial_runner import TrialRunner
from mlos_bench.services.config_persistence import ConfigPersistenceService
from mlos_bench.storage.sql.storage import SqlStorage
from mlos_bench.tests.config import locate_config_examples
from mlos_bench.util import get_class_from_name

import mlos_bench.tests.storage.sql.fixtures
import mlos_bench.tests.optimizers.fixtures

Comment thread
bpkroth marked this conversation as resolved.
Outdated
mock_opt = mlos_bench.tests.optimizers.fixtures.mock_opt
sqlite_storage = mlos_bench.tests.storage.sql.fixtures.sqlite_storage


_LOG = logging.getLogger(__name__)
_LOG.setLevel(logging.DEBUG)

# pylint: disable=redefined-outer-name

# Get the set of configs to test.
CONFIG_TYPE = "schedulers"


def filter_configs(configs_to_filter: list[str]) -> list[str]:
"""If necessary, filter out json files that aren't for the module we're testing."""
return configs_to_filter


configs = locate_config_examples(
ConfigPersistenceService.BUILTIN_CONFIG_PATH,
CONFIG_TYPE,
filter_configs,
)
assert configs


@pytest.mark.parametrize("config_path", configs)
def test_load_scheduler_config_examples(
config_loader_service: ConfigPersistenceService,
config_path: str,
mock_env_config_path: str,
trial_runners: list[TrialRunner],
sqlite_storage: SqlStorage,
mock_opt: MockOptimizer,
) -> None:
"""Tests loading a config example."""
config = config_loader_service.load_config(config_path, ConfigSchema.SCHEDULER)
assert isinstance(config, dict)
cls = get_class_from_name(config["class"])
assert issubclass(cls, Scheduler)
global_config = {
# Required configs generally provided by the Launcher.
"experiment_id": f"test_experiment_{__name__}",
"trial_id": 1,
}
# Make an instance of the class based on the config.
scheduler_inst = config_loader_service.build_scheduler(
config=config,
global_config=global_config,
trial_runners=trial_runners,
optimizer=mock_opt,
storage=sqlite_storage,
root_env_config=mock_env_config_path,
)
assert scheduler_inst is not None
assert isinstance(scheduler_inst, cls)
180 changes: 13 additions & 167 deletions mlos_bench/mlos_bench/tests/optimizers/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,170 +2,16 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
"""Test fixtures for mlos_bench optimizers."""


import pytest

from mlos_bench.optimizers.manual_optimizer import ManualOptimizer
from mlos_bench.optimizers.mlos_core_optimizer import MlosCoreOptimizer
from mlos_bench.optimizers.mock_optimizer import MockOptimizer
from mlos_bench.tests import SEED
from mlos_bench.tunables.tunable_groups import TunableGroups

# pylint: disable=redefined-outer-name


@pytest.fixture
def mock_configs() -> list[dict]:
"""Mock configurations of earlier experiments."""
return [
{
"vmSize": "Standard_B4ms",
"idle": "halt",
"kernel_sched_migration_cost_ns": 50000,
"kernel_sched_latency_ns": 1000000,
},
{
"vmSize": "Standard_B4ms",
"idle": "halt",
"kernel_sched_migration_cost_ns": 40000,
"kernel_sched_latency_ns": 2000000,
},
{
"vmSize": "Standard_B4ms",
"idle": "mwait",
"kernel_sched_migration_cost_ns": -1, # Special value
"kernel_sched_latency_ns": 3000000,
},
{
"vmSize": "Standard_B2s",
"idle": "mwait",
"kernel_sched_migration_cost_ns": 200000,
"kernel_sched_latency_ns": 4000000,
},
]


@pytest.fixture
def mock_opt_no_defaults(tunable_groups: TunableGroups) -> MockOptimizer:
"""Test fixture for MockOptimizer that ignores the initial configuration."""
return MockOptimizer(
tunables=tunable_groups,
service=None,
config={
"optimization_targets": {"score": "min"},
"max_suggestions": 5,
"start_with_defaults": False,
"seed": SEED,
},
)


@pytest.fixture
def mock_opt(tunable_groups: TunableGroups) -> MockOptimizer:
"""Test fixture for MockOptimizer."""
return MockOptimizer(
tunables=tunable_groups,
service=None,
config={"optimization_targets": {"score": "min"}, "max_suggestions": 5, "seed": SEED},
)


@pytest.fixture
def mock_opt_max(tunable_groups: TunableGroups) -> MockOptimizer:
"""Test fixture for MockOptimizer."""
return MockOptimizer(
tunables=tunable_groups,
service=None,
config={"optimization_targets": {"score": "max"}, "max_suggestions": 10, "seed": SEED},
)


@pytest.fixture
def flaml_opt(tunable_groups: TunableGroups) -> MlosCoreOptimizer:
"""Test fixture for mlos_core FLAML optimizer."""
return MlosCoreOptimizer(
tunables=tunable_groups,
service=None,
config={
"optimization_targets": {"score": "min"},
"max_suggestions": 15,
"optimizer_type": "FLAML",
"seed": SEED,
},
)


@pytest.fixture
def flaml_opt_max(tunable_groups: TunableGroups) -> MlosCoreOptimizer:
"""Test fixture for mlos_core FLAML optimizer."""
return MlosCoreOptimizer(
tunables=tunable_groups,
service=None,
config={
"optimization_targets": {"score": "max"},
"max_suggestions": 15,
"optimizer_type": "FLAML",
"seed": SEED,
},
)


# FIXME: SMAC's RF model can be non-deterministic at low iterations, which are
# normally calculated as a percentage of the max_suggestions and number of
# tunable dimensions, so for now we set the initial random samples equal to the
# number of iterations and control them with a seed.

SMAC_ITERATIONS = 10


@pytest.fixture
def smac_opt(tunable_groups: TunableGroups) -> MlosCoreOptimizer:
"""Test fixture for mlos_core SMAC optimizer."""
return MlosCoreOptimizer(
tunables=tunable_groups,
service=None,
config={
"optimization_targets": {"score": "min"},
"max_suggestions": SMAC_ITERATIONS,
"optimizer_type": "SMAC",
"seed": SEED,
"output_directory": None,
# See Above
"n_random_init": SMAC_ITERATIONS,
"max_ratio": 1.0,
},
)


@pytest.fixture
def smac_opt_max(tunable_groups: TunableGroups) -> MlosCoreOptimizer:
"""Test fixture for mlos_core SMAC optimizer."""
return MlosCoreOptimizer(
tunables=tunable_groups,
service=None,
config={
"optimization_targets": {"score": "max"},
"max_suggestions": SMAC_ITERATIONS,
"optimizer_type": "SMAC",
"seed": SEED,
"output_directory": None,
# See Above
"n_random_init": SMAC_ITERATIONS,
"max_ratio": 1.0,
},
)


@pytest.fixture
def manual_opt(tunable_groups: TunableGroups, mock_configs: list[dict]) -> ManualOptimizer:
"""Test fixture for ManualOptimizer."""
return ManualOptimizer(
tunables=tunable_groups,
service=None,
config={
"max_cycles": 2,
"tunable_values_cycle": mock_configs,
},
)
"""Export test fixtures for mlos_bench optimizers."""

import mlos_bench.tests.optimizers.fixtures

mock_configs = mlos_bench.tests.optimizers.fixtures.mock_configs
mock_opt_no_defaults = mlos_bench.tests.optimizers.fixtures.mock_opt_no_defaults
mock_opt = mlos_bench.tests.optimizers.fixtures.mock_opt
mock_opt_max = mlos_bench.tests.optimizers.fixtures.mock_opt_max
flaml_opt = mlos_bench.tests.optimizers.fixtures.flaml_opt
flaml_opt_max = mlos_bench.tests.optimizers.fixtures.flaml_opt_max
smac_opt = mlos_bench.tests.optimizers.fixtures.smac_opt
smac_opt_max = mlos_bench.tests.optimizers.fixtures.smac_opt_max
manual_opt = mlos_bench.tests.optimizers.fixtures.manual_opt
Loading
Loading