Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions condor_tools/condor_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,30 @@ def _setup_condor() -> tuple:

def _get_real_name(username: str) -> str:
"""Uses the 'pinky' command to get the real name of a user from their username"""
real_name = ""
try:
# Parse output of 'pinky' to extract the real name
result = subprocess.run(["pinky", "-l", username], check=False, stdout=subprocess.PIPE, text=True)
if result.returncode == 0:
for line in result.stdout.split("\n"):
if "In real life:" in line:
return line.split("In real life:")[1].strip()
real_name = line.split("In real life:")[1].strip()
except Exception:
pass
return ""
finally:
if real_name in {"???", ""}:
real_name = "Unknown"
return real_name


def _get_user_experiments(username: str, excluded_groups: Optional[list[str]] = None) -> str:
"""Get user's experiment(s) using groups command"""
if excluded_groups is None:
excluded_groups = [username, "res0", "htcuser"]
try:
result = subprocess.run(["groups", username], check=False, stdout=subprocess.PIPE, text=True)
result = subprocess.run(
["groups", username], check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL
)
if result.returncode == 0:
excluded_groups.append(username)
# command output is formatted like username : username group1 group2 ...
Expand Down Expand Up @@ -252,7 +258,7 @@ def format_table(
return tab


def log():
def log(args: argparse.Namespace):
"""Logs the usage of the script"""
# Get the current user's username
username = getpass.getuser()
Expand All @@ -266,7 +272,7 @@ def log():
log_file_path = os.path.join(script_dir, "usage_log.txt")
with open(log_file_path, "a+") as log_file:
# Write the timestamp, username, and real name to the log file
log_file.write(f"{timestamp}, {username}, {real_name}\n")
log_file.write(f"{timestamp}, {username}, {real_name}, {str(vars(args)).replace(',', ';').replace(' ', '')}\n")


def main():
Expand Down Expand Up @@ -295,7 +301,7 @@ def main():
else:
user_priorities = {}

log()
log(args)
user_stats = fetch_jobs(args.only, _setup_condor()[1])
table = format_table(user_stats, args.only, user_priorities, current_user=username, priority=priority)
logging.info(table, extra={"simple": True})
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[project]
name = "condor_tools"
version = "1.1.1"
version = "1.1.2"
description = "A collection of tools for working with Condor jobs and data."
requires-python = "==3.9.21"
authors = [{name = "Tom Runting", email = "thomas.runting@cern.ch"}]

dependencies = [
"coverage==7.10.3",
"exceptiongroup==1.3.0",
"htcondor==24.0.10",
"htcondor==24.0.11",
"iniconfig==2.1.0",
"packaging==25.0",
"pluggy==1.6.0",
Expand Down
8 changes: 5 additions & 3 deletions tests/test_top_level.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import datetime
import getpass
import os
Expand Down Expand Up @@ -32,14 +33,15 @@ def test_log_writes_to_file(fs, monkeypatch):
monkeypatch.setattr(condor_tools, "__file__", os.path.join(script_dir, "myscript.py"))

# Act
condor_tools.log()
args = argparse.Namespace(priority=False, only=None)
condor_tools.log(args)

# Assert: Check file contents
log_path = os.path.join(script_dir, "usage_log.txt")
with open(log_path) as f:
content = f.read()

assert content == "2025-01-01T12:00:00, testuser, Test User\n"
assert content == "2025-01-01T12:00:00, testuser, Test User, {'priority':False;'only':None}\n"


@pytest.mark.parametrize("priority", [True, False])
Expand All @@ -64,7 +66,7 @@ def test_main_with_priority(monkeypatch, caplog, priority):
monkeypatch.setattr(
subprocess, "run", lambda *a, **kw: subprocess.CompletedProcess(args=a, returncode=0, stdout=fake_output)
)
monkeypatch.setattr(condor_tools, "log", lambda: None)
monkeypatch.setattr(condor_tools, "log", lambda args: None)
monkeypatch.setattr(condor_tools, "_setup_condor", lambda: (None, "schedd"))
monkeypatch.setattr(condor_tools, "fetch_jobs", lambda only, schedd: {"job": {"some": "stats"}})
monkeypatch.setattr(condor_tools, "format_table", lambda *a, **k: "formatted table")
Expand Down
4 changes: 2 additions & 2 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def test_setup_condor(self):
class TestGetRealName:
"""Test cases for _get_real_name function."""

@pytest.mark.parametrize("username, expected", [("testuser", "???"), (None, "")])
@pytest.mark.parametrize("username, expected", [("testuser", "Unknown"), (None, "Unknown")])
def test_get_real_name(self, username, expected):
result = _get_real_name(username)
assert result == expected
Expand Down Expand Up @@ -120,7 +120,7 @@ def test_get_row(self, priority, only, april_fools, user):
row, machine_stats = _get_row(user=user, jobs=jobs, ctx=test_context)
assert row[0] == user
if user == "test_user0":
assert row[1] == "??? (expA)"
assert row[1] == "Unknown (expA)"
if priority:
assert row[2] == test_context.user_priorities[user]
if only:
Expand Down