@@ -365,6 +365,256 @@ test_expect_success 'flux job list all jobs works' '
365365 test_cmp all.ids list_all_jobids.out
366366'
367367
368+ # do some more advanced constraint queries
369+
370+ test_expect_success ' flux job list hostname jobs' '
371+ id=$(id -u) &&
372+ constraint="{ and: [ {userid:[${id}]}, {name:[\"hostname\"]}] }" &&
373+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
374+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_hostname_jobs.out &&
375+ numlines=$(cat pending.ids completed.ids | wc -l) &&
376+ test $(cat list_constraint_hostname_jobs.out | wc -l) -eq ${numlines}
377+ '
378+
379+ test_expect_success ' flux job list active hostname jobs' '
380+ id=$(id -u) &&
381+ constraint="{ and: [ {userid:[${id}]}, {states:[\"active\"]}, {name:[\"hostname\"]}] }" &&
382+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
383+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_pending_hostname.out &&
384+ test_cmp list_constraint_pending_hostname.out pending.ids
385+ '
386+
387+ test_expect_success ' flux job list inactive hostname jobs' '
388+ id=$(id -u) &&
389+ constraint="{ and: [ {userid:[${id}]}, {states:[\"inactive\"]}, {name:[\"hostname\"]}] }" &&
390+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
391+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_inactive_hostname.out &&
392+ test_cmp list_constraint_inactive_hostname.out completed.ids
393+ '
394+
395+ test_expect_success ' flux job list invalid queue' '
396+ id=$(id -u) &&
397+ constraint="{ and: [ {userid:[${id}]}, {queue:[\"blarg\"]}] }" &&
398+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
399+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_invalid_queue.out &&
400+ test $(cat list_constraint_invalid_queue.out | wc -l) -eq 0
401+ '
402+
403+ test_expect_success ' flux job list active (1)' '
404+ state1=`${JOB_CONV} strtostate SCHED` &&
405+ state2=`${JOB_CONV} strtostate RUN` &&
406+ constraint="{ or: [ {states:[${state1}]}, {states:[${state2}]} ] }" &&
407+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
408+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_active1.out &&
409+ numlines=$(cat active.ids | wc -l) &&
410+ test $(cat list_constraint_active1.out | wc -l) -eq ${numlines}
411+ '
412+
413+ test_expect_success ' flux job list active (2)' '
414+ state1=`${JOB_CONV} strtostate INACTIVE` &&
415+ constraint="{ not: [ {states:[${state1}]} ] }" &&
416+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
417+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_active2.out &&
418+ numlines=$(cat active.ids | wc -l) &&
419+ test $(cat list_constraint_active2.out | wc -l) -eq ${numlines}
420+ '
421+
422+ test_expect_success ' flux job list pending jobs or inactive jobs (1)' '
423+ state1=`${JOB_CONV} strtostate SCHED` &&
424+ state2=`${JOB_CONV} strtostate INACTIVE` &&
425+ constraint="{ or: [ {states:[${state1}]}, {states:[${state2}]} ] }" &&
426+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
427+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_pending_inactive1.out &&
428+ numlines=$(cat pending.ids inactive.ids | wc -l) &&
429+ test $(cat list_constraint_pending_inactive1.out | wc -l) -eq ${numlines}
430+ '
431+
432+ test_expect_success ' flux job list pending jobs or inactive jobs (2)' '
433+ state1=`${JOB_CONV} strtostate SCHED` &&
434+ state2=`${JOB_CONV} strtostate INACTIVE` &&
435+ constraint="{ or: [ {states:[${state1}, ${state2}]} ] }" &&
436+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
437+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_pending_inactive2.out &&
438+ numlines=$(cat pending.ids inactive.ids | wc -l) &&
439+ test $(cat list_constraint_pending_inactive2.out | wc -l) -eq ${numlines}
440+ '
441+
442+ test_expect_success ' flux job list failed and canceled jobs (1)' '
443+ result1=`${JOB_CONV} strtoresult FAILED` &&
444+ result2=`${JOB_CONV} strtoresult CANCELED` &&
445+ constraint="{ or: [ {results:[${result1}]}, {results:[${result2}]} ] }" &&
446+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
447+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_failed_canceled1.out &&
448+ numlines=$(cat canceled.ids failed.ids | wc -l) &&
449+ test $(cat list_constraint_failed_canceled1.out | wc -l) -eq ${numlines}
450+ '
451+
452+ test_expect_success ' flux job list failed and canceled jobs (2)' '
453+ result1=`${JOB_CONV} strtoresult FAILED` &&
454+ result2=`${JOB_CONV} strtoresult CANCELED` &&
455+ constraint="{ and: [ {userid:[${id}]}, {results:[${result1}, ${result2}]}] }" &&
456+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
457+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_failed_canceled2.out &&
458+ numlines=$(cat canceled.ids failed.ids | wc -l) &&
459+ test $(cat list_constraint_failed_canceled2.out | wc -l) -eq ${numlines}
460+ '
461+
462+ test_expect_success ' flux job list pending jobs or failed jobs (1)' '
463+ state1=`${JOB_CONV} strtostate SCHED` &&
464+ state2=`${JOB_CONV} strtostate INACTIVE` &&
465+ result1=`${JOB_CONV} strtoresult FAILED` &&
466+ constraint="{ or: [ {states:[${state1}]}, {and: [ {states:[${state2}]}, {results:[${result1}]} ] } ] }" &&
467+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
468+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_pending_failed1.out &&
469+ numlines=$(cat pending.ids failed.ids | wc -l) &&
470+ test $(cat list_constraint_pending_failed1.out | wc -l) -eq ${numlines}
471+ '
472+
473+ test_expect_success ' flux job list pending jobs or failed jobs (2)' '
474+ state1=`${JOB_CONV} strtostate SCHED` &&
475+ result1=`${JOB_CONV} strtoresult FAILED` &&
476+ constraint="{ or: [ {states:[${state1}]}, {results:[${result1}]} ] }" &&
477+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
478+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_pending_failed2.out &&
479+ numlines=$(cat pending.ids failed.ids | wc -l) &&
480+ test $(cat list_constraint_pending_failed2.out | wc -l) -eq ${numlines}
481+ '
482+
483+ test_expect_success ' flux job list inactive (1)' '
484+ state1=`${JOB_CONV} strtostate INACTIVE` &&
485+ constraint="{ or: [ {states:[${state1}]} ] }" &&
486+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
487+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_inactive1.out &&
488+ numlines=$(cat inactive.ids | wc -l) &&
489+ test $(cat list_constraint_inactive1.out | wc -l) -eq ${numlines}
490+ '
491+
492+ test_expect_success ' flux job list inactive (2)' '
493+ state1=`${JOB_CONV} strtostate SCHED` &&
494+ state2=`${JOB_CONV} strtostate RUN` &&
495+ constraint="{ not: [ { or: [ {states:[${state1}]}, {states:[${state2}]} ] } ] }" &&
496+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
497+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_inactive2.out &&
498+ numlines=$(cat inactive.ids | wc -l) &&
499+ test $(cat list_constraint_inactive2.out | wc -l) -eq ${numlines}
500+ '
501+
502+ # N.B. default is >= when no operator specified
503+ test_expect_success ' flux job list have run via t_run (1)' '
504+ constraint="{ or: [ {t_run:[0]} ] }" &&
505+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
506+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_run1.out &&
507+ numlines=$(cat running.ids failed.ids timeout.ids completed.ids | wc -l) &&
508+ test $(cat list_constraint_t_run1.out | wc -l) -eq ${numlines}
509+ '
510+
511+ # use a floating point in this one
512+ test_expect_success ' flux job list have run via t_run (2)' '
513+ constraint="{ or: [ {t_run:[1.0]} ] }" &&
514+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
515+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_run2.out &&
516+ numlines=$(cat running.ids failed.ids timeout.ids completed.ids | wc -l) &&
517+ test $(cat list_constraint_t_run2.out | wc -l) -eq ${numlines}
518+ '
519+
520+ test_expect_success ' flux job list have run via t_run (3)' '
521+ constraint="{ or: [ {t_run:[\"1.1\"]} ] }" &&
522+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
523+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_run3.out &&
524+ numlines=$(cat running.ids failed.ids timeout.ids completed.ids | wc -l) &&
525+ test $(cat list_constraint_t_run3.out | wc -l) -eq ${numlines}
526+ '
527+
528+ test_expect_success ' flux job list have run via t_run (4)' '
529+ constraint="{ or: [ {t_run:[\">1.2\"]} ] }" &&
530+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
531+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_run4.out &&
532+ numlines=$(cat running.ids failed.ids timeout.ids completed.ids | wc -l) &&
533+ test $(cat list_constraint_t_run4.out | wc -l) -eq ${numlines}
534+ '
535+
536+ # N.B. default is >= when no operator specified
537+ test_expect_success ' flux job list inactive via t_inactive (1)' '
538+ constraint="{ or: [ {t_inactive:[0]} ] }" &&
539+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
540+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_inactive1.out &&
541+ numlines=$(cat inactive.ids | wc -l) &&
542+ test $(cat list_constraint_t_inactive1.out | wc -l) -eq ${numlines}
543+ '
544+
545+ # use a floating point in this one
546+ test_expect_success ' flux job list inactive via t_inactive (2)' '
547+ constraint="{ or: [ {t_inactive:[1.0]} ] }" &&
548+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
549+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_inactive2.out &&
550+ numlines=$(cat inactive.ids | wc -l) &&
551+ test $(cat list_constraint_t_inactive2.out | wc -l) -eq ${numlines}
552+ '
553+
554+ test_expect_success ' flux job list inactive via t_inactive (3)' '
555+ constraint="{ or: [ {t_inactive:[\"1.1\"]} ] }" &&
556+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
557+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_inactive3.out &&
558+ numlines=$(cat inactive.ids | wc -l) &&
559+ test $(cat list_constraint_t_inactive3.out | wc -l) -eq ${numlines}
560+ '
561+
562+ test_expect_success ' flux job list inactive via t_inactive (4)' '
563+ constraint="{ or: [ {t_inactive:[\">1.2\"]} ] }" &&
564+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
565+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_t_inactive4.out &&
566+ numlines=$(cat inactive.ids | wc -l) &&
567+ test $(cat list_constraint_t_inactive4.out | wc -l) -eq ${numlines}
568+ '
569+
570+ test_expect_success ' flux job list none via t_inactive (1)' '
571+ constraint="{ or: [ {t_inactive:[\"<0\"]} ] }" &&
572+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
573+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_none1.out &&
574+ test $(cat list_constraint_none1.out | wc -l) -eq 0
575+ '
576+
577+ test_expect_success ' flux job list none via t_inactive (2)' '
578+ constraint="{ or: [ {t_inactive:[\"<=0\"]} ] }" &&
579+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
580+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_none1.out &&
581+ test $(cat list_constraint_none1.out | wc -l) -eq 0
582+ '
583+
584+ # N.B. default is >= when no operator specified
585+ test_expect_success ' flux job list all via t_depend (1)' '
586+ constraint="{ or: [ {t_depend:[0]} ] }" &&
587+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
588+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_all1.out &&
589+ numlines=$(cat all.ids | wc -l) &&
590+ test $(cat list_constraint_all1.out | wc -l) -eq ${numlines}
591+ '
592+
593+ # use a floating point in this one
594+ test_expect_success ' flux job list all via t_depend (2)' '
595+ constraint="{ or: [ {t_depend:[1.0]} ] }" &&
596+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
597+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_all2.out &&
598+ numlines=$(cat all.ids | wc -l) &&
599+ test $(cat list_constraint_all2.out | wc -l) -eq ${numlines}
600+ '
601+
602+ test_expect_success ' flux job list all via t_depend (3)' '
603+ constraint="{ or: [ {t_depend:[\"1.1\"]} ] }" &&
604+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
605+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_all3.out &&
606+ numlines=$(cat all.ids | wc -l) &&
607+ test $(cat list_constraint_all3.out | wc -l) -eq ${numlines}
608+ '
609+
610+ test_expect_success ' flux job list all via t_depend (4)' '
611+ constraint="{ or: [ {t_depend:[\">1.2\"]} ] }" &&
612+ $jq -j -c -n "{max_entries:1000, attrs:[], constraint:${constraint}}" \
613+ | $RPC job-list.list | $jq .jobs | $jq -c ' .[]' | $jq .id > list_constraint_all4.out &&
614+ numlines=$(cat all.ids | wc -l) &&
615+ test $(cat list_constraint_all4.out | wc -l) -eq ${numlines}
616+ '
617+
368618# with single anonymous queue, queues arrays should be zero length
369619test_expect_success ' job stats lists jobs in correct state (mix)' '
370620 flux job stats | jq -e ".job_states.depend == 0" &&
0 commit comments