@@ -22,6 +22,7 @@ import nextflow.executor.ExecutorConfig
22
22
import nextflow.util.Duration
23
23
import nextflow.util.RateUnit
24
24
import spock.lang.Specification
25
+ import spock.lang.Unroll
25
26
/**
26
27
*
27
28
* @author Paolo Di Tommaso <[email protected] >
@@ -150,4 +151,76 @@ class TaskPollingMonitorTest extends Specification {
150
151
3 * session. notifyTaskSubmit(handler)
151
152
}
152
153
154
+ @Unroll
155
+ def ' should throw error if job array size exceeds queue size [capacity: #CAPACITY, array: #ARRAY_SIZE]' () {
156
+ given :
157
+ def session = Mock (Session )
158
+ def monitor = Spy (new TaskPollingMonitor (name : ' foo' , session : session, capacity : CAPACITY , pollInterval : Duration . of(' 1min' )))
159
+ and :
160
+ def processor = Mock (TaskProcessor )
161
+ def arrayHandler = Mock (TaskHandler ) {
162
+ getTask() >> Mock (TaskArrayRun ) {
163
+ getName() >> TASK_NAME
164
+ getArraySize() >> ARRAY_SIZE
165
+ getProcessor() >> processor
166
+ }
167
+ }
168
+
169
+ when :
170
+ monitor. canSubmit(arrayHandler)
171
+ then :
172
+ def e = thrown(IllegalArgumentException )
173
+ e. message. contains(" Process '$TASK_NAME ' declares array size ($ARRAY_SIZE ) which exceeds the executor queue size ($CAPACITY )" )
174
+
175
+ where :
176
+ CAPACITY | ARRAY_SIZE | TASK_NAME
177
+ 10 | 15 | ' test_array'
178
+ 5 | 10 | ' large_array'
179
+ 1 | 2 | ' small_array'
180
+ }
181
+
182
+ @Unroll
183
+ def ' should validate array size accounting in queue capacity [capacity: #CAPACITY, running: #RUNNING_COUNT, array: #ARRAY_SIZE]' () {
184
+ given :
185
+ def session = Mock (Session )
186
+ def monitor = Spy (new TaskPollingMonitor (name : ' foo' , session : session, capacity : CAPACITY , pollInterval : Duration . of(' 1min' )))
187
+ and :
188
+ def processor = Mock (TaskProcessor )
189
+ def regularHandler = Mock (TaskHandler ) {
190
+ getTask() >> Mock (TaskRun ) {
191
+ getProcessor() >> processor
192
+ }
193
+ canForkProcess() >> CAN_FORK
194
+ isReady() >> IS_READY
195
+ }
196
+ def arrayHandler = Mock (TaskHandler ) {
197
+ getTask() >> Mock (TaskArrayRun ) {
198
+ getArraySize() >> ARRAY_SIZE
199
+ getProcessor() >> processor
200
+ }
201
+ canForkProcess() >> CAN_FORK
202
+ isReady() >> IS_READY
203
+ }
204
+
205
+ and :
206
+ RUNNING_COUNT . times { monitor. runningQueue. add(regularHandler) }
207
+
208
+ expect :
209
+ monitor. runningQueue. size() == RUNNING_COUNT
210
+ monitor. canSubmit(regularHandler) == REGULAR_EXPECTED
211
+ monitor. canSubmit(arrayHandler) == ARRAY_EXPECTED
212
+
213
+ where :
214
+ CAPACITY | RUNNING_COUNT | ARRAY_SIZE | CAN_FORK | IS_READY | REGULAR_EXPECTED | ARRAY_EXPECTED
215
+ 10 | 6 | 5 | true | true | true | false // Array too big (6+5>10)
216
+ 10 | 5 | 5 | true | true | true | true // Array fits exactly (5+5=10)
217
+ 10 | 9 | 1 | true | true | true | true // Both fit (9+1=10)
218
+ 10 | 10 | 1 | true | true | false | false // Queue full (10+1>10)
219
+ 5 | 4 | 1 | true | true | true | true // Both fit (4+1=5)
220
+ 5 | 4 | 2 | true | true | true | false // Array too big (4+2>5)
221
+ 0 | 5 | 10 | true | true | true | true // Unlimited capacity
222
+ 10 | 5 | 3 | false | true | false | false // Cannot fork
223
+ 10 | 5 | 3 | true | false | false | false // Not ready
224
+ }
225
+
153
226
}
0 commit comments