From ee47c2992a1114fe1655499b7152c6e3314d70bd Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Wed, 25 Oct 2023 16:52:36 -0700 Subject: [PATCH 01/18] Updated the config files with OCPS:2 to make the string 'replace_me' instead. --- .../configs/enabled_offline_state_transition_configs.py | 2 +- .../configs/obssys_state_transition_configs.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/configs/enabled_offline_state_transition_configs.py b/python/lsst/ts/IntegrationTests/configs/enabled_offline_state_transition_configs.py index 77a741d5..f2e65468 100644 --- a/python/lsst/ts/IntegrationTests/configs/enabled_offline_state_transition_configs.py +++ b/python/lsst/ts/IntegrationTests/configs/enabled_offline_state_transition_configs.py @@ -46,7 +46,7 @@ - [Scheduler:1, OFFLINE] - [Scheduler:2, OFFLINE] - [OCPS:1, OFFLINE] - - [OCPS:2, OFFLINE] + - [replace_me, OFFLINE] """ ) diff --git a/python/lsst/ts/IntegrationTests/configs/obssys_state_transition_configs.py b/python/lsst/ts/IntegrationTests/configs/obssys_state_transition_configs.py index b58ade99..cc88aa74 100644 --- a/python/lsst/ts/IntegrationTests/configs/obssys_state_transition_configs.py +++ b/python/lsst/ts/IntegrationTests/configs/obssys_state_transition_configs.py @@ -34,7 +34,7 @@ - [Scheduler:1, DISABLED] - [Scheduler:2, DISABLED] - [OCPS:1, DISABLED] - - [OCPS:2, DISABLED] + - [replace_me, DISABLED] - [Watcher, DISABLED] """ ) @@ -50,7 +50,7 @@ - [Scheduler:1, ENABLED] - [Scheduler:2, ENABLED] - [OCPS:1, ENABLED] - - [OCPS:2, ENABLED] + - [replace_me, ENABLED] - [Watcher, ENABLED] """ ) From ebb593a7aa8af2d05252adc8c683f918ee454965 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Wed, 25 Oct 2023 16:53:29 -0700 Subject: [PATCH 02/18] Updated obssys_disabled_enabled.py to define with OCPS index to use based on the test environment. --- .../obssys_disabled_enabled.py | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py b/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py index db17279c..3752ca3e 100644 --- a/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py +++ b/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py @@ -22,8 +22,10 @@ __all__ = ["ObsSysDisabledEnabled", "run_obssys_disabled_enabled"] +import argparse import asyncio +import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry @@ -42,12 +44,56 @@ class ObsSysDisabledEnabled(BaseScript): ("set_summary_state.py", BaseScript.is_standard), ] - def __init__(self) -> None: + def __init__(self, test_env: str) -> None: super().__init__() + # Set the OCPS index based on test environment + self.test_env = test_env + self.env_configs = yaml.safe_load(registry["obssys_disabled_enabled"]) + if test_env.lower() == "bts": + # Running on BTS with OCPS:3 + self.ocps = "OCPS:3" + else: + # Running on TTS or Summit with OCPS:2 + self.ocps = "OCPS:2" + self.env_configs["data"][3][0] = self.ocps + self.configs = (yaml.safe_dump(self.env_configs),) def run_obssys_disabled_enabled() -> None: - script_class = ObsSysDisabledEnabled() - num_scripts = len(script_class.scripts) - print(f"\nObsSys Disabled to Enabled; running {num_scripts} scripts") - asyncio.run(script_class.run()) + # Define the script arguments. + parser = argparse.ArgumentParser() + parser.add_argument( + "test_env", + nargs="?", + type=str.lower, + choices=["bts", "tts", "summit"], + help="Specify on which environment the tests are running (case insensitive).", + ) + args = parser.parse_args() + # Print the help if the environment is not defined. + if not (args.test_env): + parser.print_help() + exit() + main(args) + + +def main(opts: argparse.Namespace) -> None: + # Ensure the invocation is correct. + # If not, raise KeyError. + # If it is correct, execute the state transition. + try: + script_class = ObsSysDisabledEnabled( + test_env=opts.test_env, + ) + except KeyError as ke: + print(repr(ke)) + else: + num_scripts = len(script_class.scripts) + print( + f"\nObsSys Disabled to Enabled; " + f"running {num_scripts} scripts " + f"on the '{opts.test_env}' environment, " + f"with this configuration: \n" + f"{script_class.configs}" + ) + asyncio.run(script_class.run()) From af035b043691c70fb4d4bfd251d529605750a18b Mon Sep 17 00:00:00 2001 From: rbovill Date: Thu, 26 Oct 2023 13:43:54 -0700 Subject: [PATCH 03/18] Updated .gitignore with new pre-commit items. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5130d2c7..be7d7ff5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ ospl*log .flake8 .isort.cfg .mypy.ini +.clang-format +.ruff.toml +towncrier.toml From de8de2a647942ae52e000bdb080aaf6dd24c77f9 Mon Sep 17 00:00:00 2001 From: rbovill Date: Thu, 26 Oct 2023 13:47:04 -0700 Subject: [PATCH 04/18] Updated obssys_standby_disabled.py to define with OCPS index to use based on the test environment. --- .../obssys_standby_disabled.py | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py b/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py index 9f2a65cb..dad0d456 100644 --- a/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py +++ b/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py @@ -22,8 +22,10 @@ __all__ = ["ObsSysStandbyDisabled", "run_obssys_standby_disabled"] +import argparse import asyncio +import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry @@ -42,12 +44,56 @@ class ObsSysStandbyDisabled(BaseScript): ("set_summary_state.py", BaseScript.is_standard), ] - def __init__(self) -> None: + def __init__(self, test_env: str) -> None: super().__init__() + # Set the OCPS index based on test environment + self.test_env = test_env + self.env_configs = yaml.safe_load(registry["obssys_standby_disabled"]) + if test_env.lower() == "bts": + # Running on BTS with OCPS:3 + self.ocps = "OCPS:3" + else: + # Running on TTS or Summit with OCPS:2 + self.ocps = "OCPS:2" + self.env_configs["data"][3][0] = self.ocps + self.configs = (yaml.safe_dump(self.env_configs),) def run_obssys_standby_disabled() -> None: - script_class = ObsSysStandbyDisabled() - num_scripts = len(script_class.scripts) - print(f"\nObsSys Standby to Disabled; running {num_scripts} scripts") - asyncio.run(script_class.run()) + # Define the script arguments. + parser = argparse.ArgumentParser() + parser.add_argument( + "test_env", + nargs="?", + type=str.lower, + choices=["bts", "tts", "summit"], + help="Specify on which environment the tests are running (case insensitive).", + ) + args = parser.parse_args() + # Print the help if the environment is not defined. + if not (args.test_env): + parser.print_help() + exit() + main(args) + + +def main(opts: argparse.Namespace) -> None: + # Ensure the invocation is correct. + # If not, raise KeyError. + # If it is correct, execute the state transition. + try: + script_class = ObsSysStandbyDisabled( + test_env=opts.test_env, + ) + except KeyError as ke: + print(repr(ke)) + else: + num_scripts = len(script_class.scripts) + print( + f"\nObsSys Standby to Disabled; " + f"running {num_scripts} scripts " + f"on the '{opts.test_env}' environment. " + f"with this configuration: \n" + f"{script_class.configs}" + ) + asyncio.run(script_class.run()) From 1053f4f04fdb33e082ebe9670d238e4210f33291 Mon Sep 17 00:00:00 2001 From: rbovill Date: Thu, 26 Oct 2023 13:47:32 -0700 Subject: [PATCH 05/18] Updated enabled_offline.pyto define with OCPS index to use based on the test environment. --- .../ts/IntegrationTests/enabled_offline.py | 64 +++++++++++++++++-- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/enabled_offline.py b/python/lsst/ts/IntegrationTests/enabled_offline.py index fbda88fa..1dff01a0 100644 --- a/python/lsst/ts/IntegrationTests/enabled_offline.py +++ b/python/lsst/ts/IntegrationTests/enabled_offline.py @@ -22,8 +22,10 @@ __all__ = ["EnabledOffline", "run_enabled_offline"] +import argparse import asyncio +import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry @@ -63,12 +65,64 @@ class EnabledOffline(BaseScript): ("set_summary_state.py", BaseScript.is_standard), ] - def __init__(self) -> None: + def __init__(self, test_env: str) -> None: super().__init__() + # Set the OCPS index based on test environment + self.test_env = test_env + self.env_configs = yaml.safe_load(self.configs[1]) + if test_env.lower() == "bts": + # Running on BTS with OCPS:3 + self.ocps = "OCPS:3" + else: + # Running on TTS or Summit with OCPS:2 + self.ocps = "OCPS:2" + self.env_configs["data"][3][0] = self.ocps + # Update the self.configs tuple with the updated + # registry["sched_ocps_enabled_offline"] configuration. + # Do this by converting the tuple to a list, replacing the + # updated entry and converting it back to a tuple. + temp_list = list(self.configs) + temp_list[1] = yaml.safe_dump( + self.env_configs, explicit_start=True, canonical=True + ) + self.configs = tuple(temp_list) def run_enabled_offline() -> None: - script_class = EnabledOffline() - num_scripts = len(script_class.scripts) - print(f"\nEnabled to Offline; running {num_scripts} scripts") - asyncio.run(script_class.run()) + # Define the script arguments. + parser = argparse.ArgumentParser() + parser.add_argument( + "test_env", + nargs="?", + type=str.lower, + choices=["bts", "tts", "summit"], + help="Specify on which environment the tests are running (case insensitive).", + ) + args = parser.parse_args() + # Print the help if the environment is not defined. + if not (args.test_env): + parser.print_help() + exit() + main(args) + + +def main(opts: argparse.Namespace) -> None: + # Ensure the invocation is correct. + # If not, raise KeyError. + # If it is correct, execute the state transition. + try: + script_class = EnabledOffline( + test_env=opts.test_env, + ) + except KeyError as ke: + print(repr(ke)) + else: + num_scripts = len(script_class.scripts) + print( + f"\nEnabled to Offline; " + f"running {num_scripts} scripts " + f"on the '{opts.test_env}' environment. " + f"with this configuration: \n" + f"{script_class.configs}" + ) + asyncio.run(script_class.run()) From 685f773cbd4926e1f014573dd3d49675fc46c2c3 Mon Sep 17 00:00:00 2001 From: rbovill Date: Thu, 26 Oct 2023 15:40:04 -0700 Subject: [PATCH 06/18] Mocking the command-line argument. --- tests/test_obssys_state_transitions.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/test_obssys_state_transitions.py b/tests/test_obssys_state_transitions.py index ba9f9a16..2f544e50 100644 --- a/tests/test_obssys_state_transitions.py +++ b/tests/test_obssys_state_transitions.py @@ -21,6 +21,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import sys import unittest from lsst.ts import salobj @@ -51,9 +52,13 @@ async def test_obssys_standby_disabled(self) -> None: module. """ + # Mock the command-line arguments that the obssys_standby_disabled.py + # script expects. + test_env = "tts" + sys.argv[1:] = [test_env] # Instantiate the ObsSysStandbyDisabled integration tests. - script_class = ObsSysStandbyDisabled() - # Get number of scripts + script_class = ObsSysStandbyDisabled(test_env=test_env) + # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) print(f"ObsSys Standby to Disabled; running {num_scripts} scripts") # Execute the scripts. @@ -70,9 +75,13 @@ async def test_obssys_disabled_enabled(self) -> None: module. """ + # Mock the command-line arguments that the obssys_disabled_enabled.py + # script expects. + test_env = "bts" + sys.argv[1:] = [test_env] # Instantiate the ObsSysDisabledEnabled integration tests. - script_class = ObsSysDisabledEnabled() - # Get number of scripts + script_class = ObsSysDisabledEnabled(test_env=test_env) + # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) print(f"ObsSys Disabled to Enabled; running {num_scripts} scripts") # Execute the scripts. From ec068ac1de8c60d7eba8826be4f1560270b99292 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Mon, 30 Oct 2023 10:11:09 -0700 Subject: [PATCH 07/18] Updated unit tests to verify OCPS index based on test environment. --- tests/test_enabled_offline.py | 2 +- tests/test_obssys_state_transitions.py | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/test_enabled_offline.py b/tests/test_enabled_offline.py index fe3ebba5..6f1f1f12 100644 --- a/tests/test_enabled_offline.py +++ b/tests/test_enabled_offline.py @@ -50,7 +50,7 @@ async def test_enabled_offline(self) -> None: """ # Instantiate the EnabledOffline integration tests. - script_class = EnabledOffline() + script_class = EnabledOffline(test_env="bts") # Get number of scripts num_scripts = len(script_class.scripts) print(f"Enabled to Offline; running {num_scripts} scripts") diff --git a/tests/test_obssys_state_transitions.py b/tests/test_obssys_state_transitions.py index 2f544e50..51217261 100644 --- a/tests/test_obssys_state_transitions.py +++ b/tests/test_obssys_state_transitions.py @@ -21,9 +21,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import unittest +import yaml from lsst.ts import salobj from lsst.ts.IntegrationTests import ( ObsSysDisabledEnabled, @@ -50,16 +50,13 @@ async def test_obssys_standby_disabled(self) -> None: which runs the ts_standardscripts/set_summary_state.py script. Use the configuration stored in the obssys_state_transition_configs.py module. - """ - # Mock the command-line arguments that the obssys_standby_disabled.py - # script expects. - test_env = "tts" - sys.argv[1:] = [test_env] + # Instantiate the ObsSysStandbyDisabled integration tests. - script_class = ObsSysStandbyDisabled(test_env=test_env) + script_class = ObsSysStandbyDisabled(test_env="tts") # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) + script_config = yaml.safe_load(script_class.configs[0]) print(f"ObsSys Standby to Disabled; running {num_scripts} scripts") # Execute the scripts. await script_class.run() @@ -67,22 +64,21 @@ async def test_obssys_standby_disabled(self) -> None: self.assertEqual(len(self.controller.queue_list), num_scripts) # Assert scripts passed. self.assertEqual(script_class.script_states, [8]) + # Assert OCPS index was set correctly. + self.assertEqual(script_config["data"][3][0], "OCPS:2") async def test_obssys_disabled_enabled(self) -> None: """Execute the ObsSysDisabledEnabled integration test script, which runs the ts_standardscripts/set_summary_state.py script. Use the configuration stored in the obssys_state_transition_configs.py module. - """ - # Mock the command-line arguments that the obssys_disabled_enabled.py - # script expects. - test_env = "bts" - sys.argv[1:] = [test_env] + # Instantiate the ObsSysDisabledEnabled integration tests. - script_class = ObsSysDisabledEnabled(test_env=test_env) + script_class = ObsSysDisabledEnabled(test_env="bts") # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) + script_config = yaml.safe_load(script_class.configs[0]) print(f"ObsSys Disabled to Enabled; running {num_scripts} scripts") # Execute the scripts. await script_class.run() @@ -90,6 +86,8 @@ async def test_obssys_disabled_enabled(self) -> None: self.assertEqual(len(self.controller.queue_list), num_scripts) # Assert scripts passed. self.assertEqual(script_class.script_states, [8]) + # Assert OCPS index was set correctly. + self.assertEqual(script_config["data"][3][0], "OCPS:3") async def asyncTearDown(self) -> None: await self.controller.close() From 62a51ccfa5dfa846aad276a401c6e491ec744c08 Mon Sep 17 00:00:00 2001 From: rbovill Date: Fri, 27 Oct 2023 10:42:53 -0700 Subject: [PATCH 08/18] Removed unnecessary use of sys.argv from test_load_camera_playlist.py. --- tests/test_load_camera_playlist.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_load_camera_playlist.py b/tests/test_load_camera_playlist.py index af774d9c..bfd14b9f 100644 --- a/tests/test_load_camera_playlist.py +++ b/tests/test_load_camera_playlist.py @@ -22,7 +22,6 @@ # along with this program. If not, see . import subprocess -import sys import unittest from lsst.ts import salobj @@ -55,7 +54,6 @@ async def test_camera_playlist(self) -> None: # script expects. test_camera = "at" test_playlist = "test" - sys.argv[1:] = [test_camera, test_playlist] # Instantiate the LoadCameraPlaylist integration tests. script_class = LoadCameraPlaylist( camera=test_camera, playlist_shortname=test_playlist From dc6827bc5b7ac0798128fd3341ac5944f4f43f76 Mon Sep 17 00:00:00 2001 From: rbovill Date: Fri, 27 Oct 2023 10:36:06 -0700 Subject: [PATCH 09/18] Updated version-history. --- doc/version-history.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/version-history.rst b/doc/version-history.rst index 0979b87f..74a75238 100644 --- a/doc/version-history.rst +++ b/doc/version-history.rst @@ -10,6 +10,10 @@ Version History .. No new work should be required in order to complete this section. .. Below is an example of a version history format. +v0.17.0 +------- +* Parameterized the OCSP 2||3 index, determined by test environment. + v0.16.0 ------- * Added Watcher to the ObsSys State transition tests. From 2dba287d57cf6dfd3cfb813d503c2d7ca1f78905 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Mon, 30 Oct 2023 11:51:03 -0700 Subject: [PATCH 10/18] Moved the test_env argument definition to a function in the new utils.py module. --- python/lsst/ts/IntegrationTests/__init__.py | 1 + .../obssys_disabled_enabled.py | 25 ++--------- .../obssys_standby_disabled.py | 25 ++--------- python/lsst/ts/IntegrationTests/utils.py | 41 +++++++++++++++++++ 4 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 python/lsst/ts/IntegrationTests/utils.py diff --git a/python/lsst/ts/IntegrationTests/__init__.py b/python/lsst/ts/IntegrationTests/__init__.py index 15530f68..99339e1a 100644 --- a/python/lsst/ts/IntegrationTests/__init__.py +++ b/python/lsst/ts/IntegrationTests/__init__.py @@ -64,4 +64,5 @@ from .obssys_standby_disabled import * from .script_queue_controller import * from .testutils import * +from .utils import * from .yaml_test_strings import * diff --git a/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py b/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py index 3752ca3e..d7212ae2 100644 --- a/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py +++ b/python/lsst/ts/IntegrationTests/obssys_disabled_enabled.py @@ -22,13 +22,13 @@ __all__ = ["ObsSysDisabledEnabled", "run_obssys_disabled_enabled"] -import argparse import asyncio import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry +from .utils import get_test_env_arg class ObsSysDisabledEnabled(BaseScript): @@ -60,30 +60,13 @@ def __init__(self, test_env: str) -> None: def run_obssys_disabled_enabled() -> None: - # Define the script arguments. - parser = argparse.ArgumentParser() - parser.add_argument( - "test_env", - nargs="?", - type=str.lower, - choices=["bts", "tts", "summit"], - help="Specify on which environment the tests are running (case insensitive).", - ) - args = parser.parse_args() - # Print the help if the environment is not defined. - if not (args.test_env): - parser.print_help() - exit() - main(args) - - -def main(opts: argparse.Namespace) -> None: # Ensure the invocation is correct. # If not, raise KeyError. # If it is correct, execute the state transition. + args = get_test_env_arg() try: script_class = ObsSysDisabledEnabled( - test_env=opts.test_env, + test_env=args.test_env, ) except KeyError as ke: print(repr(ke)) @@ -92,7 +75,7 @@ def main(opts: argparse.Namespace) -> None: print( f"\nObsSys Disabled to Enabled; " f"running {num_scripts} scripts " - f"on the '{opts.test_env}' environment, " + f"on the '{args.test_env}' environment, " f"with this configuration: \n" f"{script_class.configs}" ) diff --git a/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py b/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py index dad0d456..fae1e077 100644 --- a/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py +++ b/python/lsst/ts/IntegrationTests/obssys_standby_disabled.py @@ -22,13 +22,13 @@ __all__ = ["ObsSysStandbyDisabled", "run_obssys_standby_disabled"] -import argparse import asyncio import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry +from .utils import get_test_env_arg class ObsSysStandbyDisabled(BaseScript): @@ -60,30 +60,13 @@ def __init__(self, test_env: str) -> None: def run_obssys_standby_disabled() -> None: - # Define the script arguments. - parser = argparse.ArgumentParser() - parser.add_argument( - "test_env", - nargs="?", - type=str.lower, - choices=["bts", "tts", "summit"], - help="Specify on which environment the tests are running (case insensitive).", - ) - args = parser.parse_args() - # Print the help if the environment is not defined. - if not (args.test_env): - parser.print_help() - exit() - main(args) - - -def main(opts: argparse.Namespace) -> None: # Ensure the invocation is correct. # If not, raise KeyError. # If it is correct, execute the state transition. + args = get_test_env_arg() try: script_class = ObsSysStandbyDisabled( - test_env=opts.test_env, + test_env=args.test_env, ) except KeyError as ke: print(repr(ke)) @@ -92,7 +75,7 @@ def main(opts: argparse.Namespace) -> None: print( f"\nObsSys Standby to Disabled; " f"running {num_scripts} scripts " - f"on the '{opts.test_env}' environment. " + f"on the '{args.test_env}' environment. " f"with this configuration: \n" f"{script_class.configs}" ) diff --git a/python/lsst/ts/IntegrationTests/utils.py b/python/lsst/ts/IntegrationTests/utils.py new file mode 100644 index 00000000..5f84e6cd --- /dev/null +++ b/python/lsst/ts/IntegrationTests/utils.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This file is part of ts_IntegrationTests. +# +# Developed for the Vera C. Rubin Observatory Telescope & Site Software system. +# This product includes software developed by the Vera C. Rubin Observatory +# Project (https://www.lsst.org). +# See the COPYRIGHT file at the top-level directory of this distribution +# for details of code ownership. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License + +import argparse + + +def get_test_env_arg() -> None: + # Define the script arguments. + parser = argparse.ArgumentParser() + parser.add_argument( + "test_env", + nargs="?", + type=str.lower, + choices=["bts", "tts", "summit"], + help="Specify on which environment the tests are running (case insensitive).", + ) + args = parser.parse_args() + # Print the help if the environment is not defined. + if not (args.test_env): + parser.print_help() + exit() + return args From fe19a48f3c70486d952cc29a2de51841e37b4304 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Mon, 30 Oct 2023 11:59:24 -0700 Subject: [PATCH 11/18] Added more verbose logging to the tests/test_obssys_state_transitions.py unit tests. --- tests/test_obssys_state_transitions.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_obssys_state_transitions.py b/tests/test_obssys_state_transitions.py index 51217261..d789049a 100644 --- a/tests/test_obssys_state_transitions.py +++ b/tests/test_obssys_state_transitions.py @@ -57,7 +57,11 @@ async def test_obssys_standby_disabled(self) -> None: # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) script_config = yaml.safe_load(script_class.configs[0]) - print(f"ObsSys Standby to Disabled; running {num_scripts} scripts") + print( + f"ObsSys Standby to Disabled; running {num_scripts} scripts" + f" on the TTS environment, with this configuration: \n" + f"{script_config}" + ) # Execute the scripts. await script_class.run() # Assert script was added to ScriptQueue. @@ -79,7 +83,11 @@ async def test_obssys_disabled_enabled(self) -> None: # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) script_config = yaml.safe_load(script_class.configs[0]) - print(f"ObsSys Disabled to Enabled; running {num_scripts} scripts") + print( + f"ObsSys Disabled to Enabled; running {num_scripts} scripts" + f" on the BTS environment, with this configuration: \n" + f"{script_config}" + ) # Execute the scripts. await script_class.run() # Assert script was added to ScriptQueue. From 1aa2095fa1cb213ffec2be7a361fb922f0eebcef Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Tue, 31 Oct 2023 12:34:52 -0700 Subject: [PATCH 12/18] Updated love_stress_test.py and love_stress_test_configs.py to define the LOVE 'location' URL based on the test environment. --- .../configs/love_stress_test_configs.py | 2 +- .../ts/IntegrationTests/love_stress_test.py | 37 ++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/configs/love_stress_test_configs.py b/python/lsst/ts/IntegrationTests/configs/love_stress_test_configs.py index 1a593432..0d333c6b 100644 --- a/python/lsst/ts/IntegrationTests/configs/love_stress_test_configs.py +++ b/python/lsst/ts/IntegrationTests/configs/love_stress_test_configs.py @@ -30,7 +30,7 @@ registry["love_stress"] = yaml.safe_dump( { - "location": "love1.tu.lsst.org", + "location": "replace_me", "number_of_clients": 50, "number_of_messages": 5000, "data": [ diff --git a/python/lsst/ts/IntegrationTests/love_stress_test.py b/python/lsst/ts/IntegrationTests/love_stress_test.py index bab417d9..5d5fd9d5 100644 --- a/python/lsst/ts/IntegrationTests/love_stress_test.py +++ b/python/lsst/ts/IntegrationTests/love_stress_test.py @@ -24,9 +24,11 @@ import asyncio +import yaml from lsst.ts.IntegrationTests import BaseScript from .configs.config_registry import registry +from .utils import get_test_env_arg class LoveStressTest(BaseScript): @@ -42,12 +44,37 @@ class LoveStressTest(BaseScript): ("make_love_stress_tests.py", BaseScript.is_external), ] - def __init__(self) -> None: + def __init__(self, test_env: str) -> None: super().__init__() + # Set the LOVE location based on test environment + self.test_env = test_env + self.env_configs = yaml.safe_load(registry["love_stress"]) + if test_env.lower() == "bts": + # Running on BTS + self.location = "love01.ls.lsst.org" + elif test_env.lower() == "tts": + # Running on TTS + self.location = "love1.tu.lsst.org" + self.env_configs["location"] = self.location + self.configs = (yaml.safe_dump(self.env_configs),) def run_love_stress_test() -> None: - script_class = LoveStressTest() - num_scripts = len(script_class.scripts) - print(f"\nLOVE Stress Test; running {num_scripts} scripts") - asyncio.run(script_class.run()) + # Ensure the invocation is correct. + # If not, raise KeyError. + # If it is correct, execute the Stress Test. + args = get_test_env_arg() + try: + script_class = LoveStressTest( + test_env=args.test_env, + ) + except KeyError as ke: + print(repr(ke)) + else: + num_scripts = len(script_class.scripts) + print( + f"\nLOVE Stress Test; running {num_scripts} scripts" + f" with this configuration:\n" + f"{script_class.configs}" + ) + asyncio.run(script_class.run()) From 2d169d3bb6c6b33b69d751a696dd3e2d22e730b3 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Tue, 31 Oct 2023 12:35:28 -0700 Subject: [PATCH 13/18] Updated test_love_stress.py unit test with new 'location' defintion. --- .../lsst/ts/IntegrationTests/love_stress_test.py | 13 ++++++++++--- tests/test_love_stress.py | 14 +++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/love_stress_test.py b/python/lsst/ts/IntegrationTests/love_stress_test.py index 5d5fd9d5..2276b5d7 100644 --- a/python/lsst/ts/IntegrationTests/love_stress_test.py +++ b/python/lsst/ts/IntegrationTests/love_stress_test.py @@ -49,12 +49,19 @@ def __init__(self, test_env: str) -> None: # Set the LOVE location based on test environment self.test_env = test_env self.env_configs = yaml.safe_load(registry["love_stress"]) - if test_env.lower() == "bts": - # Running on BTS - self.location = "love01.ls.lsst.org" + if test_env.lower() == "summit": + # Running on Summit + self.location = "love01.cp.lsst.org" elif test_env.lower() == "tts": # Running on TTS self.location = "love1.tu.lsst.org" + elif test_env.lower() == "bts": + # Running on BTS + self.location = "love01.ls.lsst.org" + else: + raise Exception( + "Please choose one of the proper locations: ['bts', 'tts', 'summit']" + ) self.env_configs["location"] = self.location self.configs = (yaml.safe_dump(self.env_configs),) diff --git a/tests/test_love_stress.py b/tests/test_love_stress.py index b489c09f..dab521b9 100644 --- a/tests/test_love_stress.py +++ b/tests/test_love_stress.py @@ -23,6 +23,7 @@ import unittest +import yaml from lsst.ts import salobj from lsst.ts.IntegrationTests import LoveStressTest, ScriptQueueController @@ -47,16 +48,23 @@ async def test_love_stress(self) -> None: """ # Instantiate the LoveStress integration tests. - script_class = LoveStressTest() - # Get number of scripts + script_class = LoveStressTest(test_env="bts") + # Get number of scripts and the configuration. num_scripts = len(script_class.scripts) - print(f"LOVE Stress Test; running {num_scripts} scripts") + script_config = yaml.safe_load(script_class.configs[0]) + print( + f"LOVE Stress Test; running {num_scripts} scripts" + f" on the BTS environment, with this configuration: \n" + f"{script_config}" + ) # Execute the scripts. await script_class.run() # Assert script was added to ScriptQueue. self.assertEqual(len(self.controller.queue_list), num_scripts) # Assert scripts passed. self.assertEqual(script_class.script_states, [8]) + # Assert location is correct. + self.assertEqual(script_config["location"], "love01.ls.lsst.org") async def asyncTearDown(self) -> None: await self.controller.close() From 32daa3aba63ffa1dd7cb27948b4dbd3002e4d8f5 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Tue, 31 Oct 2023 12:52:33 -0700 Subject: [PATCH 14/18] Updated version-history. --- doc/version-history.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/version-history.rst b/doc/version-history.rst index 74a75238..6d0e412b 100644 --- a/doc/version-history.rst +++ b/doc/version-history.rst @@ -13,6 +13,7 @@ Version History v0.17.0 ------- * Parameterized the OCSP 2||3 index, determined by test environment. +* Updated love_stress_test to define the LOVE 'location' URL based on the test environment. v0.16.0 ------- From 866ccaceca8b6bd1da51facb11c8d9aa9f6a43e9 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Thu, 2 Nov 2023 17:06:41 -0700 Subject: [PATCH 15/18] Added the 'k8s' boolean argument to utils.py. --- python/lsst/ts/IntegrationTests/utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/lsst/ts/IntegrationTests/utils.py b/python/lsst/ts/IntegrationTests/utils.py index 5f84e6cd..35bbff4a 100644 --- a/python/lsst/ts/IntegrationTests/utils.py +++ b/python/lsst/ts/IntegrationTests/utils.py @@ -33,6 +33,12 @@ def get_test_env_arg() -> None: choices=["bts", "tts", "summit"], help="Specify on which environment the tests are running (case insensitive).", ) + parser.add_argument( + "--k8s", + default=False, + action="store_true", + help="Specify if the tests are running against the kubernetes instance.", + ) args = parser.parse_args() # Print the help if the environment is not defined. if not (args.test_env): From b0d288c288dbf459d69f22f97a2a9bbcd7ecb61d Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Thu, 2 Nov 2023 17:07:20 -0700 Subject: [PATCH 16/18] Added handling of the 'location' value if the script is running against the kubernetes LOVE instance or not. --- .../ts/IntegrationTests/love_stress_test.py | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/python/lsst/ts/IntegrationTests/love_stress_test.py b/python/lsst/ts/IntegrationTests/love_stress_test.py index 2276b5d7..f3e13d2d 100644 --- a/python/lsst/ts/IntegrationTests/love_stress_test.py +++ b/python/lsst/ts/IntegrationTests/love_stress_test.py @@ -36,6 +36,14 @@ class LoveStressTest(BaseScript): with the given Yaml configuration, placed in the given ScriptQueue location. + Attributes + ---------- + test_env : `str` + Defines which test environment the script is running. + Choices are ['bts', 'tts', 'summit']. + k8s : `bool` + Indicates if the script should run against the kubernetes + instance. Default is False. """ index: int = 1 @@ -44,20 +52,30 @@ class LoveStressTest(BaseScript): ("make_love_stress_tests.py", BaseScript.is_external), ] - def __init__(self, test_env: str) -> None: + def __init__(self, test_env: str, k8s: bool = False) -> None: super().__init__() # Set the LOVE location based on test environment self.test_env = test_env + self.k8s = k8s self.env_configs = yaml.safe_load(registry["love_stress"]) if test_env.lower() == "summit": # Running on Summit - self.location = "love01.cp.lsst.org" + if self.k8s: + self.location = "https://summit-lsp.lsst.codes/love" + else: + self.location = "http://love01.cp.lsst.org" elif test_env.lower() == "tts": # Running on TTS - self.location = "love1.tu.lsst.org" + if self.k8s: + self.location = "https://tucson-teststand.lsst.codes/love" + else: + self.location = "http://love1.tu.lsst.org" elif test_env.lower() == "bts": # Running on BTS - self.location = "love01.ls.lsst.org" + if self.k8s: + self.location = "https://base-lsp.lsst.codes/love" + else: + self.location = "http://love01.ls.lsst.org" else: raise Exception( "Please choose one of the proper locations: ['bts', 'tts', 'summit']" @@ -74,6 +92,7 @@ def run_love_stress_test() -> None: try: script_class = LoveStressTest( test_env=args.test_env, + k8s=args.k8s, ) except KeyError as ke: print(repr(ke)) From 150bdd4bb3b71f877a837a7c837d560774a563e8 Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Fri, 3 Nov 2023 10:16:18 -0700 Subject: [PATCH 17/18] Added a unit test test_love_stress.py for the kubernetes location. --- tests/test_love_stress.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/test_love_stress.py b/tests/test_love_stress.py index dab521b9..101ff5e6 100644 --- a/tests/test_love_stress.py +++ b/tests/test_love_stress.py @@ -64,7 +64,33 @@ async def test_love_stress(self) -> None: # Assert scripts passed. self.assertEqual(script_class.script_states, [8]) # Assert location is correct. - self.assertEqual(script_config["location"], "love01.ls.lsst.org") + self.assertEqual(script_config["location"], "http://love01.ls.lsst.org") + + async def test_love_stress_on_k8s(self) -> None: + """Execute the LoveStress integration test script on the kubernetes + LOVE instance, which runs the + ts_externalscripts/make_love_stress_tests.py script. + Use the configuration stored in the love_stress_configs.py module. + + """ + # Instantiate the LoveStress integration tests. + script_class = LoveStressTest(test_env="bts", k8s="--k8s") + # Get number of scripts and the configuration. + num_scripts = len(script_class.scripts) + script_config = yaml.safe_load(script_class.configs[0]) + print( + f"LOVE Stress Test; running {num_scripts} scripts" + f" on the BTS environment, with this configuration: \n" + f"{script_config}" + ) + # Execute the scripts. + await script_class.run() + # Assert script was added to ScriptQueue. + self.assertEqual(len(self.controller.queue_list), num_scripts) + # Assert scripts passed. + self.assertEqual(script_class.script_states, [8]) + # Assert location is correct. + self.assertEqual(script_config["location"], "https://base-lsp.lsst.codes/love") async def asyncTearDown(self) -> None: await self.controller.close() From b23fcdc60961d5e8aec63f18f73d1ef0f3c8211d Mon Sep 17 00:00:00 2001 From: Rob Bovill Date: Fri, 3 Nov 2023 10:17:31 -0700 Subject: [PATCH 18/18] Updated version-history. --- doc/version-history.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/version-history.rst b/doc/version-history.rst index 6d0e412b..0bba034c 100644 --- a/doc/version-history.rst +++ b/doc/version-history.rst @@ -14,6 +14,7 @@ v0.17.0 ------- * Parameterized the OCSP 2||3 index, determined by test environment. * Updated love_stress_test to define the LOVE 'location' URL based on the test environment. +* Added LOVE kubernetes instance testing. v0.16.0 -------