From 9a4ded5a2728d737bd94f0d62efcf670c143f103 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Thu, 26 Sep 2024 14:54:07 +0200 Subject: [PATCH 1/3] GL-1428: Use natural sort for plot entries (code adapted from Cylc GPLv3) --- autosubmit/helpers/utils.py | 96 +++++++++++++++++++++++++++++++++-- autosubmit/monitor/monitor.py | 3 +- 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/autosubmit/helpers/utils.py b/autosubmit/helpers/utils.py index 7ccca9cf8..6d13cb53b 100644 --- a/autosubmit/helpers/utils.py +++ b/autosubmit/helpers/utils.py @@ -1,13 +1,15 @@ -import subprocess +import locale import os import pwd +import re import signal -import locale -from autosubmit.notifications.mail_notifier import MailNotifier - -from autosubmit.notifications.notifier import Notifier +import subprocess +from itertools import zip_longest from autosubmitconfigparser.config.basicconfig import BasicConfig + +from autosubmit.notifications.mail_notifier import MailNotifier +from autosubmit.notifications.notifier import Notifier from log.log import AutosubmitCritical, Log @@ -160,3 +162,87 @@ def restore_platforms(platform_to_test, mail_notify=False, as_conf=None, expid=N raise AutosubmitCritical("Issues while checking the connectivity of platforms.", 7010, issues + "\n" + ssh_config_issues) +# Source: https://github.com/cylc/cylc-flow/blob/a722b265ad0bd68bc5366a8a90b1dbc76b9cd282/cylc/flow/tui/util.py#L226 +class NaturalSort: + """An object to use as a sort key for sorting strings as a human would. + + This recognises numerical patterns within strings. + + Examples: + >>> N = NaturalSort + + String comparisons work as normal: + >>> N('') < N('') + False + >>> N('a') < N('b') + True + >>> N('b') < N('a') + False + + Integer comparisons work as normal: + >>> N('9') < N('10') + True + >>> N('10') < N('9') + False + + Integers rank higher than strings: + >>> N('1') < N('a') + True + >>> N('a') < N('1') + False + + Integers within strings are sorted numerically: + >>> N('a9b') < N('a10b') + True + >>> N('a10b') < N('a9b') + False + + Lexicographical rules apply when substrings match: + >>> N('a1b2') < N('a1b2c3') + True + >>> N('a1b2c3') < N('a1b2') + False + + Equality works as per regular string rules: + >>> N('a1b2c3') == N('a1b2c3') + True + + """ + + PATTERN = re.compile(r'(\d+)') + + def __init__(self, value): + self.value = tuple( + int(item) if item.isdigit() else item + for item in self.PATTERN.split(value) + # remove empty strings if value ends with a digit + if item + ) + + def __eq__(self, other): + return self.value == other.value + + def __lt__(self, other): + for this, that in zip_longest(self.value, other.value): + if this is None: + return True + if that is None: + return False + this_isstr = isinstance(this, str) + that_isstr = isinstance(that, str) + if this_isstr and that_isstr: + if this == that: + continue + return this < that + this_isint = isinstance(this, int) + that_isint = isinstance(that, int) + if this_isint and that_isint: + if this == that: + continue + return this < that + if this_isint and that_isstr: + return True + if this_isstr and that_isint: + return False + return False + diff --git a/autosubmit/monitor/monitor.py b/autosubmit/monitor/monitor.py index 224ee604e..ccdfffb02 100644 --- a/autosubmit/monitor/monitor.py +++ b/autosubmit/monitor/monitor.py @@ -34,6 +34,7 @@ import autosubmit.helpers.utils as HelperUtils from autosubmit.job.job_common import Status from autosubmit.job.job import Job +from autosubmit.helpers.utils import NaturalSort from autosubmitconfigparser.config.basicconfig import BasicConfig from autosubmitconfigparser.config.configcommon import AutosubmitConfig @@ -319,7 +320,7 @@ class Monitor: return self.nodes_plotted.add(job) if job.has_children() != 0: - for child in sorted(job.children, key=lambda k: k.name): + for child in sorted(job.children, key=lambda k: NaturalSort(k.name)): node_child, skip = self._check_node_exists( exp, child, groups, hide_groups) color, label = self._check_final_status(job, child) -- GitLab From 06ae34b0515a621e4aa389e851f2ba0434fdf0be Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Thu, 26 Sep 2024 15:48:13 +0200 Subject: [PATCH 2/3] GL-1428: enable doctests in pytest --- pytest.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pytest.ini b/pytest.ini index 5ab9b5fe7..32a1148ce 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,8 +4,10 @@ addopts = --cov=autosubmit --cov-config=.coveragerc --cov-report=html:test/htmlcov --cov-report=xml:test/coverage.xml --strict-markers + --doctest-modules testpaths = test/unit + autosubmit doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL -- GitLab From cd2527d51d7ed6667d2e1f434d48d3e307709a87 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Thu, 26 Sep 2024 15:50:40 +0200 Subject: [PATCH 3/3] GL-1428: changelog --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index af69e6800..ef6a0eec1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ - #1373: Update installation instructions with `rsync`, and fix our `Dockerfile` adding `rsync` and `subversion`. - #1207: Add experiment path in `autosubmit describe`. +- #1397: Use `tini` as entrypoint in our Docker image. +- #1428: Use natural sort order for graph entries (adapted from Cylc), + enable doctests to be executed with pytest. 4.1.10 - Hotfix =============== -- GitLab