← Feature overview

VICARIO test procedures

full tier · 2026-10-24 11:56 UTC · commit cc8509d · failed

Every test in the suite, grouped by feature: what it does, what makes it pass, the kinds of testing it covers, and its latest result. Each test links to its run details (commands, logs, image previews) and to its source on GitHub.

Scope of testing

Each test carries one or more scope tags. Click a tag to show only those tests.

Features

VICAR image read/write

Reading and writing VICAR images in every data type (BYTE, HALF, FULL, REAL, DOUB) and organization (BSQ, BIL, BIP), in both byte orders, including degenerate shapes and damaged files.

35 tests · nominal29 off-nominal3 malformed-input1 lossless18 regression1 legacy3 suite1 unit1

  1. byte: BSQ, BIL and BIP decode to the same pixelsPassed
    nominal

    Decodes the synthetic BYTE image written in each band organization (BSQ, BIL, BIP). Passes when all three decode to the same 48 x 64 x 3 BYTE image (identical pixel hashes).

  2. byte/bsq: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic BYTE BSQ image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='BYTE' and the output pixels are identical to the input.

  3. byte/bil: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic BYTE BIL image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='BYTE' and the output pixels are identical to the input.

  4. byte/bip: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic BYTE BIP image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='BYTE' and the output pixels are identical to the input.

  5. half: BSQ, BIL and BIP decode to the same pixelsPassed
    nominal

    Decodes the synthetic HALF image written in each band organization (BSQ, BIL, BIP). Passes when all three decode to the same 48 x 64 x 3 SHORT image (identical pixel hashes).

  6. half/bsq: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic HALF BSQ image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='HALF' and the output pixels are identical to the input.

  7. half/bil: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic HALF BIL image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='HALF' and the output pixels are identical to the input.

  8. half/bip: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic HALF BIP image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='HALF' and the output pixels are identical to the input.

  9. full: BSQ, BIL and BIP decode to the same pixelsPassed
    nominal

    Decodes the synthetic FULL image written in each band organization (BSQ, BIL, BIP). Passes when all three decode to the same 48 x 64 x 3 INT image (identical pixel hashes).

  10. full/bsq: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic FULL BSQ image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='FULL' and the output pixels are identical to the input.

  11. full/bil: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic FULL BIL image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='FULL' and the output pixels are identical to the input.

  12. full/bip: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic FULL BIP image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='FULL' and the output pixels are identical to the input.

  13. real: BSQ, BIL and BIP decode to the same pixelsPassed
    nominal

    Decodes the synthetic REAL image written in each band organization (BSQ, BIL, BIP). Passes when all three decode to the same 48 x 64 x 3 FLOAT image (identical pixel hashes).

  14. real/bsq: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic REAL BSQ image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='REAL' and the output pixels are identical to the input.

  15. real/bil: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic REAL BIL image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='REAL' and the output pixels are identical to the input.

  16. real/bip: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic REAL BIP image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='REAL' and the output pixels are identical to the input.

  17. doub: BSQ, BIL and BIP decode to the same pixelsPassed
    nominal

    Decodes the synthetic DOUB image written in each band organization (BSQ, BIL, BIP). Passes when all three decode to the same 48 x 64 x 3 DOUBLE image (identical pixel hashes).

  18. doub/bsq: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic DOUB BSQ image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='DOUB' and the output pixels are identical to the input.

  19. doub/bil: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic DOUB BIL image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='DOUB' and the output pixels are identical to the input.

  20. doub/bip: VICAR to VICAR round trip keeps type and pixelsPassed
    nominallossless

    Converts the synthetic DOUB BIP image to VICAR with jConvertIIO. Passes when the output label keeps FORMAT='DOUB' and the output pixels are identical to the input.

  21. degenerate shape gen_byte_ns1_nl1024.vic survives VICAR and PDS round tripsPassed
    legacyoff-nominallossless

    Legacy shapes from tstjConvertIIO.csh (1 x 1024, 1024 x 1, REAL 100 x 100): converts gen_byte_ns1_nl1024.vic to VICAR and to PDS3. Passes when both outputs decode to exactly the input pixels.

  22. degenerate shape gen_byte_ns1024_nl1.vic survives VICAR and PDS round tripsPassed
    legacyoff-nominallossless

    Legacy shapes from tstjConvertIIO.csh (1 x 1024, 1024 x 1, REAL 100 x 100): converts gen_byte_ns1024_nl1.vic to VICAR and to PDS3. Passes when both outputs decode to exactly the input pixels.

  23. degenerate shape gen_real_100x100.vic survives VICAR and PDS round tripsPassed
    legacyoff-nominallossless

    Legacy shapes from tstjConvertIIO.csh (1 x 1024, 1024 x 1, REAL 100 x 100): converts gen_real_100x100.vic to VICAR and to PDS3. Passes when both outputs decode to exactly the input pixels.

  24. jConvertIIO decodes little-endian int16 (INTFMT/REALFMT LOW)Passed
    nominal

    Converts the GDAL int16 fixture, written on a little-endian machine (INTFMT/REALFMT = LOW), to TIFF. Passes when the values read back are the ones stored in the file (1 to 24), so the bytes were swapped correctly.

  25. jConvertIIO decodes little-endian float32-bsq (INTFMT/REALFMT LOW)Passed
    nominal

    Converts the GDAL float32-bsq fixture, written on a little-endian machine (INTFMT/REALFMT = LOW), to TIFF. Passes when the values read back are the ones stored in the file (1 to 122.5), so the bytes were swapped correctly.

  26. little-endian float32 BSQ, BIL and BIP agree after conversionPassed
    nominal

    Converts the GDAL little-endian float32 fixtures in BSQ, BIL and BIP order to TIFF. Passes when the three TIFFs have identical pixels.

  27. ImageIO API decodes little-endian HALF the same as BYTE 1..24Failed
    nominal

    Reads the GDAL little-endian HALF fixture (values 1 to 24) through the Java ImageIO API rather than jConvertIIO, and compares it with the BYTE fixture holding the same values. Passes when the pixel hashes match.

    Needs review (bug or intended?): REVIEW-1: VicarImageReader via the ImageIO API returns byte-swapped samples for INTFMT=LOW files (256, 512, ... instead of 1, 2, ...); jConvertIIO output is correct

  28. reads bigendian-int16 (system label with DAT_TIM/BINC)Failed
    nominal

    Reads the GDAL bigendian-int16 fixture, whose system label has DAT_TIM and BINC items written by GDAL. Passes when the file decodes.

    Needs review (bug or intended?): REVIEW-2: VICAR reader rejects GDAL-written system labels: "DAT_TIM may only go in history label"

  29. reads bigendian-float32 (system label with DAT_TIM/BINC)Failed
    nominal

    Reads the GDAL bigendian-float32 fixture, whose system label has DAT_TIM and BINC items written by GDAL. Passes when the file decodes.

    Needs review (bug or intended?): REVIEW-2: VICAR reader rejects GDAL-written system labels: "DAT_TIM may only go in history label"

  30. reads vax-float32 (system label with DAT_TIM/BINC)Failed
    nominal

    Reads the GDAL vax-float32 fixture, whose system label has DAT_TIM and BINC items written by GDAL. Passes when the file decodes.

    Needs review (bug or intended?): REVIEW-2: VICAR reader rejects GDAL-written system labels: "DAT_TIM may only go in history label"

  31. jConvertIIO decodes little-endian DOUB (float64) and FULL (int32) fixturesPassed
    nominal

    Converts the GDAL little-endian DOUB (float64) and FULL (int32) fixtures to VICAR. Passes when each output holds the stored values 1 to 24.

  32. binary line prefix fixture decodes to its 1x1 imagePassed
    nominal

    Reads the GDAL fixture whose image line carries a binary prefix. Passes when it decodes to its 1 x 1 BYTE image (the prefix is not part of the image).

  33. truncated VICAR file fails with a non-zero exitPassed
    malformed-inputregression

    Converts a truncated VICAR file (the label promises more data than the file holds). Passes when jConvertIIO exits non-zero and writes no output.

    Issue IDS-8497: fixed: jConvertIIO used to exit 0 after a read failure

  34. testPassed
    unitUnit tests (JUnit): VicarLabelTest

    Imports the result of the JUnit test VicarLabelTest.test from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  35. class is listed under a feature in features.ymlPassed
    suiteUnit tests (JUnit): VicarLabelTest

    Bookkeeping, not a product test: checks that the JUnit class jpl.mipl.io.vicar.VicarLabelTest is listed in a feature's junit: list in features.yml, so its results are grouped under that feature.

VICAR binary headers and prefixes

Images with binary label headers and per-line prefixes (NLB/NBB): decoding them, and keeping the prefix bytes when converting to VICAR or PDS (KEEP_LINE_PREFIX, ADD_BINARY_HEADER).

4 tests · lossless2 mission-data4

  1. Cassini ISS image (NLB=1, NBB=24) decodes identically with RI=truePassed
    mission-datalossless

    Reads a public Cassini ISS image with a binary label header (NLB=1) and a 24-byte prefix on every line (NBB=24), then converts it to VICAR with RI=true (read as a RenderedImage). Passes when the pixels match the recorded golden hash and the output has the same pixels.

  2. KEEP_LINE_PREFIX=true carries the prefixes into PDS outputPassed
    mission-datalossless

    Converts the Cassini ISS image to PDS3 with KEEP_LINE_PREFIX=true. Passes when the label declares LINE_PREFIX_BYTES = 24, the first 8 line prefixes are byte for byte those of the input, and the pixels are unchanged.

  3. KEEP_LINE_PREFIX=true carries the prefixes into VICAR outputFailed
    mission-data

    Converts the Cassini ISS image to VICAR with KEEP_LINE_PREFIX=true. Passes when the output label has NBB=24 and the first 8 line prefixes match the input.

    Needs review (bug or intended?): REVIEW-13: VICAR output drops the line prefixes (NBB=0) even with KEEP_LINE_PREFIX=true

  4. ADD_BINARY_HEADER=true writes the binary header to VICAR outputFailed
    mission-data

    Converts the Cassini ISS image to VICAR with ADD_BINARY_HEADER=true. Passes when the output label has NLB=1, showing the binary header was written.

    Needs review (bug or intended?): REVIEW-13: VICAR output has no binary header (NLB=0) even with ADD_BINARY_HEADER=true

PDS3 products

Reading PDS3 products (attached and detached labels, dual PDS3/VICAR labels) and writing PDS3 with an embedded VICAR label, file name in the label, or ODL3 labels.

16 tests · nominal4 lossless5 mission-data7 regression1 legacy1 suite1 unit4

  1. VICAR to PDS3 writes a valid label and keeps pixelsPassed
    nominallossless

    Converts the synthetic 3-band BYTE image to PDS3. Passes when the label is valid (PDS3 version, ^IMAGE pointer, an IMAGE object with the right LINES, LINE_SAMPLES and BANDS, no empty "" values) and the pixels are unchanged.

  2. EMBED_VICAR_LABEL=true embeds the VICAR labelPassed
    nominallossless

    Converts the synthetic image to PDS3 with EMBED_VICAR_LABEL=true. Passes when the PDS3 label is valid, the VICAR label (LBLSIZE=) is embedded in the file, and the pixels are unchanged.

  3. PDS_FILENAME_IN_LABEL=true puts the output file name in the labelFailed
    nominal

    Converts the synthetic image to PDS3 with PDS_FILENAME_IN_LABEL=true. Passes when the output file name appears in the label.

    Needs review (bug or intended?): REVIEW-9: the documented keyword PDS_FILENAME_IN_LABEL is parsed as PDS_FILENAME, so it is ignored

  4. PDS_LABEL_TYPE=ODL3 writes an ODL3 labelPassed
    nominal

    Converts the synthetic image to PDS3 with PDS_LABEL_TYPE=ODL3. Passes when the label starts with ODL_VERSION_ID = ODL3 and is otherwise valid.

  5. reads an MSL Navcam EDR thumbnail (attached PDS3 + VICAR labels)Passed
    mission-datalossless

    Reads a public MSL Navcam EDR thumbnail, which carries both a PDS3 and a VICAR label, and converts it to VICAR. Passes when the pixels match the recorded golden hash and the VICAR output has the same pixels.

  6. reads an MSL Navcam EDR through its detached .LBLFailed
    mission-data

    Converts the same MSL thumbnail by giving jConvertIIO its detached .LBL label instead of the image file. Passes when the conversion succeeds.

    Needs review (bug or intended?): REVIEW-7: PDSImageReader fails on the detached MSL label: "Error reading header: Negative size"

  7. PDS-labelled input to FORMAT=pds with the default stylesheetPassed
    mission-dataregression

    Converts a PDS-labelled MSL image to PDS3 (FORMAT=pds) without a stylesheet, so the default PDS-to-PDS stylesheet is used. Passes when the conversion succeeds with a non-empty output; before the IDS-8497 fix it crashed and left an empty file.

    Issue IDS-8497: fixed: the default PDS-to-PDS stylesheet name was empty (NullPointerException, empty .pds)

  8. PDS-labelled input to FORMAT=pds with an explicit copy stylesheetPassed
    mission-datalossless

    Same conversion with XSL=CopyEverything.xsl given explicitly. Passes when the output label has an ^IMAGE pointer and the pixels are unchanged.

    Issue IDS-8497: an explicit copy stylesheet gives the same result as the default

  9. MSL Navcam full EDR reads and round-trips through VICARPassed
    mission-datalosslessPDS3 products (full-size products)

    Reads a full-size public MSL Navcam EDR and converts it to VICAR. Passes when the pixels match the recorded golden hash and the VICAR output has the same pixels.

  10. MER Opportunity Navcam EDR reads (stand-in for the legacy mer_file.vic)Passed
    mission-datalegacyPDS3 products (full-size products)

    Reads a public MER Opportunity Navcam EDR, the public stand-in for the internal mer_file.vic of the legacy test. Passes when the pixels match the recorded golden hash.

  11. Cassini ISS: VICAR image and its detached PDS3 label decode identicallyPassed
    mission-dataPDS3 products (full-size products)

    Reads a public Cassini ISS image directly and through its detached PDS3 label (.lbl, whose ^IMAGE points at the image). Passes when both match the recorded golden hash.

  12. noImageObjectProducesEmptySystemLabelPassed
    unitUnit tests (JUnit): PDS3ObjectNameTest

    Imports the result of the JUnit test PDS3ObjectNameTest.noImageObjectProducesEmptySystemLabel from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  13. readsRflImageWithExplicitParamPassed
    unitUnit tests (JUnit): PDS3ObjectNameTest

    Imports the result of the JUnit test PDS3ObjectNameTest.readsRflImageWithExplicitParam from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  14. readsRflImageViaHeuristicWhenParamUnsetPassed
    unitUnit tests (JUnit): PDS3ObjectNameTest

    Imports the result of the JUnit test PDS3ObjectNameTest.readsRflImageViaHeuristicWhenParamUnset from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  15. readsStandardImageObjectPassed
    unitUnit tests (JUnit): PDS3ObjectNameTest

    Imports the result of the JUnit test PDS3ObjectNameTest.readsStandardImageObject from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  16. class is listed under a feature in features.ymlPassed
    suiteUnit tests (JUnit): PDS3ObjectNameTest

    Bookkeeping, not a product test: checks that the JUnit class jpl.mipl.io.vicar.PDS3ObjectNameTest is listed in a feature's junit: list in features.yml, so its results are grouped under that feature.

PDS label transcoding (XSL)

Building PDS labels from VICAR labels with the bundled XSL stylesheets, the default stylesheet (XSL=-) and the legacy mission recipes.

5 tests · nominal3 off-nominal1 lossless3 mission-data2 regression1 legacy3

  1. XSL=- uses the default stylesheet from the jarPassed
    nominallossless

    Converts the synthetic image to PDS3 with XSL=- (the default stylesheet in the jar) and EMBED_VICAR_LABEL=true. Passes when the label is valid and the pixels are unchanged.

  2. legacy recipe: XML=false, VicarToPDSmer1.xsl, EMBED_VICAR_LABEL=truePassed
    legacynominal

    The legacy normal.pds recipe from tstjConvertIIO.csh (XML=false, XSL=VicarToPDSmer1.xsl, EMBED_VICAR_LABEL=true) on the synthetic image. Passes when the PDS3 label is valid.

  3. all 23 bundled VicarToPDS stylesheets produce valid labelsPassed
    nominallossless

    Converts the synthetic image to PDS3 with each of the 23 VicarToPDS stylesheets in the jar, one step per stylesheet. Passes when every label is valid and every output has the input pixels.

  4. legacy normal.pds recipe on a public MER EDR (via VICAR)Passed
    legacymission-datalosslessPDS label transcoding (XSL) (mission products)

    The legacy normal.pds recipe on real data: converts a public MER EDR to VICAR, then to PDS3 with VicarToPDSmer1.xsl. Passes when the label is valid for a 512 x 512 image and the pixels match the original EDR.

  5. VICAR-to-PDS stylesheet on a PDS-labelled MER EDRPassed
    legacymission-dataoff-nominalregressionPDS label transcoding (XSL) (mission products)

    Applies a VICAR-to-PDS stylesheet directly to a PDS-labelled MER EDR (the legacy mer_file.vic case in runAll.csh). Passes when the conversion succeeds, copying the input label with a warning; before the IDS-8497 fix it crashed.

    Issue IDS-8497: fixed: a VICAR-to-PDS stylesheet on PDS-labelled input (the legacy mer_file.vic case) crashed; the input label is now copied with a warning

PDS4 images

Reading images through PDS4 XML labels; the PDS4 view must match the attached-label view of the same data.

4 tests · nominal1 lossless2 mission-data4

  1. PDS4 label and attached label decode the same pixelsPassed
    mission-data

    Reads a public Mars 2020 Navcam thumbnail two ways: through its PDS4 XML label and directly through the label attached to the image. Passes when the PDS4 reader is used and both give identical pixels matching the recorded golden hash.

  2. jConvertIIO converts a PDS4 label to TIFF and VICARPassed
    mission-datalossless

    Converts the Mars 2020 thumbnail to TIFF and to VICAR, giving jConvertIIO the PDS4 label as input. Passes when both outputs have the pixels the label decodes to.

  3. a relative PDS4 label path resolves its data file next to the labelPassed
    mission-datanominal

    Runs jConvertIIO from a parent directory with a relative path to the PDS4 label. Passes when the data file is found next to the label and the TIFF has the expected pixels.

  4. Mars 2020 Navcam full EDR via PDS4 labelPassed
    mission-datalosslessPDS4 images (full-size products)

    Reads a full-size public Mars 2020 Navcam EDR through its PDS4 label and directly, then converts it to VICAR. Passes when all three decode to identical pixels matching the recorded golden hash.

PDS4 tables

Exporting PDS4 tables (character, delimited) as CSV or fixed-width text, with the bundled ExtractTableJPL tool and jConvertIIO's PDS4_TABLE_* keywords.

5 tests · nominal4 off-nominal1

  1. character table to CSV: header plus every record, values intactPassed
    nominal

    Exports a PDS4 character table (GDAL fixture: 22 fields, 5 records) to CSV with ExtractTableJPL -c. Passes when the CSV has a 22-column header including "Event Number" and every record's values equal the source table.

  2. character table to fixed-width textPassed
    nominal

    Exports the same table to fixed-width text with ExtractTableJPL -w. Passes when there is a header plus 5 records and the first record's values equal the source.

  3. without -o the table is written to stdoutFailed
    off-nominal

    Runs ExtractTableJPL -c without -o. Passes when the table (header plus 5 records) is written to stdout.

    Needs review (bug or intended?): REVIEW-15: ExtractTableJPL prints nothing (exit 0) when no output file is given, and --list-tables prints nothing

  4. delimited (CSV) tableFailed
    nominal

    Exports a PDS4 delimited (CSV) table (GDAL fixture) with ExtractTableJPL -c. Passes when the output has a header and records.

    Needs review (bug or intended?): REVIEW-16: pds4-jparser needs a newer opencsv than the 5.5 pinned in pom.xml: NoSuchMethodError CSVParserBuilder.withKeepQuotations

  5. jConvertIIO PDS4_TABLE_OUPUT_FORMAT=csv exports the tableFailed
    nominal

    Exports the character table through jConvertIIO with PDS4_TABLE_OUPUT_FORMAT=csv (the keyword's spelling). Passes when the CSV has a header plus 5 records.

    Needs review (bug or intended?): REVIEW-17: jConvertIIO never passes the label to the PDS4 table reader (the PDS4TableReadParam setup is commented out); "Cannot read label file", no output

ISIS cubes

Reading ISIS2 cubes with SFDU labels, such as Cassini VIMS spectral cubes (ISIS3 cubes are not supported).

2 tests · nominal2 mission-data1

  1. reads the Cassini VIMS cube and converts it to VICARFailed
    nominalmission-data

    Converts the Cassini VIMS cube to VICAR. Passes when the output has the dimensions and data type given by the label's CORE_ITEMS (1 x 64 x 352, SHORT).

    Needs review (bug or intended?): REVIEW-14: ISIS reader does not trim CORE_ITEMS values: NumberFormatException for " 352", then a NullPointerException (no image); jConvertIIO exits 0 with no output

  2. reads the GDAL ISIS2 cube and converts it to VICARFailed
    nominal

    Converts the GDAL ISIS2 cube to VICAR. Passes when the output has the dimensions and data type given by the label's CORE_ITEMS (43 x 1 x 1, FLOAT).

    Needs review (bug or intended?): REVIEW-14: ISIS reader does not trim CORE_ITEMS values: NumberFormatException for " 352", then a NullPointerException (no image); jConvertIIO exits 0 with no output

FITS images

Reading FITS images and converting them to other formats.

1 tests · lossless1 mission-data1

  1. reads HorseHead.fits and converts it to VICAR and TIFFPassed
    mission-datalossless

    Reads the public HorseHead.fits (astropy sample data) and converts it to VICAR and TIFF. jConvertIIO flips FITS rows into display order, so outputs are compared with the source by statistics and with each other by pixels. Passes when the source matches the recorded golden hash, both outputs have the source's size, type and statistics, and the two outputs are identical.

    Note: jConvertIIO flips FITS (bottom-up rows) to top-down display order; the ImageIO reader returns storage order, so outputs are compared with each other and by statistics

Magellan products

Reading Magellan F-BIDR radar image strips (full-resolution basic image data records). The resampled format (MgnResampImageReader) has no public sample and is not tested.

2 tests · mission-data2

  1. F-BIDR reader decodes the orbit 378 image stripPassed
    mission-data

    Reads a public Magellan F-BIDR (orbit 378, file 13) with the F-BIDR ImageIO reader. Passes when it decodes to a 1092 x 14672 BYTE image that is not blank and matches the recorded golden hash.

  2. jConvertIIO converts the F-BIDR to VICARFailed
    mission-data

    Converts the same F-BIDR to VICAR with jConvertIIO. Passes when the output decodes with all 14672 lines.

    Needs review (bug or intended?): REVIEW-18: F-BIDR read fails in jConvertIIO ("must be read from a stream allowing random access"): VicarInputFile only treats javax FileImageInputStream as random access, but the FAT jar's ImageIO returns imageio-ext FileImageInputStreamExtImpl; exits 0 with no output

Output formats

Every FORMAT= name and alias used by the legacy test (TIFF, PNG, JPEG, JPEG 2000, JPEG-LS, BMP, PNM, RAW, PDS, VICAR, ISIS), for 8-bit, 16-bit and float images.

39 tests · nominal25 off-nominal2 lossless20 regression1 legacy29

  1. FORMAT=tif (#01)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=tif, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  2. FORMAT=tiff (#02)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=tiff, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  3. FORMAT=TIF (#03)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=TIF, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  4. FORMAT=TIFF (#04)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=TIFF, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  5. FORMAT=png (#05)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=png, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  6. FORMAT=PNG (#06)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=PNG, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  7. FORMAT=jpeg2000 (#07)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=jpeg2000, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  8. FORMAT=JPEG2000 (#08)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=JPEG2000, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  9. FORMAT=JPEG 2000 (#09)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=JPEG 2000, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  10. FORMAT=jpeg 2000 (#10)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=jpeg 2000, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  11. FORMAT=pds (#11)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=pds, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  12. FORMAT=vicar (#12)Passed
    legacylossless

    Converts the synthetic 3-band BYTE image with FORMAT=vicar, one of the 29 format names and aliases in the legacy test. Passes when the output decodes to exactly the input pixels.

  13. FORMAT=jpg (#13)Passed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=jpg, one of the 29 format names and aliases in the legacy test. Passes when the output has the input's size and bands and its mean is within 2 DN of the input (JPEG is lossy).

  14. FORMAT=JPG (#14)Passed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=JPG, one of the 29 format names and aliases in the legacy test. Passes when the output has the input's size and bands and its mean is within 2 DN of the input (JPEG is lossy).

  15. FORMAT=jpeg (#15)Passed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=jpeg, one of the 29 format names and aliases in the legacy test. Passes when the output has the input's size and bands and its mean is within 2 DN of the input (JPEG is lossy).

  16. FORMAT=JPEG (#16)Passed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=JPEG, one of the 29 format names and aliases in the legacy test. Passes when the output has the input's size and bands and its mean is within 2 DN of the input (JPEG is lossy).

  17. FORMAT=raw (#17)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=raw, one of the 29 format names and aliases in the legacy test. Passes when the file holds exactly width x height x bands bytes.

    Needs review (bug or intended?): REVIEW-3: RAW output is padded to 256 x 256 tiles unless OFORM is given

  18. FORMAT=RAW (#18)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=RAW, one of the 29 format names and aliases in the legacy test. Passes when the file holds exactly width x height x bands bytes.

    Needs review (bug or intended?): REVIEW-3: RAW output is padded to 256 x 256 tiles unless OFORM is given

  19. FORMAT=bmp (#19)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=bmp, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-4: BMP writer throws ArrayIndexOutOfBoundsException for 3-band input

  20. FORMAT=BMP (#20)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=BMP, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-4: BMP writer throws ArrayIndexOutOfBoundsException for 3-band input

  21. FORMAT=pnm (#21)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=pnm, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-4: PNM writer (jai-imageio) fails to initialise on JDK 17+

  22. FORMAT=PNM (#22)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=PNM, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-4: PNM writer (jai-imageio) fails to initialise on JDK 17+

  23. FORMAT=jfif (#23)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=jfif, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  24. FORMAT=JFIF (#24)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=JFIF, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  25. FORMAT=jpeg-ls (#25)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=jpeg-ls, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  26. FORMAT=JPEG-LS (#26)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=JPEG-LS, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  27. FORMAT=jpeg-lossless (#27)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=jpeg-lossless, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  28. FORMAT=JPEG-LOSSLESS (#28)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=JPEG-LOSSLESS, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  29. FORMAT=isis (#29)Failed
    legacynominal

    Converts the synthetic 3-band BYTE image with FORMAT=isis, one of the 29 format names and aliases in the legacy test. Passes when the output decodes with the input's size and bands and its mean within 2 DN of the input.

    Needs review (bug or intended?): REVIEW-19: no ImageIO writer for this format name, though the legacy tstjConvertIIO.csh lists it

  30. HALF input to FORMAT=tif is losslessPassed
    nominallossless

    Converts the synthetic HALF image with FORMAT=tif, which can hold 16-bit data. Passes when the output decodes to exactly the input pixels.

  31. HALF input to FORMAT=png is losslessPassed
    nominallossless

    Converts the synthetic HALF image with FORMAT=png, which can hold 16-bit data. Passes when the output decodes to exactly the input pixels.

  32. HALF input to FORMAT=jpeg2000 is losslessPassed
    nominallossless

    Converts the synthetic HALF image with FORMAT=jpeg2000, which can hold 16-bit data. Passes when the output decodes to exactly the input pixels.

  33. HALF input to FORMAT=pds is losslessPassed
    nominallossless

    Converts the synthetic HALF image with FORMAT=pds, which can hold 16-bit data. Passes when the output decodes to exactly the input pixels.

  34. HALF input to FORMAT=vicar is losslessPassed
    nominallossless

    Converts the synthetic HALF image with FORMAT=vicar, which can hold 16-bit data. Passes when the output decodes to exactly the input pixels.

  35. REAL input to FORMAT=tif is losslessPassed
    nominallossless

    Converts the synthetic REAL image with FORMAT=tif, which can hold floating-point data. Passes when the output decodes to exactly the input pixels.

  36. REAL input to FORMAT=pds is losslessPassed
    nominallossless

    Converts the synthetic REAL image with FORMAT=pds, which can hold floating-point data. Passes when the output decodes to exactly the input pixels.

  37. REAL input to FORMAT=vicar is losslessPassed
    nominallossless

    Converts the synthetic REAL image with FORMAT=vicar, which can hold floating-point data. Passes when the output decodes to exactly the input pixels.

  38. REAL input to PNG without OFORM is refused with a non-zero exitPassed
    off-nominal

    Converts a REAL (float) image to PNG without OFORM; PNG cannot hold floating-point data. Passes when jConvertIIO refuses with a non-zero exit code.

  39. HALF input to JPEG without OFORM is refused with a non-zero exitPassed
    off-nominalregression

    Converts a HALF (16-bit) image to JPEG without OFORM; the JPEG writer cannot encode 16-bit data. Passes when jConvertIIO exits non-zero instead of leaving an empty file.

    Issue IDS-8497: fixed: jConvertIIO used to exit 0 and leave an empty file when the writer could not encode the data type

Data type conversion

Changing the output data type (OFORM) with or without rescaling, clamping, and float data to 8-bit display formats.

8 tests · nominal8 lossless1 mission-data1 regression1 legacy1

  1. REAL to PNG with OFORM=BYTE is stretched, not blankPassed
    nominallegacyregression

    Converts the legacy REAL 100 x 100 image to PNG with OFORM=BYTE. Passes when the PNG is BYTE, stretched to the byte range (maximum at least 250) and not blank (standard deviation over 10).

    Issue IDS-7610: float VICAR to PNG came out blank

  2. REAL to BYTE with RESCALE=false keeps the values (0..74)Passed
    nominal

    Converts the REAL image (values 0 to 74) to BYTE with RESCALE=false. Passes when the output values are exactly 0 to 74.

  3. HALF to BYTE with the default RESCALE fills the byte rangePassed
    nominal

    Converts the synthetic HALF image to BYTE with the default rescaling. Passes when the output is BYTE and fills the byte range (maximum at least 250).

  4. BYTE to HALF with RESCALE=false is exactPassed
    nominallossless

    Converts the synthetic BYTE image to HALF with RESCALE=false. Passes when the output is 16-bit with pixels equal to the input.

  5. BYTE to REAL with RESCALE=false keeps the valuesPassed
    nominal

    Converts the synthetic BYTE image to REAL with RESCALE=false. Passes when the output is floating point with the input's minimum, maximum and mean.

  6. BYTE to HALF with the default RESCALE keeps the image contrastFailed
    nominal

    Converts the synthetic BYTE image to HALF with the default rescaling. Passes when the output keeps at least half the relative contrast (standard deviation over range) of the input.

    Needs review (bug or intended?): REVIEW-6: OFORM=HALF with default RESCALE saturates byte input (mean 254.5, std 9.8; source std 56)

  7. CLAMP=(10,100) limits the output rangePassed
    nominal

    Converts the synthetic HALF image with CLAMP=(10,100). Passes when the output values span exactly 10 to 100.

  8. 12-bit MER EDR to an 8-bit PNG browse imagePassed
    mission-datanominalData type conversion (mission products)

    Converts a public 12-bit MER Navcam EDR to an 8-bit PNG browse image with OFORM=BYTE. Passes when the PNG is a 512 x 512 BYTE image that is not blank.

Regions, subsampling and bands

Cropping (SOURCE_REGION, CROP), subsampling, scaling, band selection and reordering (READ_BANDS, BANDS), single band to RGB (2RGB), and PNG alpha (WRITE_TRANSPARENCY).

10 tests · nominal9 off-nominal1 lossless2 regression3

  1. SOURCE_REGION=(x,y,width,height) cuts out exactly that regionPassed
    nominal

    Cuts out SOURCE_REGION=(10,20,16,8) from the synthetic image. Passes when the output is 16 x 8 x 3 and its pixel hash equals the hash computed from the generator formula for exactly that region. The region is outlined on the source preview.

  2. SOURCE_REGION running past the image edge is clipped, not an errorPassed
    off-nominalregression

    Asks for a 20 x 20 region at (40,60) of the 48 x 64 image, which runs past both edges. Passes when the output is clipped to 8 x 4 with exactly those pixels, rather than an error.

    Issue IDS-7560: EOF exception when the region is not fully inside the image

  3. SUBSAMPLING=(2,2,0,0) keeps every Nth sample and linePassed
    nominalregression

    Subsamples with SUBSAMPLING=(2,2,0,0) (x step, y step, x offset, y offset). Passes when the output size and pixel hash match the samples and lines the formula selects. The kept pixels are marked on the source preview.

    Issue IDS-7098: subsampling factor did not work

  4. SUBSAMPLING=(3,2,1,1) keeps every Nth sample and linePassed
    nominalregression

    Subsamples with SUBSAMPLING=(3,2,1,1) (x step, y step, x offset, y offset). Passes when the output size and pixel hash match the samples and lines the formula selects. The kept pixels are marked on the source preview.

    Issue IDS-7098: subsampling factor did not work

  5. CROP=(x,y,height,width) as documentedFailed
    nominal

    Crops a gray image with CROP=(1,5,7,11), documented as (x, y, height, width). Passes when the output is 11 wide by 7 high with exactly those pixels.

    Needs review (bug or intended?): REVIEW-11: CROP uses cropX for the y offset (jConvertIIO.java:4816) and reads the last two values as width,height although the help text says height,width; CROP to VICAR also fails (raster bounds)

  6. SCALE=(2,2,0,0) doubles the image sizePassed
    nominal

    Scales the synthetic image with SCALE=(2,2,0,0). Passes when the output is 96 x 128 x 3 with the source's value range.

  7. READ_BANDS selects bands on readPassed
    nominal

    Reads only some bands, with READ_BANDS=2 and with READ_BANDS=0,2. Passes when each output has exactly those bands, with the pixel hash computed for them.

  8. BANDS reorders bands (2,1,0 twice restores the original)Passed
    nominallossless

    Reverses the bands with BANDS=2,1,0, then reverses the result again. Passes when the first output has the bands reversed and the second equals the original.

  9. 2RGB=true turns a single band into gray RGBPassed
    nominal

    Writes a single-band image to PNG with 2RGB=true and with 2RGB=false. Passes when the first PNG is RGB with the gray value in all three bands and the second is a gray PNG.

  10. WRITE_TRANSPARENCY writes the fourth band as PNG alphaPassed
    nominallossless

    Writes a 4-band image to PNG with WRITE_TRANSPARENCY=true. Passes when the PNG is RGBA and the fourth band is the alpha channel, pixel for pixel.

XML metadata and parser security

Label DOM utilities and XML debug output (XML=true), with every XML parser hardened against external entity (XXE) attacks.

9 tests · nominal1 malformed-input2 regression1 security2 suite1 unit5

  1. XML=true writes the label DOM as XML debug documentsPassed
    nominal

    Converts the synthetic image to PDS3 with XML=true, which writes the label DOM as XML debug files. Passes when at least one XML file is written and each is well formed (opens and closes its root element).

  2. a DOCTYPE with a missing external DTD parses; the DTD is never loadedPassed
    securitymalformed-inputregression

    Parses, with the TreeInfo tool, an XML document whose DOCTYPE points at a DTD that does not exist. Passes when there is no exception: the hardened parser never loads external DTDs.

    Issue IDS-10406: before the fix this failed with FileNotFoundException for the DTD

  3. external entities are not resolved (no file read, no error)Passed
    securitymalformed-input

    Parses a hostile XML document with external general and parameter entities: one reads a local "secret" file, another points at a missing file. Passes when the secret text never appears in the output and nothing tries to open the missing file.

    Issue IDS-10406: XXE: external general and parameter entities must be ignored

  4. externalParameterEntityIsNotResolvedPassed
    unitUnit tests (JUnit): DOMutilsXXETest

    Imports the result of the JUnit test DOMutilsXXETest.externalParameterEntityIsNotResolved from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  5. externalDtdIsNotLoadedPassed
    unitUnit tests (JUnit): DOMutilsXXETest

    Imports the result of the JUnit test DOMutilsXXETest.externalDtdIsNotLoaded from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  6. factoryHasXXEFeaturesDisabledPassed
    unitUnit tests (JUnit): DOMutilsXXETest

    Imports the result of the JUnit test DOMutilsXXETest.factoryHasXXEFeaturesDisabled from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  7. namespacedLabelStillParsesPassed
    unitUnit tests (JUnit): DOMutilsXXETest

    Imports the result of the JUnit test DOMutilsXXETest.namespacedLabelStillParses from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  8. externalGeneralEntityIsNotResolvedPassed
    unitUnit tests (JUnit): DOMutilsXXETest

    Imports the result of the JUnit test DOMutilsXXETest.externalGeneralEntityIsNotResolved from the Maven build (target/surefire-reports). Passes when it passed in JUnit; a JUnit failure is shown with its message.

  9. class is listed under a feature in features.ymlPassed
    suiteUnit tests (JUnit): DOMutilsXXETest

    Bookkeeping, not a product test: checks that the JUnit class jpl.mipl.io.util.DOMutilsXXETest is listed in a feature's junit: list in features.yml, so its results are grouped under that feature.

Batch, streaming and remote input

Batch runs from an argument file (serial and parallel), files without extensions, output to stdout, and https input from the public PDS archive.

5 tests · nominal3 off-nominal1 lossless4 mission-data1 regression1

  1. ARGFILE batch runs every linePassed
    nominallossless

    Runs a batch file of 3 conversions (PNG, TIFF and VICAR from different inputs) with ARGFILE. Passes when the run exits 0 and every output exists with its input's pixels.

  2. ARGFILE batch with PARALLEL_BATCH=2 runs every linePassed
    nominallossless

    Runs a batch file of 3 conversions (PNG, TIFF and VICAR from different inputs) with ARGFILE and PARALLEL_BATCH=2. Passes when the run exits 0 and every output exists with its input's pixels.

  3. input and output file names without extensionsPassed
    off-nominalregressionlossless

    Converts an input file that has no extension to an output name with no extension. Passes when the output has the input pixels.

    Issue IDS-10067: launchers failed on file names with no extension

  4. OUT=- with SILENT writes the image to stdoutFailed
    nominal

    Converts to PNG with OUT=- and SILENT, which should stream the image to stdout. Passes when the exit code is 0 and stdout starts with the PNG signature.

    Needs review (bug or intended?): REVIEW-12: OUT=- fails with IllegalArgumentException "image == null!" and writes nothing

  5. https input from the public PDS archive matches the local copyPassed
    mission-datalosslessBatch, streaming and remote input (network)

    Converts an MSL Navcam thumbnail straight from its https URL on the public PDS Imaging Node. Passes when the result has the same pixels as the local copy.

Visual check (replaces JADE review)

Every output a person would look at decodes to an image of the right size that is neither blank nor saturated, with a preview in the report. Replaces opening each output in the JADE viewer in the legacy procedure; the viewer itself is not tested.

8 tests · nominal1 mission-data7 legacy8

  1. legacy step 18: PNG converted to JPEG displaysPassed
    legacynominal

    Legacy step 18, once checked by eye in JADE: converts the synthetic image to PNG, then the PNG to JPEG. Passes when the JPEG displays: BYTE, the same size as the PNG, not blank (standard deviation over 3), not black (mean over 2) and not saturated (mean under 253). The preview is attached for a person to look at.

  2. browse image of msl-navcam-thumb-img displaysPassed
    mission-datalegacy

    Makes an 8-bit PNG browse image (OFORM=BYTE) of msl-navcam-thumb-img, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  3. browse image of m2020-navcam-thumb-img displaysPassed
    mission-datalegacy

    Makes an 8-bit PNG browse image (OFORM=BYTE) of m2020-navcam-thumb-img, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  4. browse image of cassini-iss-img displaysPassed
    mission-datalegacy

    Makes an 8-bit PNG browse image (OFORM=BYTE) of cassini-iss-img, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  5. browse image of astropy-horsehead-fits displaysPassed
    mission-datalegacy

    Makes an 8-bit PNG browse image (OFORM=BYTE) of astropy-horsehead-fits, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  6. browse image of mer1-navcam-edr displaysPassed
    mission-datalegacyVisual check (full-size products)

    Makes an 8-bit PNG browse image (OFORM=BYTE) of mer1-navcam-edr, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  7. browse image of msl-navcam-edr-img displaysPassed
    mission-datalegacyVisual check (full-size products)

    Makes an 8-bit PNG browse image (OFORM=BYTE) of msl-navcam-edr-img, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

  8. browse image of m2020-navcam-edr-img displaysPassed
    mission-datalegacyVisual check (full-size products)

    Makes an 8-bit PNG browse image (OFORM=BYTE) of m2020-navcam-edr-img, as a reviewer once viewed it in JADE. Passes when it displays: the source's size, BYTE, and not blank, black or saturated. The preview is attached.

Python label scripts

The Python utilities in src/main/scripts: xml_swap.py (replace, list and show modes, XXE hardening) and build_mesh_extras.py (mesh label extras, path validation).

5 tests · nominal3 off-nominal1 malformed-input1 regression2 security2

  1. replace mode swaps one element and keeps the restPassed
    nominal

    Runs xml_swap.py in replace mode: replaces //pds:A in a target document with the element from a source document. Passes when the output has the new element, keeps the untouched sibling and no longer has the old value.

  2. list mode prints structural XPathsPassed
    nominal

    Runs xml_swap.py --list-xpaths on a PDS4-namespaced document. Passes when it exits 0 and lists the pds:A element path.

  3. show mode does not expand external entitiesPassed
    securitymalformed-inputregression

    Runs xml_swap.py --show-xpath on a document with an external entity that would read a local "secret" file. Passes when the element is printed with the entity unexpanded (&xxe;) and the secret never appears.

    Issue IDS-10407: lxml parser must not resolve entities or use the network

  4. build_mesh_extras.py writes the mesh extras JSON (LabelObj usage)Passed
    nominal

    Runs build_mesh_extras.py on a mesh .mtl file. Passes when the JSON it writes holds the solar longitude and the texture PNG list from the .mtl.

  5. build_mesh_extras.py refuses paths outside its folders or of the wrong typePassed
    securityoff-nominalregression

    Runs build_mesh_extras.py with four bad paths: an output outside its folders (../escaped.json), an output that is not .json, and /etc/hosts as the .mtl and as the base JSON. Passes when each run exits non-zero with a build_mesh_extras: error and writes nothing.

    Issue S8707: SonarCloud pythonsecurity:S8707 path traversal via command-line arguments

PDS4 label generation (Labelocity)

Generating detached PDS4 labels from Velocity templates with the public Labelocity release (PDS4 writer and mission templates) and the vicario build under test. Generated labels must match the archive label's array structure and read back to the same pixels.

2 tests · nominal2 mission-data2

  1. Mars 2020 Navcam: generated label matches the archive label and reads backPassed
    mission-datanominal

    Generates a PDS4 label for a public Mars 2020 Navcam image with Labelocity (Velocity templates plus vicario). Passes when the label is complete XML with no unresolved template references, names the image file, has a urn:nasa:pds logical identifier, describes the image array exactly as the official archive label does, and reads back to the same pixels.

  2. MSL Navcam: generated label describes and reads back the imagePassed
    mission-datanominal

    Generates a PDS4 label for a public MSL Navcam image (MSL has no official PDS4 label to compare with). Passes when the label is valid as above, describes a 64 x 64 array and reads back to the image's pixels.

Test suite integrity

Feature registry, specs and test-data manifest are consistent.

6 tests · suite6

  1. feature ids are unique and well formed, with a name and descriptionPassed
    suiteFeature registry

    Checks features.yml: feature ids are unique, lowercase and not reserved, and every feature has a name, a description and a valid status.

  2. every active feature has specs that carry its tagPassed
    suiteFeature registry

    Checks that every active feature lists spec files that exist and call feature() with its id, so their tests carry the feature's tag.

  3. planned features name a milestone and excluded features give a reasonPassed
    suiteFeature registry

    Checks that planned features name a milestone and excluded features give a reason.

  4. every spec belongs to a featurePassed
    suiteFeature registry

    Checks that every spec file in features/ is listed under a feature in features.yml.

  5. every manifest asset is pinned, licensed and used by a spec or helperPassed
    suiteFeature registry

    Checks the test data manifest: every downloaded file is pinned by SHA-256, has a license and is used by a spec or helper.

  6. every test has a description and a scope tagPassed
    suiteFeature registry

    Lists the whole suite (playwright test --list) and checks that every test has a "what it checks" description and at least one scope tag (@nominal, @off-nominal, @malformed-input, @lossless, @mission-data, @regression, @security, @legacy, @suite, @unit), so the procedures report describes every test.