From 1e1056dd03694b1f39e2d758def78b464056ccc3 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Wed, 11 Sep 2024 11:09:48 -0400 Subject: [PATCH] prefer json= over body=, as the former sets the headers for you; fix some api endpoints --- .../actions/leader/experiment_profile.py | 29 +++++------- .../tests/test_execute_experiment_profile.py | 47 +++++++++++++++++++ 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/pioreactor/actions/leader/experiment_profile.py b/pioreactor/actions/leader/experiment_profile.py index 5978cbb6..8f7f9ebc 100644 --- a/pioreactor/actions/leader/experiment_profile.py +++ b/pioreactor/actions/leader/experiment_profile.py @@ -11,7 +11,6 @@ from typing import Optional import click -from msgspec.json import encode from msgspec.yaml import decode from pioreactor.cluster_management import get_active_workers_in_experiment @@ -536,13 +535,11 @@ def _callable() -> None: logger.info(f"Dry-run: Starting {job_name} on {unit} with options {options} and args {args}.") else: patch_into_leader( - f"/api/workers/{unit}/jobs/run/job_name/{job_name}/experiment/{experiment}", - body=encode( - { - "options": evaluate_options(options, env) | {"job_source": "experiment_profile"}, - "args": args, - } - ), + f"/api/workers/{unit}/jobs/run/job_name/{job_name}/experiments/{experiment}", + json={ + "options": evaluate_options(options, env) | {"job_source": "experiment_profile"}, + "args": args, + }, ) else: logger.debug(f"Action's `if` condition, `{if_}`, evaluated False. Skipping action.") @@ -574,8 +571,8 @@ def _callable() -> None: logger.info(f"Dry-run: Pausing {job_name} on {unit}.") else: patch_into_leader( - f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiment/{experiment}", - body=encode({"settings": {"state": "sleeping"}}), + f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiments/{experiment}", + json={"settings": {"$state": "sleeping"}}, ) else: logger.debug(f"Action's `if` condition, `{if_}`, evaluated False. Skipping action.") @@ -607,8 +604,8 @@ def _callable() -> None: logger.info(f"Dry-run: Resuming {job_name} on {unit}.") else: patch_into_leader( - f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiment/{experiment}", - body=encode({"settings": {"state": "ready"}}), + f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiments/{experiment}", + json={"settings": {"$state": "ready"}}, ) else: logger.debug(f"Action's `if` condition, `{if_}`, evaluated False. Skipping action.") @@ -640,8 +637,8 @@ def _callable() -> None: logger.info(f"Dry-run: Stopping {job_name} on {unit}.") else: patch_into_leader( - f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiment/{experiment}", - body=encode({"settings": {"state": "disconnected"}}), + f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiments/{experiment}", + json={"settings": {"$state": "disconnected"}}, ) else: logger.debug(f"Action's `if` condition, `{if_}`, evaluated False. Skipping action.") @@ -677,8 +674,8 @@ def _callable() -> None: else: for setting, value in evaluate_options(options, env).items(): patch_into_leader( - f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiment/{experiment}", - body=encode({"settings": {setting: value}}), + f"/api/workers/{unit}/jobs/update/job_name/{job_name}/experiments/{experiment}", + json={"settings": {setting: value}}, ) else: logger.debug(f"Action's `if` condition, `{if_}`, evaluated False. Skipping action.") diff --git a/pioreactor/tests/test_execute_experiment_profile.py b/pioreactor/tests/test_execute_experiment_profile.py index a4339913..88d11aa1 100644 --- a/pioreactor/tests/test_execute_experiment_profile.py +++ b/pioreactor/tests/test_execute_experiment_profile.py @@ -829,3 +829,50 @@ def test_profiles_in_github_repo() -> None: content = get(file["download_url"]).content profile = decode(content, type=Profile) assert _verify_experiment_profile(profile) + + +@patch("pioreactor.actions.leader.experiment_profile._load_experiment_profile") +def test_api_requests_are_made( + mock__load_experiment_profile, +) -> None: + experiment = "_testing_experiment" + + action1 = Start(hours_elapsed=0 / 60 / 60) + action2 = Start(hours_elapsed=2 / 60 / 60) + action3 = Stop(hours_elapsed=4 / 60 / 60) + + profile = Profile( + experiment_profile_name="test_profile", + plugins=[], + common=CommonBlock(jobs={"job1": Job(actions=[action1])}), + pioreactors={ + "unit1": PioreactorSpecificBlock(jobs={"job2": Job(actions=[action2, action3])}, label="label1"), + }, + metadata=Metadata(author="test_author"), + ) + + mock__load_experiment_profile.return_value = profile + + from pioreactor.tests.conftest import capture_requests + + with capture_requests() as bucket: + execute_experiment_profile("profile.yaml", experiment) + + assert len(bucket) == 5 + assert bucket[0].url == f"http://localhost:4999/api/experiments/{experiment}/unit_labels" + assert ( + bucket[1].url + == f"http://localhost:4999/api/workers/unit1/jobs/run/job_name/job1/experiments/{experiment}" + ) + assert ( + bucket[2].url + == f"http://localhost:4999/api/workers/unit2/jobs/run/job_name/job1/experiments/{experiment}" + ) + assert ( + bucket[3].url + == f"http://localhost:4999/api/workers/unit1/jobs/run/job_name/job2/experiments/{experiment}" + ) + assert ( + bucket[4].url + == f"http://localhost:4999/api/workers/unit1/jobs/update/job_name/job2/experiments/{experiment}" + )