Fortran · 6971 bytes Raw Blame History
1 program test_devloop_jobs
2 use fgof_devloop, only : &
3 FGOF_DEVLOOP_JOB_ACTION_NONE, &
4 FGOF_DEVLOOP_JOB_ACTION_RESTART, &
5 FGOF_DEVLOOP_JOB_ACTION_START, &
6 attach_devloop_job, &
7 attach_devloop_pipeline_members, &
8 devloop_change_trigger, &
9 devloop_job_restart_plan, &
10 devloop_manual_trigger, &
11 devloop_service_job, &
12 job_continue_result, &
13 job_exit_result, &
14 job_stop_result, &
15 observe_devloop_job, &
16 release_devloop_job
17 use fgof_devloop_types, only : &
18 devloop_job_plan, &
19 devloop_job_spec, &
20 devloop_job_state
21 use fgof_jobs, only : &
22 FGOF_JOBS_SIGNAL_SCOPE_GROUP, &
23 FGOF_JOBS_TERMINAL_HANDOFF_ALWAYS, &
24 FGOF_JOBS_TERMINAL_HANDOFF_NEVER
25 implicit none
26
27 call test_service_restart_plan()
28 call test_terminal_handoff_plan()
29 call test_pipeline_wait_observation()
30
31 contains
32
33 subroutine test_service_restart_plan()
34 type(devloop_job_spec) :: spec
35 type(devloop_job_state) :: job
36 type(devloop_job_plan) :: plan
37
38 spec = devloop_service_job("serve", label="local service", &
39 terminal_handoff=FGOF_JOBS_TERMINAL_HANDOFF_NEVER)
40 job = attach_devloop_job(spec, pid=501, process_group=501)
41
42 if (.not. job%configured) error stop "attached devloop job should be configured"
43 if (.not. job%attached) error stop "attached devloop job should record attachment"
44 if (.not. job%running) error stop "attached devloop job should be running"
45 if (.not. job%cleanup_needed) error stop "owned devloop job should need cleanup"
46 if (.not. job%owns_process_group) error stop "service job should own its process group"
47 if (job%terminal_handoff_required) error stop "never-handoff service should not require terminal handoff"
48 if (job%label /= "local service") error stop "job label should be preserved"
49
50 plan = devloop_job_restart_plan(job, devloop_change_trigger(1, "source changed"))
51 if (plan%action /= FGOF_DEVLOOP_JOB_ACTION_RESTART) error stop "running job should restart on changes"
52 if (.not. plan%should_restart) error stop "restart plan should mark restart"
53 if (.not. plan%should_stop) error stop "restart plan should stop existing job"
54 if (.not. plan%should_start) error stop "restart plan should start replacement job"
55 if (.not. plan%cleanup_needed) error stop "restart plan should expose cleanup need"
56 if (plan%pid /= 501) error stop "restart plan should preserve pid"
57 if (plan%process_group /= 501) error stop "restart plan should preserve process group"
58 if (plan%signal_scope /= FGOF_JOBS_SIGNAL_SCOPE_GROUP) error stop "restart plan should preserve signal scope"
59
60 call release_devloop_job(job)
61 if (.not. job%released) error stop "release should mark devloop job released"
62 if (job%cleanup_needed) error stop "release should clear cleanup obligations"
63 if (.not. job%running) error stop "release should not alter runtime state"
64
65 plan = devloop_job_restart_plan(job, devloop_change_trigger(1, "source changed"))
66 if (plan%action /= FGOF_DEVLOOP_JOB_ACTION_NONE) error stop "released job should not plan action"
67 if (plan%should_stop) error stop "released job should not stop"
68 if (plan%should_start) error stop "released job should not start"
69 if (plan%should_restart) error stop "released job should not restart"
70 if (plan%reason /= "job released") error stop "released job reason should be explicit"
71 end subroutine test_service_restart_plan
72
73 subroutine test_terminal_handoff_plan()
74 type(devloop_job_spec) :: spec
75 type(devloop_job_state) :: job
76 type(devloop_job_plan) :: plan
77
78 spec = devloop_service_job("foreground", background=.false., &
79 terminal_handoff=FGOF_JOBS_TERMINAL_HANDOFF_ALWAYS, &
80 release_on_handoff=.true.)
81 job = attach_devloop_job(spec, pid=601, process_group=601)
82 plan = devloop_job_restart_plan(job, devloop_manual_trigger("handoff"))
83
84 if (.not. plan%terminal_handoff_required) error stop "foreground jobs should surface terminal handoff"
85 if (.not. plan%should_release) error stop "release-on-handoff should be explicit"
86 if (plan%action /= FGOF_DEVLOOP_JOB_ACTION_NONE) error stop "release-on-handoff should not restart"
87 if (plan%should_stop) error stop "release-on-handoff should not stop the job"
88 if (plan%should_start) error stop "release-on-handoff should not start a replacement"
89 if (plan%should_restart) error stop "release-on-handoff should not request restart"
90 if (plan%reason /= "release for terminal handoff") then
91 error stop "release-on-handoff reason should be explicit"
92 end if
93 end subroutine test_terminal_handoff_plan
94
95 subroutine test_pipeline_wait_observation()
96 type(devloop_job_spec) :: spec
97 type(devloop_job_state) :: job
98 type(devloop_job_plan) :: plan
99
100 spec = devloop_service_job("pipeline-head")
101 job = attach_devloop_job(spec, pid=701, process_group=701)
102 call attach_devloop_pipeline_members(job, [701, 702, 703])
103
104 call observe_devloop_job(job, job_exit_result(0, pid=701, process_group=701))
105 if (job%finished) error stop "one finished pipeline member should not finish the service"
106 if (.not. job%handle%members(1)%finished) error stop "first pipeline member should finish"
107 if (job%handle%members(2)%finished) error stop "untouched pipeline member should stay live"
108
109 call observe_devloop_job(job, job_stop_result(20, pid=702, process_group=701))
110 if (.not. job%handle%members(1)%finished) error stop "group stop should preserve finished member"
111 if (job%handle%members(1)%stopped) error stop "group stop should not stop finished member"
112 if (.not. job%handle%members(2)%stopped) error stop "group stop should stop live member"
113 if (.not. job%stopped) error stop "group stop should mark service stopped"
114
115 call observe_devloop_job(job, job_continue_result(pid=701, process_group=701))
116 if (job%handle%members(1)%running) error stop "group continue should not restart finished member"
117 if (.not. job%handle%members(2)%running) error stop "group continue should resume live member"
118 if (.not. job%running) error stop "continued pipeline should run"
119
120 call observe_devloop_job(job, job_exit_result(0, pid=702, process_group=701))
121 call observe_devloop_job(job, job_exit_result(0, pid=703, process_group=701))
122 if (.not. job%finished) error stop "all terminal members should finish service"
123 if (job%cleanup_needed) error stop "finished service should not need cleanup"
124
125 plan = devloop_job_restart_plan(job, devloop_change_trigger(2, "restart finished"))
126 if (plan%action /= FGOF_DEVLOOP_JOB_ACTION_START) error stop "finished service should start fresh"
127 if (.not. plan%should_start) error stop "finished service restart should start"
128 if (plan%should_stop) error stop "finished service restart should not stop old job"
129 end subroutine test_pipeline_wait_observation
130
131 end program test_devloop_jobs
132