From 1f34454e493d768fe2870f37a2e78f8c3bba5272 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 24 Oct 2024 18:36:57 -0600 Subject: [PATCH 01/10] test(acceptance): add test to read configs --- tests/acceptance/test_softmaxAC_mc.py | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/acceptance/test_softmaxAC_mc.py diff --git a/tests/acceptance/test_softmaxAC_mc.py b/tests/acceptance/test_softmaxAC_mc.py new file mode 100644 index 0000000..6d59d86 --- /dev/null +++ b/tests/acceptance/test_softmaxAC_mc.py @@ -0,0 +1,58 @@ +from ml_experiment.ExperimentDefinition import ExperimentDefinition +from ml_experiment.DefinitionPart import DefinitionPart + + +def init_softmaxAC_mc(alphas: list[float], taus: list[float]): + softmaxAC = DefinitionPart("softmaxAC-mc") + softmaxAC.add_sweepable_property("alpha", alphas) + softmaxAC.add_sweepable_property("tau", taus) + softmaxAC.add_property("n_step", 1) + softmaxAC.add_property("tiles", 4) + softmaxAC.add_property("tilings", 16) + softmaxAC.add_property("total_steps", 100000) + softmaxAC.add_property("episode_cutoff", 5000) + softmaxAC.commit() + + +def test_read_configs(): + """ + Test that we can retrieve the configurations from the experiment definition. + """ + + # expected outputs + alphas = [0.05, 0.01] + taus = [10.0, 20.0, 5.0] + partial_configs = ( + { + "alpha": a, + "tau": t, + "n_step": 1, + "tiles": 4, + "tilings": 16, + "total_steps": 100000, + "episode_cutoff": 5000, + } + for a in alphas + for t in taus + ) + expected_configs = ( + { + **config, + "id": i, + } + for i, config in enumerate(partial_configs) + ) + + # write experiment definition to table + init_softmaxAC_mc(alphas, taus) + + # make Experiment object (versions start at 0) + softmaxAC_mc = ExperimentDefinition("softmaxAC-mc", 0) + + # TODO: This can't be the intended way to get the configurations? + num_configs = len(alphas) * len(taus) + config_ids = list(range(num_configs)) + + for cid, expected_config in zip(config_ids, expected_configs, strict=True): + config = softmaxAC_mc.get_config(cid) + assert config == expected_config From 3c2bc8eb2e23534e1899ea379d36be19a4901105 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 24 Oct 2024 18:41:23 -0600 Subject: [PATCH 02/10] test(acceptance): add test for writing configs to database --- tests/test_generate_configurations.py | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/test_generate_configurations.py diff --git a/tests/test_generate_configurations.py b/tests/test_generate_configurations.py new file mode 100644 index 0000000..f4c0d4b --- /dev/null +++ b/tests/test_generate_configurations.py @@ -0,0 +1,51 @@ +from ml_experiment import DefinitionPart as dp + + +def init_esarsa_mc(alphas: list[float], epsilons: list[float], n_steps: list[int]): + esarsa = dp.DefinitionPart("esarsa-mc") + esarsa.add_sweepable_property("alpha", alphas) + esarsa.add_sweepable_property("epsilon", epsilons) + esarsa.add_sweepable_property("n_step", n_steps) + esarsa.add_property("tiles", 4) + esarsa.add_property("tilings", 16) + esarsa.add_property("total_steps", 100000) + esarsa.add_property("episode_cutoff", 5000) + esarsa.commit() + + return esarsa + + +def test_generate_configurations(): + """ + Tests that the dp.generate_configurations function returns the same configurations as the ones written by the dp.DefinitionPart.commit function. + + Note: configs do not have ID numbers + """ + + # expected outputs + alphas = [0.5, 0.25, 0.125] + epsilons = [0.1, 0.05, 0.15] + n_steps = [2, 3] + expected_configs = ( + { + "alpha": a, + "epsilon": e, + "n_step": n, + "tiles": 4, + "tilings": 16, + "total_steps": 100000, + "episode_cutoff": 5000, + } + for a in alphas + for e in epsilons + for n in n_steps + ) + + # write experiment definition to table + esarsa_mc = init_esarsa_mc(alphas, epsilons, n_steps) + + # get all the hyperparameter configurations + configs = dp.generate_configurations(esarsa_mc._properties) + + for config, expected_config in zip(configs, expected_configs, strict=True): + assert config == expected_config From db88df28aa30e05203f50962a619e8e731f95813 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 24 Oct 2024 19:20:39 -0600 Subject: [PATCH 03/10] test: use pytest's tmp_path in tests --- tests/acceptance/test_softmaxAC_mc.py | 10 +++++----- tests/test_generate_configurations.py | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/acceptance/test_softmaxAC_mc.py b/tests/acceptance/test_softmaxAC_mc.py index 6d59d86..96be810 100644 --- a/tests/acceptance/test_softmaxAC_mc.py +++ b/tests/acceptance/test_softmaxAC_mc.py @@ -2,8 +2,8 @@ from ml_experiment.DefinitionPart import DefinitionPart -def init_softmaxAC_mc(alphas: list[float], taus: list[float]): - softmaxAC = DefinitionPart("softmaxAC-mc") +def init_softmaxAC_mc(tmp_path, alphas: list[float], taus: list[float]): + softmaxAC = DefinitionPart("softmaxAC-mc", base=str(tmp_path)) softmaxAC.add_sweepable_property("alpha", alphas) softmaxAC.add_sweepable_property("tau", taus) softmaxAC.add_property("n_step", 1) @@ -14,7 +14,7 @@ def init_softmaxAC_mc(alphas: list[float], taus: list[float]): softmaxAC.commit() -def test_read_configs(): +def test_read_configs(tmp_path): """ Test that we can retrieve the configurations from the experiment definition. """ @@ -44,10 +44,10 @@ def test_read_configs(): ) # write experiment definition to table - init_softmaxAC_mc(alphas, taus) + init_softmaxAC_mc(tmp_path, alphas, taus) # make Experiment object (versions start at 0) - softmaxAC_mc = ExperimentDefinition("softmaxAC-mc", 0) + softmaxAC_mc = ExperimentDefinition(part_name="softmaxAC-mc", version=0, base=str(tmp_path)) # TODO: This can't be the intended way to get the configurations? num_configs = len(alphas) * len(taus) diff --git a/tests/test_generate_configurations.py b/tests/test_generate_configurations.py index f4c0d4b..f6b14d0 100644 --- a/tests/test_generate_configurations.py +++ b/tests/test_generate_configurations.py @@ -1,8 +1,9 @@ from ml_experiment import DefinitionPart as dp -def init_esarsa_mc(alphas: list[float], epsilons: list[float], n_steps: list[int]): - esarsa = dp.DefinitionPart("esarsa-mc") +def init_esarsa_mc(tmp_path, alphas: list[float], epsilons: list[float], n_steps: list[int]): + + esarsa = dp.DefinitionPart("esarsa-mc", base=str(tmp_path)) esarsa.add_sweepable_property("alpha", alphas) esarsa.add_sweepable_property("epsilon", epsilons) esarsa.add_sweepable_property("n_step", n_steps) @@ -15,7 +16,7 @@ def init_esarsa_mc(alphas: list[float], epsilons: list[float], n_steps: list[int return esarsa -def test_generate_configurations(): +def test_generate_configurations(tmp_path): """ Tests that the dp.generate_configurations function returns the same configurations as the ones written by the dp.DefinitionPart.commit function. @@ -42,7 +43,7 @@ def test_generate_configurations(): ) # write experiment definition to table - esarsa_mc = init_esarsa_mc(alphas, epsilons, n_steps) + esarsa_mc = init_esarsa_mc(tmp_path, alphas, epsilons, n_steps) # get all the hyperparameter configurations configs = dp.generate_configurations(esarsa_mc._properties) From fd1882e242887dd18e40f0d1a4f206e30714e533 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 24 Oct 2024 19:30:11 -0600 Subject: [PATCH 04/10] test: add init.py to acceptance tests to enable pytest collection --- tests/acceptance/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/acceptance/__init__.py diff --git a/tests/acceptance/__init__.py b/tests/acceptance/__init__.py new file mode 100644 index 0000000..e69de29 From ebc0acf2e1c561c3fa57773948dc0e13cefb013d Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Fri, 25 Oct 2024 17:19:29 -0600 Subject: [PATCH 05/10] test: implement acceptance test using scheduler This test includes some janky passing of results path. Needs to be fixed outside of test. Towards: #8 --- tests/acceptance/my_experiment.py | 68 ++++++++++++++++++++ tests/acceptance/test_softmaxAC_mc.py | 89 +++++++++++++++++++++++++-- 2 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 tests/acceptance/my_experiment.py diff --git a/tests/acceptance/my_experiment.py b/tests/acceptance/my_experiment.py new file mode 100644 index 0000000..27637b7 --- /dev/null +++ b/tests/acceptance/my_experiment.py @@ -0,0 +1,68 @@ +import argparse +import random + +from ml_experiment.ExperimentDefinition import ExperimentDefinition + +parser = argparse.ArgumentParser() +parser.add_argument("--part", type=str, required=True) +parser.add_argument("--config-id", type=int, required=True) +parser.add_argument("--seed", type=int, required=True) +parser.add_argument("--version", type=int, required=True) + +# this is an extra argument for testing +# we need to be able to find the metadata database +# TODO: remove this +parser.add_argument("--results_path", type=str, required=True) + +class SoftmaxAC: + def __init__( + self, + alpha: float, + tau: float, + nstep: float, + tiles: int, + tilings: int, + ) -> None: + self.alpha = alpha + self.tau = tau + self.nstep = nstep + self.tiles = tiles + self.tilings = tilings + self.name = "SoftmaxAC" + + def run(self) -> str: + return f"{self.name}({self.alpha}, {self.tau}, {self.nstep}, {self.tiles}, {self.tilings})" + + +def main(): + cmdline = parser.parse_args() + + # make sure we are using softmaxAC + if cmdline.part != "softmaxAC": + raise ValueError(f"Unknown part: {cmdline.part}") + + # do some rng control + random.seed(cmdline.seed) + + # extract configs from the database + exp = ExperimentDefinition("softmaxAC", cmdline.version) + # TODO: don't overwrite this + exp.get_results_path = lambda *args, **kwargs: cmdline.results_path # overwrite results path + config = exp.get_config(cmdline.config_id) + + # make our dummy agent + alpha = config["alpha"] + tau = config["tau"] + n_step = config["n_step"] + tiles = config["tiles"] + tilings = config["tilings"] + agent = SoftmaxAC(alpha, tau, n_step, tiles, tilings) + + # run the agent + output = agent.run() + + # test output + assert output == f"SoftmaxAC({alpha}, {tau}, {n_step}, {tiles}, {tilings})" + +if __name__ == "__main__": + main() diff --git a/tests/acceptance/test_softmaxAC_mc.py b/tests/acceptance/test_softmaxAC_mc.py index 96be810..7566f77 100644 --- a/tests/acceptance/test_softmaxAC_mc.py +++ b/tests/acceptance/test_softmaxAC_mc.py @@ -1,25 +1,56 @@ +import os +import subprocess + from ml_experiment.ExperimentDefinition import ExperimentDefinition from ml_experiment.DefinitionPart import DefinitionPart +from ml_experiment.Scheduler import LocalRunConfig, RunSpec, Scheduler + +def write_database(results_path, alphas: list[float], taus: list[float]): + # make table writer + softmaxAC = DefinitionPart("softmaxAC") + # TODO: don't overwrite this + softmaxAC.get_results_path = lambda *args, **kwargs: results_path -def init_softmaxAC_mc(tmp_path, alphas: list[float], taus: list[float]): - softmaxAC = DefinitionPart("softmaxAC-mc", base=str(tmp_path)) + # add properties to sweep softmaxAC.add_sweepable_property("alpha", alphas) softmaxAC.add_sweepable_property("tau", taus) + + # add properties that are static softmaxAC.add_property("n_step", 1) softmaxAC.add_property("tiles", 4) softmaxAC.add_property("tilings", 16) softmaxAC.add_property("total_steps", 100000) softmaxAC.add_property("episode_cutoff", 5000) + softmaxAC.add_property("seed", 10) + + # write the properties to the database softmaxAC.commit() + return softmaxAC + + +## TODO: remove this and use the actual scheduler +# overwrite the run_single function +class StubScheduler(Scheduler): -def test_read_configs(tmp_path): + # allows us to force the results path to be in a specific spot + def __init__(self, results_path: str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.results_path = results_path + + # adding the results path to the command + def _run_single(self: Scheduler, r: RunSpec) -> None: + subprocess.run(['python', self.entry, '--part', r.part_name, '--config-id', str(r.config_id), '--seed', str(r.seed), '--version', str(r.version), '--results_path', self.results_path]) + + +def test_read_database(tmp_path): """ Test that we can retrieve the configurations from the experiment definition. """ # expected outputs + results_path = os.path.join(tmp_path, "results", "temp") alphas = [0.05, 0.01] taus = [10.0, 20.0, 5.0] partial_configs = ( @@ -31,6 +62,7 @@ def test_read_configs(tmp_path): "tilings": 16, "total_steps": 100000, "episode_cutoff": 5000, + "seed": 10, } for a in alphas for t in taus @@ -44,10 +76,14 @@ def test_read_configs(tmp_path): ) # write experiment definition to table - init_softmaxAC_mc(tmp_path, alphas, taus) + write_database(results_path, alphas, taus) # make Experiment object (versions start at 0) - softmaxAC_mc = ExperimentDefinition(part_name="softmaxAC-mc", version=0, base=str(tmp_path)) + softmaxAC_mc = ExperimentDefinition( + part_name="softmaxAC", version=0 + ) + # TODO: don't overwrite this + softmaxAC_mc.get_results_path = lambda *args, **kwargs: results_path # TODO: This can't be the intended way to get the configurations? num_configs = len(alphas) * len(taus) @@ -56,3 +92,46 @@ def test_read_configs(tmp_path): for cid, expected_config in zip(config_ids, expected_configs, strict=True): config = softmaxAC_mc.get_config(cid) assert config == expected_config + + +def test_run_tasks(tmp_path): + """Make sure that the scheduler runs all the tasks, and that they return the correct results.""" + # setup + alphas = [0.05, 0.01] + taus = [10.0, 20.0, 5.0] + results_path = os.path.join(tmp_path, "results", "temp") + db = write_database(results_path, alphas, taus) + + assert db.name == "softmaxAC" + assert os.path.exists(os.path.join(results_path, "metadata.db")) + + # get number of tasks to run in parallel + try: + import multiprocessing + + ntasks = multiprocessing.cpu_count() - 1 + except (ImportError, NotImplementedError): + ntasks = 1 + + # initialize run config + run_conf = LocalRunConfig(tasks_in_parallel=ntasks, log_path=".logs/") + + # set up experiment file + experiment_file_name = "tests/acceptance/my_experiment.py" + + # set up scheduler + sched = StubScheduler( + exp_name="temp", + entry=experiment_file_name, + seeds=[10], + version=0, + results_path=results_path, + base = str(tmp_path), + ) + + # run all the tasks + ( + sched + .get_all_runs() + .run(run_conf) + ) From 1225cc2032229a2b56a1483d086b909377f6635e Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Tue, 29 Oct 2024 14:50:10 -0600 Subject: [PATCH 06/10] test: add file io to confirm the correct dummy experiments are being run --- tests/acceptance/my_experiment.py | 11 ++--- tests/acceptance/test_softmaxAC_mc.py | 66 ++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/tests/acceptance/my_experiment.py b/tests/acceptance/my_experiment.py index 27637b7..d956dc1 100644 --- a/tests/acceptance/my_experiment.py +++ b/tests/acceptance/my_experiment.py @@ -1,4 +1,5 @@ import argparse +import os import random from ml_experiment.ExperimentDefinition import ExperimentDefinition @@ -8,10 +9,6 @@ parser.add_argument("--config-id", type=int, required=True) parser.add_argument("--seed", type=int, required=True) parser.add_argument("--version", type=int, required=True) - -# this is an extra argument for testing -# we need to be able to find the metadata database -# TODO: remove this parser.add_argument("--results_path", type=str, required=True) class SoftmaxAC: @@ -61,8 +58,10 @@ def main(): # run the agent output = agent.run() - # test output - assert output == f"SoftmaxAC({alpha}, {tau}, {n_step}, {tiles}, {tilings})" + # write the output to a file + output_path = os.path.join(cmdline.results_path, f"output_{cmdline.config_id}.txt") + with open(output_path, "w") as f: + f.write(output) if __name__ == "__main__": main() diff --git a/tests/acceptance/test_softmaxAC_mc.py b/tests/acceptance/test_softmaxAC_mc.py index 7566f77..1bf30c4 100644 --- a/tests/acceptance/test_softmaxAC_mc.py +++ b/tests/acceptance/test_softmaxAC_mc.py @@ -9,7 +9,8 @@ def write_database(results_path, alphas: list[float], taus: list[float]): # make table writer softmaxAC = DefinitionPart("softmaxAC") - # TODO: don't overwrite this + + # overwrite the results path to be in the temp directory softmaxAC.get_results_path = lambda *args, **kwargs: results_path # add properties to sweep @@ -30,7 +31,6 @@ def write_database(results_path, alphas: list[float], taus: list[float]): return softmaxAC -## TODO: remove this and use the actual scheduler # overwrite the run_single function class StubScheduler(Scheduler): @@ -82,10 +82,11 @@ def test_read_database(tmp_path): softmaxAC_mc = ExperimentDefinition( part_name="softmaxAC", version=0 ) - # TODO: don't overwrite this + + # overwrite the results path to be in the temp directory softmaxAC_mc.get_results_path = lambda *args, **kwargs: results_path - # TODO: This can't be the intended way to get the configurations? + # get the configuration ids num_configs = len(alphas) * len(taus) config_ids = list(range(num_configs)) @@ -99,6 +100,27 @@ def test_run_tasks(tmp_path): # setup alphas = [0.05, 0.01] taus = [10.0, 20.0, 5.0] + seed_num = 10 + version_num = 0 + + # expected outputs + partial_configs = ( + { + "alpha": a, + "tau": t, + "n_step": 1, + "tiles": 4, + "tilings": 16, + "total_steps": 100000, + "episode_cutoff": 5000, + "seed": 10, + } + for a in alphas + for t in taus + ) + expected_configs = {i : config for i, config in enumerate(partial_configs)} + + # write experiment definition to table results_path = os.path.join(tmp_path, "results", "temp") db = write_database(results_path, alphas, taus) @@ -123,15 +145,37 @@ def test_run_tasks(tmp_path): sched = StubScheduler( exp_name="temp", entry=experiment_file_name, - seeds=[10], - version=0, + seeds=[seed_num], + version=version_num, results_path=results_path, base = str(tmp_path), ) # run all the tasks - ( - sched - .get_all_runs() - .run(run_conf) - ) + sched = sched.get_all_runs() + sched.run(run_conf) + + # make sure there are the correct amount of runs + assert len(sched.all_runs) == len(expected_configs.keys()) + + # check that the output files were created + for runspec in sched.all_runs: + + # sanity check: make sure the runspec uses the hardcoded part, version, and seed + assert runspec.part_name == "softmaxAC" + assert runspec.version == version_num + assert runspec.seed == seed_num + + # get the expected output + expected_config = expected_configs[runspec.config_id] + expected_output = f"SoftmaxAC({expected_config['alpha']}, {expected_config['tau']}, {expected_config['n_step']}, {expected_config['tiles']}, {expected_config['tilings']})" + + # check that the output file was created + output_path = os.path.join(results_path, f"output_{runspec.config_id}.txt") + with open(output_path, "r") as f: + output = f.read() + assert output.strip() == expected_output + + + + From f018acb5cbecc5f9ffa74907885bb1c0d231e346 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Wed, 30 Oct 2024 17:22:43 -0600 Subject: [PATCH 07/10] test: add pytest fixture to overwrite __main__.__file__ This makes pytest compatible with _utils.path.get_experiment_name() Fixes: #18 --- ml_experiment/Scheduler.py | 2 +- tests/acceptance/test_softmaxAC_mc.py | 39 ++++++++++++++------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/ml_experiment/Scheduler.py b/ml_experiment/Scheduler.py index 0c2642c..8d8d5a4 100644 --- a/ml_experiment/Scheduler.py +++ b/ml_experiment/Scheduler.py @@ -126,6 +126,6 @@ def _resolve_version( def _sanity_check(self): res_path = os.path.join(self.base_path, 'results', self.exp_name, 'metadata.db') - assert os.path.exists(res_path), f'{self.exp_name} does not exist' + assert os.path.exists(res_path), f'{res_path}: {self.exp_name} does not exist' diff --git a/tests/acceptance/test_softmaxAC_mc.py b/tests/acceptance/test_softmaxAC_mc.py index 1bf30c4..37eebc7 100644 --- a/tests/acceptance/test_softmaxAC_mc.py +++ b/tests/acceptance/test_softmaxAC_mc.py @@ -1,4 +1,5 @@ import os +import pytest import subprocess from ml_experiment.ExperimentDefinition import ExperimentDefinition @@ -6,12 +7,15 @@ from ml_experiment.Scheduler import LocalRunConfig, RunSpec, Scheduler -def write_database(results_path, alphas: list[float], taus: list[float]): - # make table writer - softmaxAC = DefinitionPart("softmaxAC") +@pytest.fixture +def base_path(request): + """Overwrite the __main__.__file__ to be the path to the current file. This allows _utils.get_experiment_name to look at ./tests/acceptance/this_file.py rather than ./.venv/bin/pytest.""" + import __main__ + __main__.__file__ = request.path.__fspath__() - # overwrite the results path to be in the temp directory - softmaxAC.get_results_path = lambda *args, **kwargs: results_path +def write_database(tmp_path, alphas: list[float], taus: list[float]): + # make table writer + softmaxAC = DefinitionPart("softmaxAC", base=str(tmp_path)) # add properties to sweep softmaxAC.add_sweepable_property("alpha", alphas) @@ -44,13 +48,12 @@ def _run_single(self: Scheduler, r: RunSpec) -> None: subprocess.run(['python', self.entry, '--part', r.part_name, '--config-id', str(r.config_id), '--seed', str(r.seed), '--version', str(r.version), '--results_path', self.results_path]) -def test_read_database(tmp_path): +def test_read_database(tmp_path, base_path): """ Test that we can retrieve the configurations from the experiment definition. """ # expected outputs - results_path = os.path.join(tmp_path, "results", "temp") alphas = [0.05, 0.01] taus = [10.0, 20.0, 5.0] partial_configs = ( @@ -76,16 +79,13 @@ def test_read_database(tmp_path): ) # write experiment definition to table - write_database(results_path, alphas, taus) + write_database(tmp_path, alphas, taus) # make Experiment object (versions start at 0) softmaxAC_mc = ExperimentDefinition( - part_name="softmaxAC", version=0 + part_name="softmaxAC", version=0, base=str(tmp_path) ) - # overwrite the results path to be in the temp directory - softmaxAC_mc.get_results_path = lambda *args, **kwargs: results_path - # get the configuration ids num_configs = len(alphas) * len(taus) config_ids = list(range(num_configs)) @@ -102,6 +102,7 @@ def test_run_tasks(tmp_path): taus = [10.0, 20.0, 5.0] seed_num = 10 version_num = 0 + exp_name = "acceptance" # expected outputs partial_configs = ( @@ -120,9 +121,14 @@ def test_run_tasks(tmp_path): ) expected_configs = {i : config for i, config in enumerate(partial_configs)} + # set experiment file name + experiment_file_name = f"tests/{exp_name}/my_experiment.py" + + # set results path + results_path = os.path.join(tmp_path, "results", f"{exp_name}") + # write experiment definition to table - results_path = os.path.join(tmp_path, "results", "temp") - db = write_database(results_path, alphas, taus) + db = write_database(tmp_path, alphas, taus) assert db.name == "softmaxAC" assert os.path.exists(os.path.join(results_path, "metadata.db")) @@ -138,12 +144,9 @@ def test_run_tasks(tmp_path): # initialize run config run_conf = LocalRunConfig(tasks_in_parallel=ntasks, log_path=".logs/") - # set up experiment file - experiment_file_name = "tests/acceptance/my_experiment.py" - # set up scheduler sched = StubScheduler( - exp_name="temp", + exp_name=exp_name, entry=experiment_file_name, seeds=[seed_num], version=version_num, From ccc2acf9c7676befa9bdda293d731f050263d2bb Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 31 Oct 2024 14:14:36 -0600 Subject: [PATCH 08/10] build: remove tests for python 3.10 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 764bd9f..81cf933 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ["3.10", "3.11", "3.12"] + python-version: ["3.11", "3.12"] steps: # setup the repository From 7f4386e75ea5434c660b0e8a93917bbe661e565e Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 31 Oct 2024 14:15:27 -0600 Subject: [PATCH 09/10] build: add package install before running pytest --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 81cf933..4750389 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,7 @@ jobs: pip install uv uv pip compile --extra=dev pyproject.toml -o requirements.txt uv pip sync requirements.txt + uv pip install '.[dev]' - run: echo "$PWD/.venv/bin" >> $GITHUB_PATH From 9d0c5163ed07c316507e438959f4e93d2f0a7d04 Mon Sep 17 00:00:00 2001 From: Niko Yasui Date: Thu, 31 Oct 2024 15:54:49 -0600 Subject: [PATCH 10/10] build: remove python 3.10 from pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 56c22e7..d2c6248 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ authors = [ {name = "Andy Patterson", email = "ap3@ualberta.ca"}, ] dependencies = [] -requires-python = ">=3.10,<3.13" +requires-python = ">=3.11,<3.13" readme = "README.md" license = {text = "MIT"}