Skip to content

Commit 45a9838

Browse files
authored
issues 153 and 150 (#156)
* fixes for isse 153 and issue 152. Also noticed some differences between slurmdb_job_rec_t in slurm and pyslurm which were fixed up * add tests for slurmdb_jobs.get() * code formating and doc strings on test functions
1 parent c50467c commit 45a9838

File tree

3 files changed

+119
-2
lines changed

3 files changed

+119
-2
lines changed

pyslurm/pyslurm.pyx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5343,7 +5343,7 @@ cdef class slurmdb_jobs:
53435343
slurm.xfree(self.job_cond)
53445344
slurm.slurmdb_connection_close(&self.db_conn)
53455345

5346-
def get(self, jobids=[], starttime=0, endtime=0):
5346+
def get(self, jobids=[], userids=[], starttime=0, endtime=0, flags = None, db_flags = None, clusters = []):
53475347
u"""Get Slurmdb information about some jobs.
53485348
53495349
Input formats for start and end times:
@@ -5371,6 +5371,23 @@ cdef class slurmdb_jobs:
53715371
slurm.List JOBSList
53725372
slurm.ListIterator iters = NULL
53735373

5374+
5375+
if clusters:
5376+
self.job_cond.cluster_list = slurm.slurm_list_create(NULL)
5377+
for _cluster in clusters:
5378+
_cluster = _cluster.encode("UTF-8")
5379+
slurm.slurm_addto_char_list_with_case(self.job_cond.cluster_list, _cluster, False)
5380+
5381+
if db_flags:
5382+
if isinstance(db_flags, int):
5383+
self.job_cond.db_flags = db_flags
5384+
else:
5385+
self.job_cond.db_flags = slurm.SLURMDB_JOB_FLAG_NOTSET
5386+
5387+
if flags:
5388+
if isinstance(flags, int):
5389+
self.job_cond.flags = flags
5390+
53745391
if jobids:
53755392
self.job_cond.step_list = slurm.slurm_list_create(NULL)
53765393
for _jobid in jobids:
@@ -5380,6 +5397,15 @@ cdef class slurmdb_jobs:
53805397
_jobid = _jobid.encode("UTF-8")
53815398
slurm.slurm_addto_step_list(self.job_cond.step_list, _jobid)
53825399

5400+
if userids:
5401+
self.job_cond.userid_list = slurm.slurm_list_create(NULL)
5402+
for _userid in userids:
5403+
if isinstance(_userid, int) or isinstance(_userid, long):
5404+
_userid = str(_userid).encode("UTF-8")
5405+
else:
5406+
_userid = _userid.encode("UTF-8")
5407+
slurm.slurm_addto_char_list_with_case(self.job_cond.userid_list, _userid, False)
5408+
53835409
if starttime:
53845410
self.job_cond.usage_start = slurm.slurm_parse_time(starttime, 1)
53855411
errno = slurm.slurm_get_errno()
@@ -5466,6 +5492,10 @@ cdef class slurmdb_jobs:
54665492

54675493
slurm.slurm_list_iterator_destroy(iters)
54685494
slurm.slurm_list_destroy(JOBSList)
5495+
if clusters:
5496+
slurm.slurm_list_destroy(self.job_cond.cluster_list)
5497+
if userids:
5498+
slurm.slurm_list_destroy(self.job_cond.userid_list)
54695499
return J_dict
54705500

54715501
#

pyslurm/slurm.pxd

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,7 @@ cdef extern from 'slurm/slurmdb.h' nogil:
26082608

26092609
ctypedef struct slurmdb_job_rec_t:
26102610
char *account
2611+
char *admin_comment
26112612
char *alloc_gres
26122613
uint32_t alloc_nodes
26132614
uint32_t array_job_id
@@ -2630,8 +2631,11 @@ cdef extern from 'slurm/slurmdb.h' nogil:
26302631
uint32_t jobid
26312632
char *jobname
26322633
uint32_t lft
2633-
char *partition
2634+
char *mcs_label
26342635
char *nodes
2636+
char *partition
2637+
uint32_t pack_job_id
2638+
uint32_t pack_job_offset
26352639
uint32_t priority
26362640
uint32_t qosid
26372641
uint32_t req_cpus
@@ -2664,6 +2668,7 @@ cdef extern from 'slurm/slurmdb.h' nogil:
26642668
uint32_t user_cpu_usec
26652669
char *wckey
26662670
uint32_t wckeyid
2671+
char *work_dir
26672672

26682673
ctypedef struct slurmdb_qos_usage_t:
26692674
uint32_t accrue_cnt
@@ -2904,6 +2909,7 @@ cdef extern char *slurm_get_checkpoint_dir()
29042909
cdef extern void slurm_sprint_cpu_bind_type(char *string, cpu_bind_type_t cpu_bind_type)
29052910
cdef extern void slurm_destroy_char(void *object)
29062911
cdef extern int slurm_addto_step_list(List step_list, char *names)
2912+
cdef extern int slurm_addto_char_list_with_case(List char_list, char *names, bool lower_case_noralization)
29072913
cdef extern time_t slurm_parse_time(char *time_str, int past)
29082914
cdef extern int slurm_time_str2mins(const_char_ptr string)
29092915
cdef extern int slurm_time_str2secs(const_char_ptr string)

tests/test-slurmdb.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import datetime
2+
import pwd
3+
import subprocess
4+
5+
from nose.tools import assert_equals
6+
7+
import pyslurm
8+
9+
10+
def njobs_sacct_jobs(start, end, username=None):
11+
"""
12+
Count the number of jobs reported by sacct
13+
For comparison with the reults of slurmdb_jobs.get
14+
"""
15+
sacctcmd = ['sacct', '-S', start, '-E', end, '-n', '-X']
16+
if username is not None:
17+
sacctcmd.extend(['-u', username])
18+
else:
19+
sacctcmd.append('-a')
20+
sacct = subprocess.Popen(sacctcmd,
21+
stdout=subprocess.PIPE,
22+
stderr=None).communicate()
23+
return len(sacct[0].splitlines())
24+
25+
26+
def njobs_slurmdb_jobs_get(start, end, uid=None):
27+
"""
28+
Count the number of jobs reported by slurmdb
29+
"""
30+
if uid is None:
31+
jobs = pyslurm.slurmdb_jobs().get(starttime=start.encode('utf-8'),
32+
endtime=end.encode('utf-8'))
33+
else:
34+
jobs = pyslurm.slurmdb_jobs().get(starttime=start.encode('utf-8'),
35+
endtime=end.encode('utf-8'),
36+
userids=[uid])
37+
return len(jobs)
38+
39+
40+
def get_user():
41+
"""
42+
Return a list of usernames and their uid numbers
43+
"""
44+
users = subprocess.Popen(['squeue', '-O', 'username', '-h'],
45+
stdout=subprocess.PIPE,
46+
stderr=None).communicate()
47+
for username in users[0].splitlines():
48+
print(username.decode())
49+
uid = pwd.getpwnam("{}".format(username.strip().decode()))
50+
yield username.strip().decode(), uid.pw_uid
51+
52+
53+
def test_slurmdb_jobs_get():
54+
"""
55+
Slurmdb: Compare sacct and slurmdb_jobs.get() for all users
56+
"""
57+
starttime = (datetime.datetime.now() -
58+
datetime.timedelta(days=2)).strftime("%Y-%m-%dT00:00:00")
59+
endtime = (datetime.datetime.now() -
60+
datetime.timedelta(days=1)).strftime("%Y-%m-%dT00:00:00")
61+
njobs_pyslurm = njobs_slurmdb_jobs_get(starttime, endtime)
62+
njobs_sacct = njobs_sacct_jobs(starttime, endtime)
63+
assert_equals(njobs_pyslurm, njobs_sacct)
64+
65+
66+
def test_slurmdb_jobs_get_byuser():
67+
"""
68+
Slurmdb: Compare sacct and slurmdb_jobs.get() for individual users
69+
"""
70+
71+
userlist = list(get_user())
72+
for user in userlist[:10]:
73+
starttime = (datetime.datetime.now() -
74+
datetime.timedelta(days=2)).strftime("%Y-%m-%dT00:00:00")
75+
endtime = (datetime.datetime.now() -
76+
datetime.timedelta(days=1)).strftime("%Y-%m-%dT00:00:00")
77+
njobs_pyslurm = njobs_slurmdb_jobs_get(starttime,
78+
endtime,
79+
int(user[1]))
80+
njobs_sacct = njobs_sacct_jobs(starttime, endtime, username=user[0])
81+
assert_equals(njobs_pyslurm, njobs_sacct)

0 commit comments

Comments
 (0)