def test_30_job_stats_sync(self): stats = JobStats(self.fh) # stats are uninitialized at first: self.assertEqual(stats.active, -1) self.assertEqual(stats.inactive, -1) # synchronous update stats.update_sync() self.assertGreater(stats.inactive, 0)
def test_31_job_stats_async(self): called = [False] def cb(stats, mykw=None): called[0] = True self.assertGreater(stats.inactive, 0) self.assertEqual(mykw, "mykw") stats = JobStats(self.fh) # stats are uninitialized at first: self.assertEqual(stats.active, -1) self.assertEqual(stats.inactive, -1) # asynchronous update, no callback stats.update() self.assertEqual(stats.active, -1) self.assertEqual(stats.inactive, -1) self.fh.reactor_run() self.assertGreater(stats.inactive, 0) self.assertFalse(called[0]) # asynchronous update, with callback stats.update(callback=cb, mykw="mykw") self.fh.reactor_run() self.assertTrue(called[0])
def get_jobs_recursive(job, args, fields): jobs = [] stats = None try: # Don't generate an error if we fail to connect to this # job. This could be because job services aren't up yet, # (OSError with errno ENOSYS) or this user is not the owner # of the job. Either way, simply skip descending into the job # handle = flux.Flux(str(job.uri)) jobs = fetch_jobs_flux(args, fields, flux_handle=handle) stats = None if args.stats: stats = JobStats(handle).update_sync() except (OSError, FileNotFoundError): pass return (job, jobs, stats)
def main(): sys.stdout = open(sys.stdout.fileno(), "w", encoding="utf8") args = parse_args() if args.jobids and args.filtered and not args.recursive: LOGGER.warning("Filtering options ignored with jobid list") if args.recurse_all: args.recursive = True if args.format: fmt = args.format else: fmt = ( "{id.f58:>12} {username:<8.8} {name:<10.10} {status_abbrev:>2.2} " "{ntasks:>6} {nnodes:>6h} {runtime!F:>8h} " "{nodelist:h}") try: formatter = JobInfoFormat(fmt) except ValueError as err: raise ValueError("Error in user format: " + str(err)) if args.stats or args.stats_only: stats = JobStats(flux.Flux()).update_sync() print(f"{stats.running} running, {stats.successful} completed, " f"{stats.failed} failed, {stats.pending} pending") if args.stats_only: sys.exit(0 if stats.active else 1) jobs = fetch_jobs(args, formatter.fields) if not args.suppress_header: print(formatter.header()) print_jobs(jobs, args, formatter)