@@ -58,6 +58,7 @@ import software.amazon.awssdk.services.batch.model.ResourceType
58
58
import software.amazon.awssdk.services.batch.model.RetryStrategy
59
59
import software.amazon.awssdk.services.batch.model.SubmitJobRequest
60
60
import software.amazon.awssdk.services.batch.model.SubmitJobResponse
61
+ import spock.lang.See
61
62
import spock.lang.Specification
62
63
import spock.lang.Unroll
63
64
/**
@@ -1282,14 +1283,117 @@ class AwsBatchTaskHandlerTest extends Specification {
1282
1283
1 * handler. getEnvironmentVars() >> []
1283
1284
1284
1285
and :
1285
- def tags = req. getTags ()
1286
+ def tags = req. tags ()
1286
1287
tags. size() == 3
1287
1288
tags[' validLabel' ] == ' validValue'
1288
1289
tags[' invalid_key' ] == ' invalid_value'
1289
1290
// Check that long value was truncated
1290
1291
tags[' long-key-that-might-be-truncated-if-very-very-long' ]. length() <= 256
1291
1292
tags[' long-key-that-might-be-truncated-if-very-very-long' ]. startsWith(' long-value-that-should-be-truncated' )
1292
1293
! tags[' long-key-that-might-be-truncated-if-very-very-long' ]. endsWith(' _' )
1293
- req. getPropagateTags() == true
1294
+ req. propagateTags() == true
1295
+ }
1296
+
1297
+ @Unroll
1298
+ @See (" https://github.com/nextflow-io/nextflow/pull/6211#discussion_r2161928856" )
1299
+ def ' should handle null values in labels with explicit logging' () {
1300
+ given :
1301
+ def handler = Spy (AwsBatchTaskHandler )
1302
+
1303
+ expect :
1304
+ handler. sanitizeAwsBatchLabels(INPUT ) == EXPECTED
1305
+
1306
+ where :
1307
+ INPUT | EXPECTED
1308
+ // Basic null value case - this addresses the PR comment: "when the item is "item": null is the aws tag silently dropped?"
1309
+ [' item' : null , ' validKey' : ' validValue' ] | [' validKey' : ' validValue' ]
1310
+
1311
+ // Multiple null values
1312
+ [' key1' : null , ' key2' : ' value2' , ' key3' : null ] | [' key2' : ' value2' ]
1313
+
1314
+ // All null values
1315
+ [' key1' : null , ' key2' : null ] | [:]
1316
+
1317
+ // Mix of null and empty string (which becomes null after sanitization)
1318
+ [' nullValue' : null , ' emptyValue' : ' ' , ' validValue' : ' good' ] | [' validValue' : ' good' ]
1319
+ }
1320
+
1321
+ @See (" https://github.com/nextflow-io/nextflow/pull/6211#discussion_r2161928856" )
1322
+ def ' should handle null keys in labels with explicit logging' () {
1323
+ given :
1324
+ def handler = Spy (AwsBatchTaskHandler )
1325
+
1326
+ when : ' creating map with actual null key'
1327
+ def labels = new HashMap<String , String > ()
1328
+ labels. put(null , ' validValue' )
1329
+ labels. put(' validKey' , ' validValue' )
1330
+ def result = handler. sanitizeAwsBatchLabels(labels)
1331
+
1332
+ then : ' null key is dropped'
1333
+ result. size() == 1
1334
+ result[' validKey' ] == ' validValue'
1335
+ ! result. containsKey(null )
1336
+ }
1337
+
1338
+ @See (" https://github.com/nextflow-io/nextflow/pull/6211#discussion_r2161928856" )
1339
+ def ' should handle both null keys and values' () {
1340
+ given :
1341
+ def handler = Spy (AwsBatchTaskHandler )
1342
+
1343
+ when : ' creating map with null key and null values'
1344
+ def labels = new HashMap<String , String > ()
1345
+ labels. put(null , ' someValue' ) // null key
1346
+ labels. put(' nullValue' , null ) // null value
1347
+ labels. put(null , null ) // both null (overwrites previous null key)
1348
+ labels. put(' validKey' , ' validValue' )
1349
+ def result = handler. sanitizeAwsBatchLabels(labels)
1350
+
1351
+ then : ' only valid entry remains'
1352
+ result. size() == 1
1353
+ result[' validKey' ] == ' validValue'
1354
+ ! result. containsKey(null )
1355
+ ! result. containsKey(' nullValue' )
1356
+ }
1357
+
1358
+ @See (" https://github.com/nextflow-io/nextflow/pull/6211#discussion_r2161928856" )
1359
+ def ' should verify logging behavior for null handling' () {
1360
+ given :
1361
+ def handler = new AwsBatchTaskHandler ()
1362
+ def logAppender = Mock (ch.qos.logback.core.Appender )
1363
+ def logger = (ch.qos.logback.classic.Logger ) org.slf4j.LoggerFactory . getLogger(AwsBatchTaskHandler )
1364
+ logger. addAppender(logAppender)
1365
+ logger. setLevel(ch.qos.logback.classic.Level . WARN )
1366
+
1367
+ when : ' sanitizing labels with null values'
1368
+ def labels = [' item' : null , ' validKey' : ' validValue' ] // This is the exact case from PR comment
1369
+ handler. sanitizeAwsBatchLabels(labels)
1370
+
1371
+ then : ' warning is logged for null value'
1372
+ 1 * logAppender. doAppend(_) >> { args ->
1373
+ def event = args[0 ] as ch.qos.logback.classic.spi.ILoggingEvent
1374
+ assert event. level == ch.qos.logback.classic.Level . WARN
1375
+ assert event. formattedMessage. contains(' AWS Batch label dropped due to null value: key=item, value=null' )
1376
+ }
1377
+
1378
+ cleanup :
1379
+ logger. detachAppender(logAppender)
1380
+ }
1381
+
1382
+ @See (" https://github.com/nextflow-io/nextflow/pull/6211#discussion_r2161928856" )
1383
+ def ' should verify no silent dropping - PR comment verification' () {
1384
+ given : ' This test specifically addresses the PR comment about silent dropping'
1385
+ def handler = Spy (AwsBatchTaskHandler )
1386
+
1387
+ when : ' processing the exact scenario from PR comment'
1388
+ def labels = [' item' : null ] // "when the item is "item": null is the aws tag silently dropped?"
1389
+ def result = handler. sanitizeAwsBatchLabels(labels)
1390
+
1391
+ then : ' result is empty (tag is dropped)'
1392
+ result == [:]
1393
+
1394
+ and : ' the method properly logs the dropped label (verified by observing the actual log output in test execution)'
1395
+ // The actual logging is verified by the "should verify logging behavior for null handling" test above
1396
+ // This test focuses on the functional behavior: null values are correctly dropped from the result
1397
+ true // The key point is that silent dropping has been replaced with logged dropping
1294
1398
}
1295
1399
}
0 commit comments