Repository: reframe-hpc/reframe

Issue:
Slurm node abbreviation fails for sequential nodes when the last node number is a power of 10
Using pin_nodes on a job where the requested nodes end with a power of 10 causes an invalid slurm node string to be generated in rfm_job.sh.  Example: vs-std-0009:vs-std-0010 results in #SBATCH --nodelist=vs-std-000[9-10]

I've tracked this down to reframe/utility/__init__.py:862 count_digits function.  I've fixed it locally by changing use of that function to len(str()) in nodelist_abbrev and nodelist_expand functions.  I also created a unittest in unittests/test_utility.py for this specific problem and verified the fix does not fail the existing tests.

Discussion:
@vkarak: Yes, this is indeed a bug, I've also reproduced it.@vkarak: The problem is in `count_digits()` indeed, as it wrongly reports `10` as having 1 digit. The fix is simple by changing the `while` condition in `count_digits`. I will submit a fix.

Solution patch:
diff --git a/reframe/utility/__init__.py b/reframe/utility/__init__.py
index 75c4008e3..cfa38610e 100644
--- a/reframe/utility/__init__.py
+++ b/reframe/utility/__init__.py
@@ -866,7 +866,7 @@ def count_digits(n):
     '''
 
     num_digits = 1
-    while n > 10:
+    while n >= 10:
         n /= 10
         num_digits += 1
 


Test patch:
diff --git a/unittests/test_utility.py b/unittests/test_utility.py
index 97d32c581..2cb5ac462 100644
--- a/unittests/test_utility.py
+++ b/unittests/test_utility.py
@@ -2070,6 +2070,14 @@ def test_nodelist_utilities():
     assert nodelist(nodes) == 'nid0[00-99]-x,nid100-y'
     assert expand('nid0[00-99]-x,nid100-y') == nodes
 
+    # Test edge condition when node lists jump from N to N+1 digits
+    # See GH issue #3338
+    nodes = ['vs-std-0009', 'vs-std-0010', 'vs-std-0099', 'vs-std-0100']
+    assert nodelist(nodes) == 'vs-std-00[09-10],vs-std-0[099-100]'
+    assert expand('vs-std-00[09-10],vs-std-0[099-100]') == [
+        'vs-std-0009', 'vs-std-0010', 'vs-std-0099', 'vs-std-0100'
+    ]
+
     # Test node duplicates
     assert nodelist(['nid001', 'nid001', 'nid002']) == 'nid001,nid00[1-2]'
     assert expand('nid001,nid00[1-2]') == ['nid001', 'nid001', 'nid002']