From 69fe365c81b36dabd8d826bfecb23743298bfdff Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:00:37 +0530 Subject: [PATCH 01/10] Add logs and --log-file option in parse_args --- ceph_devstack/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ceph_devstack/__init__.py b/ceph_devstack/__init__.py index fc0cc8d9..4a3ed162 100644 --- a/ceph_devstack/__init__.py +++ b/ceph_devstack/__init__.py @@ -104,6 +104,15 @@ def parse_args(args: List[str]) -> argparse.Namespace: "container", help="The container to wait for", ) + parser_logs=subparsers.add_parser( + "logs", help="Display teuthology.log logs of the latest run" + ) + parser_logs.add_argument( + "--log-file", + action="store_true", + default=False, + help="Display teuthology.log file path of the latest run with flag set" + ) return parser.parse_args(args) From 2a2b473fb1083845537f2c7d24c1c394ad73879c Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:01:21 +0530 Subject: [PATCH 02/10] Add implementation of logs and --logs-file option - ``ceph-devstack logs `` displays latest run teuthology logs of given job - ``ceph-devstack logs --log-file `` displace file location of latest run teuthology log of given job --- ceph_devstack/cli.py | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/ceph_devstack/cli.py b/ceph_devstack/cli.py index ccb02ef8..d0ddbe7a 100644 --- a/ceph_devstack/cli.py +++ b/ceph_devstack/cli.py @@ -1,8 +1,10 @@ import asyncio import logging import sys - from pathlib import Path +from pydoc import ttypager +import os +from datetime import datetime from ceph_devstack import config, logger, parse_args, VERBOSE from ceph_devstack.requirements import check_requirements @@ -40,6 +42,9 @@ async def run(): return elif args.command == "wait": return await obj.wait(container_name=args.container) + elif args.command == "logs": + ret=teuthology_logs(str(data_path)) + return ret else: await obj.apply(args.command) return 0 @@ -48,3 +53,45 @@ async def run(): sys.exit(asyncio.run(run())) except KeyboardInterrupt: logger.debug("Exiting!") + +def teuthology_logs(data_path): + list_runs = [f.path for f in os.scandir(data_path + "/archive") if f.is_dir()] + if len(list_runs) == 0: + logger.error("No runs found!") + return 1 + list_runs.sort(key=lambda x: datetime.strptime(x.split('/')[-1].split('root-')[1].split('-teuthology')[0], '%Y-%m-%d_%H:%M:%S')) + latest_run = list_runs[-1] + latest_run_subdir = [f.path for f in os.scandir(latest_run) if f.is_dir()] + if len(latest_run_subdir) == 0: + logger.error("No jobs found!") + return 1 + if len(latest_run_subdir) == 1: + try: + if config["args"].get("log_file", False): + print(f"Log file path: {latest_run_subdir[0]}/teuthology.log") + return 0 + with open(latest_run_subdir[0] + "/teuthology.log", 'r') as f: + ttypager(f.read()) + return 0 + except : + logger.error("No logs found!") + return 1 + print("Jobs present in latest run:") + job_ids=[] + for job in latest_run_subdir: + job_ids.append(job.split('/')[-1]) + print(f"Job id: {job.split('/')[-1]}") + job_id=input("Enter any of the above job id to get logs: ") + if job_id not in job_ids: + logger.error("Invalid job id!") + return 1 + try: + if config["args"].get("log_file", False): + print(f"Log file path: {latest_run +'/'+ job_id +'/teuthology.log'}") + return 0 + with open(latest_run +"/"+ job_id +"/teuthology.log", 'r') as f: + ttypager(f.read()) + except : + logger.error("Error reading the logs!") + return 1 + return 0 \ No newline at end of file From e90948e6ae27f2ea9331ce5bd43ce9e02955d707 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Mon, 24 Mar 2025 14:40:08 +0530 Subject: [PATCH 03/10] Add type hints to teuthology function and comments --- ceph_devstack/cli.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ceph_devstack/cli.py b/ceph_devstack/cli.py index d0ddbe7a..bf208651 100644 --- a/ceph_devstack/cli.py +++ b/ceph_devstack/cli.py @@ -54,7 +54,13 @@ async def run(): except KeyboardInterrupt: logger.debug("Exiting!") -def teuthology_logs(data_path): +def teuthology_logs(data_path:str) -> int: + """ + This function is used to get the teuthology logs of the latest job run. + + Args: + data_path (str): Path to the data directory. + """ list_runs = [f.path for f in os.scandir(data_path + "/archive") if f.is_dir()] if len(list_runs) == 0: logger.error("No runs found!") From 22d944b9c2d3851a8c54732ccb1e2eb519fb1017 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Mon, 24 Mar 2025 15:02:43 +0530 Subject: [PATCH 04/10] Adding pytest unit tests to test 'logs' command --- ceph_devstack/resources/test/test_config.yaml | 17 +++ ceph_devstack/resources/test/test_logs.py | 101 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 ceph_devstack/resources/test/test_config.yaml create mode 100644 ceph_devstack/resources/test/test_logs.py diff --git a/ceph_devstack/resources/test/test_config.yaml b/ceph_devstack/resources/test/test_config.yaml new file mode 100644 index 00000000..f9e3e9ff --- /dev/null +++ b/ceph_devstack/resources/test/test_config.yaml @@ -0,0 +1,17 @@ +containers: + postgres: + image: "quay.io/ceph-infra/teuthology-postgresql:latest" + paddles: + image: "quay.io/ceph-infra/paddles:latest" + beanstalk: + image: "quay.io/ceph-infra/teuthology-beanstalkd:latest" + archive: + image: "python:alpine" + pulpito: + image: "quay.io/ceph-infra/pulpito:latest" + testnode: + count: 3 + image: "quay.io/ceph-infra/teuthology-testnode:latest" + teuthology: + image: "quay.io/ceph-infra/teuthology-dev:latest" +data_dir: /tmp/ceph-devstack diff --git a/ceph_devstack/resources/test/test_logs.py b/ceph_devstack/resources/test/test_logs.py new file mode 100644 index 00000000..8c6d2197 --- /dev/null +++ b/ceph_devstack/resources/test/test_logs.py @@ -0,0 +1,101 @@ +import pytest +import os +from datetime import datetime,timedelta +from ceph_devstack.cli import main +import random +import shutil +import string +import sys +import logging + +@pytest.mark.parametrize("num_runs,num_jobs,selection",[(0,0,0),(2,0,0),(4,1,0),(4,3,2),(3, 2, 3)]) +@pytest.mark.parametrize("flag_set",["true","false"]) +def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:str,capsys:pytest.CaptureFixture,monkeypatch:pytest.MonkeyPatch,caplog:pytest.LogCaptureFixture) -> int: + """ This function tests the 'logs' command of ceph-devstack. + + Creates a directory structure with random logs and runs the 'logs' command. + Checks if the logs are displayed correctly. + Removes the directory structure after the test. + + Args: + num_runs (int): Number of runs to be created. + num_jobs (int): Number of jobs to be created. + selection (int): The job id to be selected. + flag_set (str): Flag to set log file path. + capsys (fixture): To capture stdout and stderr. + monkeypatch (fixture): To patch the sys.argv for invoking cli with args and stdin for job selection. + caplog (fixture): To capture logs. + """ + logger = logging.getLogger(__name__) + + if flag_set=="true": + monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs','--log-file']) + else: + monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs']) + monkeypatch.setattr('builtins.input', lambda name: str(selection)) + data_path = '/tmp/ceph-devstack' + try: + os.makedirs(data_path+'/archive', exist_ok=True) + except Exception as e: + logger.error(f"Error creating directory: {e}") + return 1 + runs_dir={} + if num_runs>0: + for i in range(num_runs): + end = datetime.now() + start = end - timedelta(days=4) + random_date = start + (end - start) * random.random() + random_date=random_date.strftime('%Y-%m-%d_%H:%M:%S') + try: + os.makedirs(data_path+'/archive'+'/root-'+random_date+'-teuthology', exist_ok=True) + except Exception as e: + logger.error(f"Error creating directory: {e}") + return 1 + random_logs = [] + if num_jobs>0: + for j in range(num_jobs): + try: + os.makedirs(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j), exist_ok=True) + except Exception as e: + logger.error(f"Error creating directory: {e}") + return 1 + try: + with open(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j)+'/teuthology.log', 'w') as f: + random_logs.append(''.join(random.choices(string.ascii_letters, k=200))) + f.write(random_logs[-1]) + except Exception as e: + logger.error(f"Error creating file: {e}") + return 1 + runs_dir[data_path+'/archive'+'/root-'+random_date+'-teuthology']=random_logs + try: + with pytest.raises(SystemExit) as main_exit: + main() + except Exception as e: + logger.error(f"Error running main: {e}") + return 1 + + output, err = capsys.readouterr() + try: + shutil.rmtree(data_path+'/archive') + except Exception as e: + logger.error(f"Error removing directory: {e}") + return 1 + + runs_dir_list=list(runs_dir.keys()) + if num_runs>0: + runs_dir_list.sort(key=lambda x: datetime.strptime(x.split('/')[-1].split('root-')[1].split('-teuthology')[0], '%Y-%m-%d_%H:%M:%S')) + if num_runs < 1: + assert main_exit.value.code == 1 + assert "No runs found!" in caplog.text + elif num_jobs < 1: + assert main_exit.value.code == 1 + assert "No jobs found!" in caplog.text + elif selection not in range(num_jobs): + assert main_exit.value.code == 1 + assert "Invalid job id!" in caplog.text + elif flag_set=="true": + assert main_exit.value.code == 0 + assert f"Log file path: {runs_dir_list[-1]}/{selection}/teuthology.log" in output + else: + assert main_exit.value.code == 0 + assert runs_dir[runs_dir_list[-1]][int(selection)] in output From 534cb99253f15b7b07339ae5abc846b6897a2561 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Mon, 24 Mar 2025 15:26:52 +0530 Subject: [PATCH 05/10] Update README with 'logs' command --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index c38f49b1..a73b9b62 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,16 @@ To watch teuthology's output, you can: ```bash podman logs -f teuthology ``` +To locate/ display the ``teuthology.log`` log archive of latest test run, you can + +```bash +# To display the logs of latest run +ceph-devstack logs +``` +```bash +# To locate the logs of latest run +ceph-devstack logs --log-file +``` If you want testnode containers to be replaced as they are stopped and destroyed, you can: From 8276573655c132972e63d3fad026afc8698a2d24 Mon Sep 17 00:00:00 2001 From: Abhi <29863835+abhi4578@users.noreply.github.com> Date: Tue, 25 Mar 2025 00:39:24 +0530 Subject: [PATCH 06/10] Update README.md Signed-off-by: Abhi <29863835+abhi4578@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a73b9b62..0ee43df2 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ To locate/ display the ``teuthology.log`` log archive of latest test run, you ca ceph-devstack logs ``` ```bash -# To locate the logs of latest run +# To locate the logs file of latest run ceph-devstack logs --log-file ``` From 683b7b07e7b543d94c9711a8c6da95c3e4f8eb9e Mon Sep 17 00:00:00 2001 From: Abhi <29863835+abhi4578@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:06:32 +0530 Subject: [PATCH 07/10] Update ceph_devstack/resources/test/test_logs.py Co-authored-by: Kamoltat (Junior) Sirivadhna Signed-off-by: Abhi <29863835+abhi4578@users.noreply.github.com> --- ceph_devstack/resources/test/test_logs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ceph_devstack/resources/test/test_logs.py b/ceph_devstack/resources/test/test_logs.py index 8c6d2197..f3c6d130 100644 --- a/ceph_devstack/resources/test/test_logs.py +++ b/ceph_devstack/resources/test/test_logs.py @@ -28,7 +28,7 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:str,c """ logger = logging.getLogger(__name__) - if flag_set=="true": + if flag_set: monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs','--log-file']) else: monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs']) From b48f79f17d332736dd5fa25de9dac24caf958f53 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:49:30 +0530 Subject: [PATCH 08/10] Resolving issues raised in review - Add appropriate comments for better understanding - Add try, except block while parsing latest job directory paths to catch ValueError - Make flag_set to boolean from str for simplicity in test_logs.py - Added chec condition if teuthology.log file exists before reading to prevent exceptions --- ceph_devstack/cli.py | 36 +++++++++++++++-------- ceph_devstack/resources/test/test_logs.py | 13 +++++--- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/ceph_devstack/cli.py b/ceph_devstack/cli.py index bf208651..32f4bad7 100644 --- a/ceph_devstack/cli.py +++ b/ceph_devstack/cli.py @@ -64,14 +64,21 @@ def teuthology_logs(data_path:str) -> int: list_runs = [f.path for f in os.scandir(data_path + "/archive") if f.is_dir()] if len(list_runs) == 0: logger.error("No runs found!") - return 1 - list_runs.sort(key=lambda x: datetime.strptime(x.split('/')[-1].split('root-')[1].split('-teuthology')[0], '%Y-%m-%d_%H:%M:%S')) + return 1 + # Atleast one run directory exist, due to above condition + try: + list_runs.sort(key=lambda x: datetime.strptime(x.split('/')[-1].split('root-')[1].split('-teuthology')[0], '%Y-%m-%d_%H:%M:%S')) + except ValueError as e: + # if the run directory is not in the format root-YYYY-MM-DD_HH:MM:SS-teuthology + logger.error(f"Error parsing date: {e}") + return 1 latest_run = list_runs[-1] latest_run_subdir = [f.path for f in os.scandir(latest_run) if f.is_dir()] if len(latest_run_subdir) == 0: logger.error("No jobs found!") return 1 - if len(latest_run_subdir) == 1: + # check if only one job present, then display logs. Also check if the teuthology.log file exists in the latest run directory + if len(latest_run_subdir) == 1 and os.path.exists(latest_run_subdir[0] + "/teuthology.log") and os.path.isfile(latest_run_subdir[0] + "/teuthology.log"): try: if config["args"].get("log_file", False): print(f"Log file path: {latest_run_subdir[0]}/teuthology.log") @@ -82,22 +89,27 @@ def teuthology_logs(data_path:str) -> int: except : logger.error("No logs found!") return 1 + + # Multiple jobs present, then display the job ids print("Jobs present in latest run:") job_ids=[] for job in latest_run_subdir: job_ids.append(job.split('/')[-1]) print(f"Job id: {job.split('/')[-1]}") job_id=input("Enter any of the above job id to get logs: ") + # check if the job id is valid if job_id not in job_ids: logger.error("Invalid job id!") return 1 - try: - if config["args"].get("log_file", False): - print(f"Log file path: {latest_run +'/'+ job_id +'/teuthology.log'}") - return 0 - with open(latest_run +"/"+ job_id +"/teuthology.log", 'r') as f: - ttypager(f.read()) - except : - logger.error("Error reading the logs!") - return 1 + # check if the teuthology.log file exists in the job directory + if os.path.exists(latest_run +'/'+ job_id +'/teuthology.log') and os.path.isfile(latest_run +'/'+ job_id +'/teuthology.log'): + try: + if config["args"].get("log_file", False): + print(f"Log file path: {latest_run +'/'+ job_id +'/teuthology.log'}") + return 0 + with open(latest_run +"/"+ job_id +"/teuthology.log", 'r') as f: + ttypager(f.read()) + except : + logger.error("Error reading the logs!") + return 1 return 0 \ No newline at end of file diff --git a/ceph_devstack/resources/test/test_logs.py b/ceph_devstack/resources/test/test_logs.py index f3c6d130..7a226997 100644 --- a/ceph_devstack/resources/test/test_logs.py +++ b/ceph_devstack/resources/test/test_logs.py @@ -8,9 +8,14 @@ import sys import logging +''' +Using pytest paramtrization to test logs command with different +combinations of runs, jobs, selection and if view file path flag is set. +Following parameter combination results in 5*2=10 test cases. +''' @pytest.mark.parametrize("num_runs,num_jobs,selection",[(0,0,0),(2,0,0),(4,1,0),(4,3,2),(3, 2, 3)]) -@pytest.mark.parametrize("flag_set",["true","false"]) -def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:str,capsys:pytest.CaptureFixture,monkeypatch:pytest.MonkeyPatch,caplog:pytest.LogCaptureFixture) -> int: +@pytest.mark.parametrize("flag_set",[ True, False]) +def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool,capsys:pytest.CaptureFixture,monkeypatch:pytest.MonkeyPatch,caplog:pytest.LogCaptureFixture) -> int: """ This function tests the 'logs' command of ceph-devstack. Creates a directory structure with random logs and runs the 'logs' command. @@ -21,7 +26,7 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:str,c num_runs (int): Number of runs to be created. num_jobs (int): Number of jobs to be created. selection (int): The job id to be selected. - flag_set (str): Flag to set log file path. + flag_set (bool): Flag to set log file path. capsys (fixture): To capture stdout and stderr. monkeypatch (fixture): To patch the sys.argv for invoking cli with args and stdin for job selection. caplog (fixture): To capture logs. @@ -93,7 +98,7 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:str,c elif selection not in range(num_jobs): assert main_exit.value.code == 1 assert "Invalid job id!" in caplog.text - elif flag_set=="true": + elif flag_set: assert main_exit.value.code == 0 assert f"Log file path: {runs_dir_list[-1]}/{selection}/teuthology.log" in output else: From 3a0626fa97609141ab03033c98566a8868f307d6 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Thu, 10 Apr 2025 20:04:49 +0530 Subject: [PATCH 09/10] Fix teuthology.log file exists and add test cases --- ceph_devstack/cli.py | 27 ++++++++++++++--------- ceph_devstack/resources/test/test_logs.py | 24 +++++++++++--------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/ceph_devstack/cli.py b/ceph_devstack/cli.py index 32f4bad7..98e7c355 100644 --- a/ceph_devstack/cli.py +++ b/ceph_devstack/cli.py @@ -78,16 +78,20 @@ def teuthology_logs(data_path:str) -> int: logger.error("No jobs found!") return 1 # check if only one job present, then display logs. Also check if the teuthology.log file exists in the latest run directory - if len(latest_run_subdir) == 1 and os.path.exists(latest_run_subdir[0] + "/teuthology.log") and os.path.isfile(latest_run_subdir[0] + "/teuthology.log"): - try: - if config["args"].get("log_file", False): - print(f"Log file path: {latest_run_subdir[0]}/teuthology.log") + if len(latest_run_subdir) == 1 : + if os.path.exists(latest_run_subdir[0] + "/teuthology.log") and os.path.isfile(latest_run_subdir[0] + "/teuthology.log"): + try: + if config["args"].get("log_file", False): + print(f"Log file path: {latest_run_subdir[0]}/teuthology.log") + return 0 + with open(latest_run_subdir[0] + "/teuthology.log", 'r') as f: + ttypager(f.read()) return 0 - with open(latest_run_subdir[0] + "/teuthology.log", 'r') as f: - ttypager(f.read()) - return 0 - except : - logger.error("No logs found!") + except : + logger.error("Error while reading teuthology.log!") + return 1 + else: + logger.error("teuthology.log file not found!") return 1 # Multiple jobs present, then display the job ids @@ -110,6 +114,9 @@ def teuthology_logs(data_path:str) -> int: with open(latest_run +"/"+ job_id +"/teuthology.log", 'r') as f: ttypager(f.read()) except : - logger.error("Error reading the logs!") + logger.error("Error while reading teuthology.log!!") return 1 + else: + logger.error("teuthology.log file not found!") + return 1 return 0 \ No newline at end of file diff --git a/ceph_devstack/resources/test/test_logs.py b/ceph_devstack/resources/test/test_logs.py index 7a226997..37b9663a 100644 --- a/ceph_devstack/resources/test/test_logs.py +++ b/ceph_devstack/resources/test/test_logs.py @@ -11,11 +11,11 @@ ''' Using pytest paramtrization to test logs command with different combinations of runs, jobs, selection and if view file path flag is set. -Following parameter combination results in 5*2=10 test cases. +Following parameter combination results in 7*2=14 test cases. ''' -@pytest.mark.parametrize("num_runs,num_jobs,selection",[(0,0,0),(2,0,0),(4,1,0),(4,3,2),(3, 2, 3)]) +@pytest.mark.parametrize("num_runs,num_jobs,selection,teuthology_file_present",[(0,0,0,True),(2,0,0,True),(4,1,0,True),(4,1,0,False),(4,3,2,True),((4,3,2,False)),(3, 2, 3,True)]) @pytest.mark.parametrize("flag_set",[ True, False]) -def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool,capsys:pytest.CaptureFixture,monkeypatch:pytest.MonkeyPatch,caplog:pytest.LogCaptureFixture) -> int: +def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool,teuthology_file_present:bool,capsys:pytest.CaptureFixture,monkeypatch:pytest.MonkeyPatch,caplog:pytest.LogCaptureFixture) -> int: """ This function tests the 'logs' command of ceph-devstack. Creates a directory structure with random logs and runs the 'logs' command. @@ -64,13 +64,14 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, except Exception as e: logger.error(f"Error creating directory: {e}") return 1 - try: - with open(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j)+'/teuthology.log', 'w') as f: - random_logs.append(''.join(random.choices(string.ascii_letters, k=200))) - f.write(random_logs[-1]) - except Exception as e: - logger.error(f"Error creating file: {e}") - return 1 + if teuthology_file_present: + try: + with open(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j)+'/teuthology.log', 'w') as f: + random_logs.append(''.join(random.choices(string.ascii_letters, k=200))) + f.write(random_logs[-1]) + except Exception as e: + logger.error(f"Error creating file: {e}") + return 1 runs_dir[data_path+'/archive'+'/root-'+random_date+'-teuthology']=random_logs try: with pytest.raises(SystemExit) as main_exit: @@ -98,6 +99,9 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, elif selection not in range(num_jobs): assert main_exit.value.code == 1 assert "Invalid job id!" in caplog.text + elif not teuthology_file_present: + assert main_exit.value.code == 1 + assert "teuthology.log file not found!" in caplog.text elif flag_set: assert main_exit.value.code == 0 assert f"Log file path: {runs_dir_list[-1]}/{selection}/teuthology.log" in output From fe0f8b803b8042c15c4af607261016e24f2394d3 Mon Sep 17 00:00:00 2001 From: abhi4578 <29863835+abhi4578@users.noreply.github.com> Date: Thu, 10 Apr 2025 21:29:33 +0530 Subject: [PATCH 10/10] Replacing test config yaml file with toml file - Also replace return statements with exit statements in test_logs.py file because pytest warnings --- ceph_devstack/resources/test/test_config.toml | 23 +++++++++++++++++++ ceph_devstack/resources/test/test_config.yaml | 17 -------------- ceph_devstack/resources/test/test_logs.py | 16 ++++++------- 3 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 ceph_devstack/resources/test/test_config.toml delete mode 100644 ceph_devstack/resources/test/test_config.yaml diff --git a/ceph_devstack/resources/test/test_config.toml b/ceph_devstack/resources/test/test_config.toml new file mode 100644 index 00000000..0466321c --- /dev/null +++ b/ceph_devstack/resources/test/test_config.toml @@ -0,0 +1,23 @@ +data_dir = "/tmp/ceph-devstack" + +[containers.archive] +image = "python:alpine" + +[containers.beanstalk] +image = "quay.io/ceph-infra/teuthology-beanstalkd:latest" + +[containers.paddles] +image = "quay.io/ceph-infra/paddles:latest" + +[containers.postgres] +image = "quay.io/ceph-infra/teuthology-postgresql:latest" + +[containers.pulpito] +image = "quay.io/ceph-infra/pulpito:latest" + +[containers.testnode] +count = 3 +image = "quay.io/ceph-infra/teuthology-testnode:latest" + +[containers.teuthology] +image = "quay.io/ceph-infra/teuthology-dev:latest" diff --git a/ceph_devstack/resources/test/test_config.yaml b/ceph_devstack/resources/test/test_config.yaml deleted file mode 100644 index f9e3e9ff..00000000 --- a/ceph_devstack/resources/test/test_config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -containers: - postgres: - image: "quay.io/ceph-infra/teuthology-postgresql:latest" - paddles: - image: "quay.io/ceph-infra/paddles:latest" - beanstalk: - image: "quay.io/ceph-infra/teuthology-beanstalkd:latest" - archive: - image: "python:alpine" - pulpito: - image: "quay.io/ceph-infra/pulpito:latest" - testnode: - count: 3 - image: "quay.io/ceph-infra/teuthology-testnode:latest" - teuthology: - image: "quay.io/ceph-infra/teuthology-dev:latest" -data_dir: /tmp/ceph-devstack diff --git a/ceph_devstack/resources/test/test_logs.py b/ceph_devstack/resources/test/test_logs.py index 37b9663a..5e382f84 100644 --- a/ceph_devstack/resources/test/test_logs.py +++ b/ceph_devstack/resources/test/test_logs.py @@ -34,16 +34,16 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, logger = logging.getLogger(__name__) if flag_set: - monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs','--log-file']) + monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.toml', 'logs','--log-file']) else: - monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.yaml', 'logs']) + monkeypatch.setattr(sys, 'argv', [ sys.argv[0],'-c', 'ceph_devstack/resources/test/test_config.toml', 'logs']) monkeypatch.setattr('builtins.input', lambda name: str(selection)) data_path = '/tmp/ceph-devstack' try: os.makedirs(data_path+'/archive', exist_ok=True) except Exception as e: logger.error(f"Error creating directory: {e}") - return 1 + exit(1) runs_dir={} if num_runs>0: for i in range(num_runs): @@ -55,7 +55,7 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, os.makedirs(data_path+'/archive'+'/root-'+random_date+'-teuthology', exist_ok=True) except Exception as e: logger.error(f"Error creating directory: {e}") - return 1 + exit(1) random_logs = [] if num_jobs>0: for j in range(num_jobs): @@ -63,7 +63,7 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, os.makedirs(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j), exist_ok=True) except Exception as e: logger.error(f"Error creating directory: {e}") - return 1 + exit(1) if teuthology_file_present: try: with open(data_path+'/archive'+'/root-'+random_date+'-teuthology/'+str(j)+'/teuthology.log', 'w') as f: @@ -71,21 +71,21 @@ def test_teuthology_logs(num_runs:int,num_jobs:int,selection:int, flag_set:bool, f.write(random_logs[-1]) except Exception as e: logger.error(f"Error creating file: {e}") - return 1 + exit(1) runs_dir[data_path+'/archive'+'/root-'+random_date+'-teuthology']=random_logs try: with pytest.raises(SystemExit) as main_exit: main() except Exception as e: logger.error(f"Error running main: {e}") - return 1 + exit(1) output, err = capsys.readouterr() try: shutil.rmtree(data_path+'/archive') except Exception as e: logger.error(f"Error removing directory: {e}") - return 1 + exit(1) runs_dir_list=list(runs_dir.keys()) if num_runs>0: