Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 11 additions & 3 deletions src/simstack/core/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,18 @@ async def initialize_default_resource():
ResourceDefinition.resource_str == str(context.config.resource)
)

if resource_def is None:
logger.warning(
"No ResourceDefinition found for '%s'; skipping default-resource initialization.",
str(context.config.resource),
)
return None

if resource_def.is_default:
config_path = context.config.project_root / "config.toml"
if not config_path.exists():
logger.warning(f"Default resource detected, but {config_path} not found.")
return
return resource_def

try:
with open(config_path, "rb") as f:
Expand All @@ -40,7 +47,7 @@ async def initialize_default_resource():
active_dirs = config_data.get("active_dirs", [])
if not active_dirs:
logger.info("No active_dirs found in config.toml.")
return
return resource_def

logger.info(f"Default resource: initializing tables for {active_dirs}")
await make_node_table(context.db.engine, dirs=active_dirs)
Expand All @@ -57,11 +64,12 @@ async def async_main(args):

# Initialize tables if this is the default resource
resource_def = await initialize_default_resource()
is_default_resource = bool(resource_def and resource_def.is_default)

if args.resource:
logger.info(f"Setting resource for runner to {args.resource}")
runner_manager = RunnerManager(context.config.resource, detach=args.detach, no_pull=args.no_pull,
is_default=resource_def.is_default)
is_default=is_default_resource)
await runner_manager.run_nodes_for_resource(args.polling_interval, 10, timeout=args.timeout)


Expand Down
77 changes: 77 additions & 0 deletions tests/without_context/test_runner_default_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from types import SimpleNamespace
from unittest.mock import AsyncMock

import pytest

from simstack.core import runner


@pytest.mark.asyncio
async def test_initialize_default_resource_returns_none_when_resource_is_missing(tmp_path, monkeypatch):
db = SimpleNamespace(find_one=AsyncMock(return_value=None))
config = SimpleNamespace(resource="docker", project_root=tmp_path)
monkeypatch.setattr(runner, "context", SimpleNamespace(db=db, config=config))

result = await runner.initialize_default_resource()

assert result is None


@pytest.mark.asyncio
async def test_initialize_default_resource_keeps_resource_when_config_toml_missing(tmp_path, monkeypatch):
resource_def = SimpleNamespace(is_default=True)
db = SimpleNamespace(find_one=AsyncMock(return_value=resource_def), engine=object())
config = SimpleNamespace(resource="docker", project_root=tmp_path)

make_node_table = AsyncMock()
make_model_table = AsyncMock()
monkeypatch.setattr(runner, "context", SimpleNamespace(db=db, config=config))
monkeypatch.setattr(runner, "make_node_table", make_node_table)
monkeypatch.setattr(runner, "make_model_table", make_model_table)

result = await runner.initialize_default_resource()

assert result is resource_def
make_node_table.assert_not_called()
make_model_table.assert_not_called()


@pytest.mark.asyncio
async def test_async_main_uses_false_is_default_when_default_resource_init_returns_none(monkeypatch):
captured: dict[str, object] = {}

class DummyContext:
def __init__(self):
self.config = SimpleNamespace(resource="docker")

async def initialize(self, **kwargs):
self.config = SimpleNamespace(resource=kwargs.get("resource"))

class DummyRunnerManager:
def __init__(self, resource, *, detach, no_pull, is_default):
captured["resource"] = resource
captured["detach"] = detach
captured["no_pull"] = no_pull
captured["is_default"] = is_default

async def run_nodes_for_resource(self, polling_interval, *_args, timeout=None):
captured["polling_interval"] = polling_interval
captured["timeout"] = timeout

monkeypatch.setattr(runner, "context", DummyContext())
monkeypatch.setattr(runner, "initialize_default_resource", AsyncMock(return_value=None))
monkeypatch.setattr(runner, "RunnerManager", DummyRunnerManager)

args = SimpleNamespace(
resource="docker",
db_name=None,
detach=True,
no_pull=False,
polling_interval=5,
timeout=None,
)

await runner.async_main(args)

assert captured["is_default"] is False
assert captured["resource"] == "docker"
Loading