From 93d925b6fdd7a16432cc0aade6c711d8ed0c1d6e Mon Sep 17 00:00:00 2001 From: Yvan Lubac Date: Mon, 15 Dec 2025 17:14:49 +0100 Subject: [PATCH 1/5] check for duplicate values in SENSOR and PARAMETER in META files --- file_checker_exec/pom.xml | 2 +- .../validators/ArgoMetadataFileValidator.java | 93 ++++++++++-------- .../coriolis/checker/e2etests/TestsUtils.java | 56 +++++++---- ...alidateMetaDuplicateSensorParameterIT.java | 42 ++++++++ .../2903795_meta_duplicate_PARAMETER.nc | Bin 0 -> 166712 bytes ...5902129_meta_duplicate_PARAMETER_SENSOR.nc | Bin 0 -> 37928 bytes 6 files changed, 129 insertions(+), 64 deletions(-) create mode 100644 file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateMetaDuplicateSensorParameterIT.java create mode 100644 file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/2903795_meta_duplicate_PARAMETER.nc create mode 100644 file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/5902129_meta_duplicate_PARAMETER_SENSOR.nc diff --git a/file_checker_exec/pom.xml b/file_checker_exec/pom.xml index 8cab763..19f840e 100644 --- a/file_checker_exec/pom.xml +++ b/file_checker_exec/pom.xml @@ -4,7 +4,7 @@ 4.0.0 fr.ifremer file_checker_exec - 2.9.4 + 2.9.5-SNAPSHOT Argo NetCDF file format checker diff --git a/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java b/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java index f32afbd..61d8d75 100644 --- a/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java +++ b/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java @@ -1,12 +1,16 @@ package fr.coriolis.checker.validators; import java.io.IOException; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -820,6 +824,12 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException validationResult.addError(name + "[" + (n + 1) + "]: '" + str + "': Invalid"); } } + // check unicity in PARAMETER entries : + Set duplicateParameters = checkForDuplicate(paramVar); + if (duplicateParameters.size() > 0) { + validationResult.addWarning( + "PARAMETER variable contains duplicate values: [" + String.join(", ", duplicateParameters) + "]"); + } name = "PARAMETER_UNITS"; // ..not empty paramVar = arFile.readStringArr(name); @@ -886,53 +896,23 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException ArgoReferenceTable.ArgoReferenceEntry snsrInfo; // ..check SENSOR - boolean snsrValid = false; String snsr = sensor[n].trim(); - log.debug(sensorName + "[{}]: '{}'", n, snsr); - - if ((snsrInfo = ArgoReferenceTable.SENSOR.contains(snsr)).isValid()) { - snsrValid = true; - if (snsrInfo.isDeprecated) { - validationResult - .addWarning(sensorName + "[" + (n + 1) + "]: '" + snsr + "' Status: " + snsrInfo.message); - } - - } else { - validationResult.addError(sensorName + "[" + (n + 1) + "]: '" + snsr + "' Status: " + snsrInfo.message); - } + snsrInfo = ArgoReferenceTable.SENSOR.contains(snsr); + boolean snsrValid = checkParameterValueAgainstRefTable(sensorName + "[" + (n + 1) + "]", snsr, + ArgoReferenceTable.SENSOR); // ..check SENSOR_MAKER String snsrMaker = sensorMaker[n].trim(); - boolean smkrValid = false; + mkrInfo = ArgoReferenceTable.SENSOR_MAKER.contains(snsrMaker); + boolean smkrValid = checkParameterValueAgainstRefTable(sensorMakerName + "[" + (n + 1) + "]", snsrMaker, + ArgoReferenceTable.SENSOR_MAKER); log.debug(sensorMakerName + "[{}]: '{}'", n, snsrMaker); - if ((mkrInfo = ArgoReferenceTable.SENSOR_MAKER.contains(snsrMaker)).isValid()) { - smkrValid = true; - if (mkrInfo.isDeprecated) { - validationResult.addWarning( - sensorMakerName + "[" + (n + 1) + "]: '" + snsrMaker + "' Status: " + mkrInfo.message); - } - - } else { - validationResult.addError( - sensorMakerName + "[" + (n + 1) + "]: '" + snsrMaker + "' Status: " + mkrInfo.message); - } - // ..check SENSOR_MODEL String snsrModel = sensorModel[n].trim(); - boolean mdlValid = false; - log.debug(sensorModelName + "[{}]: '{}'", n, snsrModel); - - if ((mdlInfo = ArgoReferenceTable.SENSOR_MODEL.contains(snsrModel)).isValid()) { - mdlValid = true; - if (mdlInfo.isDeprecated) { - validationResult.addWarning( - sensorModelName + "[" + (n + 1) + "]: '" + snsrModel + "' Status: " + mdlInfo.message); - } - } else { - validationResult.addError( - sensorModelName + "[" + (n + 1) + "]: '" + snsrModel + "' Status: " + mdlInfo.message); - } + mdlInfo = ArgoReferenceTable.SENSOR_MODEL.contains(snsrModel); + boolean mdlValid = checkParameterValueAgainstRefTable(sensorModelName + "[" + (n + 1) + "]", snsrModel, + ArgoReferenceTable.SENSOR_MODEL); // ..cross-reference SENSOR_MODEL / SENSOR_MAKER if (smkrValid && mdlValid) { @@ -966,6 +946,12 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException } } } + // check unicity in SENSOR entries : + Set duplicateSensors = checkForDuplicate(sensor); + if (duplicateSensors.size() > 0) { + validationResult.addWarning( + "SENSOR variable contains duplicate values: [" + String.join(", ", duplicateSensors) + "]"); + } // ..........per-positioning_system checks String[] positVar; @@ -1023,27 +1009,48 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException log.debug("....validateMandatory_v3: end....."); } // ..end validateMandatory_v3 - private void checkParameterValueAgainstRefTable(String parameterName, StringTable refTable) { + private boolean checkParameterValueAgainstRefTable(String parameterName, String parameterValue, + StringTable refTable) { ArgoReferenceTable.ArgoReferenceEntry info; - String parameterValue = arFile.readString(parameterName).trim(); log.debug("{}: '{}'", parameterName, parameterValue); if ((info = refTable.contains(parameterValue)).isValid()) { if (info.isDeprecated) { validationResult.addWarning(parameterName + ": '" + parameterValue + "' Status: " + info.message); } + return true; } else { validationResult.addError(parameterName + ": '" + parameterValue + "' Status: " + info.message); + return false; } } - private void checkOptionalParameterValueAgainstRefTable(String parameterName, StringTable refTable) { + private boolean checkOptionalParameterValueAgainstRefTable(String parameterName, StringTable refTable) { Variable dataVar = arFile.getNcReader().findVariable(parameterName); if (dataVar != null) { - checkParameterValueAgainstRefTable(parameterName, refTable); + String parameterValue = arFile.readString(parameterName).trim(); + return checkParameterValueAgainstRefTable(parameterName, parameterValue, refTable); } + return true; + } + + /** + * Check if a list of values contains duplicates + * + * @param paramValuesList (String[]) list of values to check + * @return Set of values which are found multiple time in the list + */ + private Set checkForDuplicate(String[] paramValuesList) { + // for each value of the list, count the number of times it appears + Map count = Arrays.stream(paramValuesList).map(String::trim) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); + // build the list of value which appears more than one time + Set doublons = count.entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey) + .collect(Collectors.toSet()); + + return doublons; } /** diff --git a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java index 204a6af..0d4f69b 100644 --- a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java +++ b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java @@ -33,42 +33,52 @@ public static void init(Class clazz) { } } - public static void genericFileCheckerE2ETest(String fileName, String dac, String result, String phase, - String testDirName, String options) throws IOException, InterruptedException { + private static String executeJarAndGetResult(String fileName, String dac, String testDirName, String options) + throws IOException, InterruptedException { + + // ARRANGE + String inputDirPath = TestsUtils.TEST_FILES_DIR + "/" + testDirName; + File inputDir = new File(inputDirPath); + File testFile = new File(inputDirPath + "/" + fileName); - // ARANGE - String inPutDirPath = TestsUtils.TEST_FILES_DIR + "/" + testDirName; - File intputDir = new File(inPutDirPath); - File testFile = new File(inPutDirPath + "/" + fileName); - // before executing jar, verify file and dir exists : + // pre-checks assertThat(TestsUtils.jarFile).exists().isFile().as("jar should be created in target folder"); - ; assertThat(testFile).exists().isFile().as("netcdf test file should be in test/netcdf/TEST* resources folder"); assertThat(TestsUtils.specDirDir).exists().isDirectory().as("specifications directory should exist"); - assertThat(intputDir).exists().isDirectory().as("input directory should exist"); + assertThat(inputDir).exists().isDirectory().as("input directory should exist"); assertThat(TestsUtils.outputDir).exists().isDirectory().as("output directory should exist"); // ACT ProcessBuilder builder = new ProcessBuilder("java", "-jar", TestsUtils.jarPath, options, dac, - TestsUtils.SPEC_DIR_PATH, TestsUtils.OUTPUT_DIR_PATH, inPutDirPath, fileName); + TestsUtils.SPEC_DIR_PATH, TestsUtils.OUTPUT_DIR_PATH, inputDirPath, fileName); builder.redirectErrorStream(true); Process process = builder.start(); - process.waitFor(); - // ASSESS - // No error + // ASSERT - common checks int exitCode = process.waitFor(); assertThat(exitCode).isZero().as("execution should complete without errors"); - // result file created - File xmlResultFile = new File(TestsUtils.OUTPUT_DIR_PATH + "\\" + fileName + ".filecheck"); + + File xmlResultFile = new File(TestsUtils.OUTPUT_DIR_PATH + "/" + fileName + ".filecheck"); assertThat(xmlResultFile).exists().isFile().as("Result file should be created in %s", TestsUtils.OUTPUT_DIR_PATH); - // expected status - String content = String.join("\n", Files.readAllLines(xmlResultFile.toPath())); - assertThat(content).isNotEmpty().contains("" + result); - // in the expected - assertThat(content).isNotEmpty().contains("" + phase); + return String.join("\n", Files.readAllLines(xmlResultFile.toPath())); + } + + public static void genericFileCheckerE2ETest(String fileName, String dac, String result, String phase, + String testDirName, String options) throws IOException, InterruptedException { + + String content = executeJarAndGetResult(fileName, dac, testDirName, options); + + assertThat(content).isNotEmpty().contains("" + result).contains("" + phase); + } + + public static void e2eTestWarningPresence(String fileName, String dac, String warningMessage, String testDirName, + String options) throws IOException, InterruptedException { + + String content = executeJarAndGetResult(fileName, dac, testDirName, options); + + assertThat(content).isNotEmpty().contains("" + warningMessage); } // We use an overloaded method to provide a default value for the last argument @@ -80,4 +90,10 @@ public static void genericFileCheckerE2ETest(String fileName, String dac, String } + public static void e2eTestWarningPresence(String fileName, String dac, String warningMessage, String testDirName) + throws IOException, InterruptedException { + + e2eTestWarningPresence(fileName, dac, warningMessage, testDirName, "-no-name-check"); + } + } diff --git a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateMetaDuplicateSensorParameterIT.java b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateMetaDuplicateSensorParameterIT.java new file mode 100644 index 0000000..cd1f21c --- /dev/null +++ b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateMetaDuplicateSensorParameterIT.java @@ -0,0 +1,42 @@ +package fr.coriolis.checker.e2etests; + +import java.io.IOException; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayName("Check if SENSOR and PARAMETER don't contain duplicate value") +class ValidateMetaDuplicateSensorParameterIT { + + private final String TEST_DIR_NAME = "TEST_META_0003"; + + @BeforeAll + public static void init() { + TestsUtils.init(ValidateMetaDuplicateSensorParameterIT.class); + + } + + @Tag(TEST_DIR_NAME) + @ParameterizedTest(name = "{0} from dac {1} should have status {2} at phase {3}") + @CsvSource({ "2903795_meta_duplicate_PARAMETER.nc,coriolis,FILE-ACCEPTED,DATA-VALIDATION" }) + void fileChecker_shouldAcceptMetaFile_WhenDuplicateInSensorOrParameter(String fileName, String dac, String result, + String phase) throws IOException, InterruptedException { + + TestsUtils.genericFileCheckerE2ETest(fileName, dac, result, phase, TEST_DIR_NAME); + + } + + @Tag(TEST_DIR_NAME) + @ParameterizedTest(name = "{0} from dac {1} should have warning {2}") + @CsvSource(delimiter = '|', value = { + "2903795_meta_duplicate_PARAMETER.nc|coriolis|PARAMETER variable contains duplicate values: [PPOX_DOXY, DOXY]", + "5902129_meta_duplicate_PARAMETER_SENSOR.nc|coriolis|SENSOR variable contains duplicate values: [CTD_TEMP, CTD_PRES]" }) + void fileChecker_ShouldRaiseWarning_WhenDuplicateInSensorOrParamete(String fileName, String dac, + String warningMessage) throws IOException, InterruptedException { + TestsUtils.e2eTestWarningPresence(fileName, dac, warningMessage, TEST_DIR_NAME); + } + +} diff --git a/file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/2903795_meta_duplicate_PARAMETER.nc b/file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/2903795_meta_duplicate_PARAMETER.nc new file mode 100644 index 0000000000000000000000000000000000000000..4db1bb52b0d15f5b1fc06fdddb70f5dcb92c2c17 GIT binary patch literal 166712 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 literal 0 HcmV?d00001 diff --git a/file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/5902129_meta_duplicate_PARAMETER_SENSOR.nc b/file_checker_exec/src/test/netcdf-test-files/TEST_META_0003/5902129_meta_duplicate_PARAMETER_SENSOR.nc new file mode 100644 index 0000000000000000000000000000000000000000..5f8f77b348143274d59a17e7c8c7dc813023841d GIT binary patch literal 37928 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 U#=v3yt|ES2aqc;5`k}-9AB{WvR{#J2 literal 0 HcmV?d00001 From 00c15cddb8820b1b91e5d2b63aec0c360c72429d Mon Sep 17 00:00:00 2001 From: Yvan Lubac Date: Tue, 16 Dec 2025 10:15:13 +0100 Subject: [PATCH 2/5] warning when bad program name --- .../validators/ArgoMetadataFileValidator.java | 24 ++++++--- .../coriolis/checker/e2etests/TestsUtils.java | 27 ++++++++-- ...alidateOptionalParametersValueCheckIT.java | 2 +- .../validateProgramNameCheckInMetaFileIT.java | 51 ++++++++++++++++++ .../1902735_meta_bad_programName.nc | Bin 0 -> 83516 bytes .../1902735_meta_empty_programName.nc | Bin 0 -> 83516 bytes .../5907141_meta_good_programName.nc | Bin 0 -> 77648 bytes 7 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/validateProgramNameCheckInMetaFileIT.java create mode 100644 file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_bad_programName.nc create mode 100644 file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_empty_programName.nc create mode 100644 file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/5907141_meta_good_programName.nc diff --git a/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java b/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java index 61d8d75..d9a09f5 100644 --- a/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java +++ b/file_checker_exec/src/main/java/fr/coriolis/checker/validators/ArgoMetadataFileValidator.java @@ -159,7 +159,7 @@ public boolean validateData(boolean ckNulls, boolean... optionalChecks) throws I private void validateOptionalParams() { // PROGRAM_NAME - ref table 41 - checkOptionalParameterValueAgainstRefTable("PROGRAM_NAME", ArgoReferenceTable.PROGRAM_NAME); + checkOptionalParameterValueAgainstRefTable("PROGRAM_NAME", ArgoReferenceTable.PROGRAM_NAME, true); } /** @@ -899,20 +899,20 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException String snsr = sensor[n].trim(); snsrInfo = ArgoReferenceTable.SENSOR.contains(snsr); boolean snsrValid = checkParameterValueAgainstRefTable(sensorName + "[" + (n + 1) + "]", snsr, - ArgoReferenceTable.SENSOR); + ArgoReferenceTable.SENSOR, false); // ..check SENSOR_MAKER String snsrMaker = sensorMaker[n].trim(); mkrInfo = ArgoReferenceTable.SENSOR_MAKER.contains(snsrMaker); boolean smkrValid = checkParameterValueAgainstRefTable(sensorMakerName + "[" + (n + 1) + "]", snsrMaker, - ArgoReferenceTable.SENSOR_MAKER); + ArgoReferenceTable.SENSOR_MAKER, false); log.debug(sensorMakerName + "[{}]: '{}'", n, snsrMaker); // ..check SENSOR_MODEL String snsrModel = sensorModel[n].trim(); mdlInfo = ArgoReferenceTable.SENSOR_MODEL.contains(snsrModel); boolean mdlValid = checkParameterValueAgainstRefTable(sensorModelName + "[" + (n + 1) + "]", snsrModel, - ArgoReferenceTable.SENSOR_MODEL); + ArgoReferenceTable.SENSOR_MODEL, false); // ..cross-reference SENSOR_MODEL / SENSOR_MAKER if (smkrValid && mdlValid) { @@ -1010,7 +1010,7 @@ public void validateMandatory_v3(ArgoReferenceTable.DACS dac) throws IOException } // ..end validateMandatory_v3 private boolean checkParameterValueAgainstRefTable(String parameterName, String parameterValue, - StringTable refTable) { + StringTable refTable, boolean warningOnly) { ArgoReferenceTable.ArgoReferenceEntry info; log.debug("{}: '{}'", parameterName, parameterValue); @@ -1021,17 +1021,25 @@ private boolean checkParameterValueAgainstRefTable(String parameterName, String return true; } else { - validationResult.addError(parameterName + ": '" + parameterValue + "' Status: " + info.message); + String resultMessage = parameterName + ": '" + parameterValue + "' Status: " + info.message + + " (not in reference table)"; + if (warningOnly) { + validationResult.addWarning(resultMessage); + } else { + validationResult.addError(resultMessage); + } + return false; } } - private boolean checkOptionalParameterValueAgainstRefTable(String parameterName, StringTable refTable) { + private boolean checkOptionalParameterValueAgainstRefTable(String parameterName, StringTable refTable, + boolean warningOnly) { Variable dataVar = arFile.getNcReader().findVariable(parameterName); if (dataVar != null) { String parameterValue = arFile.readString(parameterName).trim(); - return checkParameterValueAgainstRefTable(parameterName, parameterValue, refTable); + return checkParameterValueAgainstRefTable(parameterName, parameterValue, refTable, warningOnly); } return true; } diff --git a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java index 0d4f69b..2719c8b 100644 --- a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java +++ b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/TestsUtils.java @@ -65,6 +65,7 @@ private static String executeJarAndGetResult(String fileName, String dac, String return String.join("\n", Files.readAllLines(xmlResultFile.toPath())); } + // ============== CHECK RESULT ================= public static void genericFileCheckerE2ETest(String fileName, String dac, String result, String phase, String testDirName, String options) throws IOException, InterruptedException { @@ -73,6 +74,17 @@ public static void genericFileCheckerE2ETest(String fileName, String dac, String assertThat(content).isNotEmpty().contains("" + result).contains("" + phase); } + // We use an overloaded method to provide a default value for the last argument + // "options". + public static void genericFileCheckerE2ETest(String fileName, String dac, String result, String phase, + String testDirName) throws IOException, InterruptedException { + + genericFileCheckerE2ETest(fileName, dac, result, phase, testDirName, "-no-name-check"); + + } + + // ============== CHECK WARNINGS ================= + public static void e2eTestWarningPresence(String fileName, String dac, String warningMessage, String testDirName, String options) throws IOException, InterruptedException { @@ -81,13 +93,12 @@ public static void e2eTestWarningPresence(String fileName, String dac, String wa assertThat(content).isNotEmpty().contains("" + warningMessage); } - // We use an overloaded method to provide a default value for the last argument - // "options". - public static void genericFileCheckerE2ETest(String fileName, String dac, String result, String phase, - String testDirName) throws IOException, InterruptedException { + public static void e2eTestWarningAbsence(String fileName, String dac, String testDirName, String options) + throws IOException, InterruptedException { - genericFileCheckerE2ETest(fileName, dac, result, phase, testDirName, "-no-name-check"); + String content = executeJarAndGetResult(fileName, dac, testDirName, options); + assertThat(content).isNotEmpty().contains(""); } public static void e2eTestWarningPresence(String fileName, String dac, String warningMessage, String testDirName) @@ -96,4 +107,10 @@ public static void e2eTestWarningPresence(String fileName, String dac, String wa e2eTestWarningPresence(fileName, dac, warningMessage, testDirName, "-no-name-check"); } + public static void e2eTestWarningAbsence(String fileName, String dac, String testDirName) + throws IOException, InterruptedException { + + e2eTestWarningAbsence(fileName, dac, testDirName, "-no-name-check"); + } + } diff --git a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateOptionalParametersValueCheckIT.java b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateOptionalParametersValueCheckIT.java index d2c32ea..41421f6 100644 --- a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateOptionalParametersValueCheckIT.java +++ b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/ValidateOptionalParametersValueCheckIT.java @@ -22,7 +22,7 @@ public static void init() { @Tag(TEST_DIR_NAME) @ParameterizedTest(name = "{0} from dac {1} should have status {2} at phase {3}") @CsvSource({ "6903281_meta_PROGRAM_NAME_in_ref-table-41.nc,coriolis,FILE-ACCEPTED,DATA-VALIDATION", - "6903281_meta_PROGRAM_NAME_Not-in_ref-table-41.nc,coriolis,FILE-REJECTED,DATA-VALIDATION" }) + "6903281_meta_PROGRAM_NAME_Not-in_ref-table-41.nc,coriolis,FILE-ACCEPTED,DATA-VALIDATION" }) void fileChecker_shouldAcceptPROGRAMNAME_WhenConformToRefTable41(String fileName, String dac, String result, String phase) throws IOException, InterruptedException { diff --git a/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/validateProgramNameCheckInMetaFileIT.java b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/validateProgramNameCheckInMetaFileIT.java new file mode 100644 index 0000000..ac12d96 --- /dev/null +++ b/file_checker_exec/src/test/java/fr/coriolis/checker/e2etests/validateProgramNameCheckInMetaFileIT.java @@ -0,0 +1,51 @@ +package fr.coriolis.checker.e2etests; + +import java.io.IOException; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayName("Check PROGRAM_NAME against reference table") +class validateProgramNameCheckInMetaFileIT { + + private final String TEST_DIR_NAME = "TEST_META_0004"; + + @BeforeAll + public static void init() { + TestsUtils.init(validateProgramNameCheckInMetaFileIT.class); + + } + + @Tag(TEST_DIR_NAME) + @ParameterizedTest(name = "{0} from dac {1} should have status {2} at phase {3}") + @CsvSource({ "1902735_meta_bad_programName.nc,coriolis,FILE-ACCEPTED,DATA-VALIDATION", + "1902735_meta_empty_programName.nc,coriolis,FILE-ACCEPTED,DATA-VALIDATION" }) + void fileChecker_shouldAcceptMetaFile_WhenBadProgramNameValue(String fileName, String dac, String result, + String phase) throws IOException, InterruptedException { + + TestsUtils.genericFileCheckerE2ETest(fileName, dac, result, phase, TEST_DIR_NAME); + + } + + @Tag(TEST_DIR_NAME) + @ParameterizedTest(name = "{0} from dac {1} should have warning {2}") + @CsvSource(delimiter = '|', value = { + "1902735_meta_bad_programName.nc|coriolis|PROGRAM_NAME: 'test de program name' Status: Invalid (not in reference table)", + "1902735_meta_empty_programName.nc|coriolis|PROGRAM_NAME: '' Status: Invalid (not in reference table)" }) + void fileChecker_ShouldRaiseWarning_WhenBadProgramNameValue(String fileName, String dac, String warningMessage) + throws IOException, InterruptedException { + TestsUtils.e2eTestWarningPresence(fileName, dac, warningMessage, TEST_DIR_NAME); + } + + @Tag(TEST_DIR_NAME) + @ParameterizedTest(name = "{0} from dac {1} should not have warning") + @CsvSource({ "5907141_meta_good_programName.nc,coriolis" }) + void fileChecker_ShouldNotRaiseWarning_WhenGoodProgramNameValue(String fileName, String dac) + throws IOException, InterruptedException { + TestsUtils.e2eTestWarningAbsence(fileName, dac, TEST_DIR_NAME); + } + +} diff --git a/file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_bad_programName.nc b/file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_bad_programName.nc new file mode 100644 index 0000000000000000000000000000000000000000..a864e6ea8fd21b4d98b06abed5aaaae7fa37b78c GIT binary patch literal 83516 zcmeHQ%a0?+dFNV^_1I_hvJ%NsM^WsV-65x&oCmq`SmcnLT}H!)NX~BLB%*uB=1glz zHr;HlcI4Pz19D&oIv9w791X-d3UP9d0qfwK{RiZbgAwHDgAX|vNRZ_BRaZ5e9Fon| zh(oWY8X)^sUEi;M_0?BjeN|1SGdt%(q0poFJcZBG_&k|ORkO8fE}z8-woCXtRjHP9 zg&S*XVuLPSp)Y<-Q=@BiN?C-SbkjxGS+WpiEv{+NIGu$;_wjkcO}9Z$CI{!SD2|oE zxklNLu*co>EQcos=bm7GpB@i=j_wy~rBpeUr*i`KM4?v67AnOuKfhF{rHh4~+>Jr9 z(DS(WT%op`+AE}Q9={!;%$_RL^0`VSS1eR;=5EhIRtvy_$!4>{Fx zs!$nRb+2E*y(jT`%rTvofdg!W`-PN!U@6U(r8`R7aP)@m=t|RMNzR*{9+LMR)9Q%y zPo#_GTyZx?Xg=Sw`gYyTjPiPFkQXHnJ$`8R9LqkUW4ixtRE@5O)kIj0SGD!)>e_WR z@inDx8#+mNUGZ)ws%qkTOuMe(c1!O$O1}$ShO$(*Y}0C)Jq{R8wiL%~8w!KnwXM3* z>zSQ{WfB>B$~KyYZFF#vofC$oL&xb}UtN9gz4szIicSx<51fc)AFO7qdcSRS90mtz zpXv7uyVlk_eZ5t?YuG&>50Atm8fAJuZFTPA8Qfw*NXBL2A&dk{dMB(!m}XvX7_+l=GF{B1YU*Y}r`*7k*>LyxewncL0JdS744|e)w9R-ty1EwC;!O2I=aFt3A8JFX zTJ`M`Z$qRDkK;r2{s`S~S)GGgM{oP;{>cngwsX|w*Us0Em*sg@ryh}tqwlv2g%v&Y zRBgv>wQlLH{y+!LDG-K@ctAT^`A_UG?G(%TRJC?1TP8)O+e}wU9|<3&9f$83WN#=< z%WgwCeY^$9Mf+R%FXVaUW~z|cE*9VPNhV%`C^O0a9b{Z& zHZ5Jwrl^_X0ydIO+q60%*@j{@SsV1)hWp&O`nmKrwtPO5xp|Z91WOo%k?Q4tkn%jk zxL2YbJva-#7X?1vB!SdHGZ!W!^eJKt6Hk{*yQwPaPpz<*-_DXbWjM(uPvh|mJIti@ zJLWg~hGI6Ti8f8crsv0DeED|1$gRpCv2tBWC33XUV}W%KOyQT1?vYZpO6iGDYJ1ak zJW{pwPOojkY*`&2PGu=ozEP~KD8=%2x|q+eD27vyaJx2L2T5%BHIh5h6Hq(*1AK&C znAGlGt{N>^t9Bdg)tNEuDZQhfW3&}m#0GK*<^nnvAq>$TiI!~Z zz}DM-S_pu$e*~p76vt1U3y`u8tS1H7s3YgtcFNhe_OgZa+w`o!CODd8JC}BB1De&T zA5mi+LejLYHp9nyRpj{?cy!z@h~@v-pLUk1B?3!b|P++xvzsDo$92*~l%|Huqsmp-v6v`@8NId4;UH484Bnc8pZyAe|wf zPyKhKga4BrfjSe`{EjQ1L-d<_H@Z)74rb#fHt)SRbS7_)KaG&-iTz221Z6b!O#)WF|u) z=J1ou8yMrBL?-p;fEZXOBoiOzqo!)5N&%iREuC)8e_wiCrP{!IoP(8gmTu)}FZgycpObj$J z9zW1ArY5+7@{^GN0n$C5Dirgn<9+rdJxOGQRnR*}ir%r>ddoC=3XC@h!}zb=8(494 zLPyG>e%HVkISSYU^odke`vtx(Y^SQ#Z24``+-A|?S4AJauRD$bx1y`p@ARma$%4&p zSCgSolrUTr7)q)1o9^&wraHQYaevc1=-bRcCc8czPyi<(;E6p7JYPhVs9G-W?qP7%s1S9wLnNDhOM6Y(G7PJmfhGe;**-Yg2Ig zNt^}e>R6o937rM!KLY2KN-3Kr_htuCi@kD|ngd}XJ29@C|2!czhJ%W52-HdDjOk-YyK{0716&yc-9w-s`wy z{~#`sq0lDDdahW?mJz!_e3d+cTy<|ajuRyJ)neBm+knxQFN!)u4WtC?P%;#X69E^~ zdzEStA)b+VQefS<<*)Y`FSzZ+_prEcOG;5*Nw z*bfp*dWpr7miDUYWkF2C=(emQ3c^yJW8#sYFy8eQ!g!fuL_`VonPL6}E;HSx`WzR7 z{F7Z!=JXrhn2U8W%6o@K2hKBrbps-!WBdyZug)b0_eb^Cz5hG&w{CJ~-!NAHN)_iJX&_8bP((R~%h|k7_h=LMhs!y*KWjPvlJer^d@IeeW?$3%!sWLR$TuB? zB088>=yx!%!H~yTaiEC#NkcB6L+6v7JeWih{F^`ohS8JlFFdIt} zr(s_?-d38Xjj0hD!J)Z`1|&S7ao9g;+adkEIKW(+mG9?#eD@sP23XKdB^}?kPs%Md zoeK=-UP-V^{TFT1xLrQZErKfMUC*`idNVh#Pm|lfMwXZTn0@R{!~BI&Zu?!2-EsI% z%I$~1`AjBT+AY4F$6%}`!dJuyaSYv_>LdJV&I`c{RUO!RrQ6aSn&+Y1g8Rh#Xh%Op zx@UcO(&fEeCF=&5XYr#-0*~9^z4(lc(IKBS^sc$?Ox^CAJ%dHS-7o|h|AC`318yZ0 z+CqFJ^okF6IlGfBBlw)HK?%sk;4yM41C4J<2dIx9*Eih~WuU;)c;Iy_%xoIM6KH{K zmeMN$X4K3kF99^5h~JBZAZ+9G z`V-o;uM+mB{n&~AJw5=$y=iT48Syly@AwOT16Ski%PSki{Td1RyBwB{%(4-C7ng2>4*W zac);f{Kmk*Tfvm9+lL}EYytSbbRYOKNcY7__->_k_qaz!%0(Eb>HbwV?M(VI8^BR~ zWBjMjp`UB~0&<_5L>}%De;4rq-&66u62KoG58{lb_77I@_53kB1F{IuWqb(JG`^G| zzVQ4E9EJWlbncB7(h83F;uPQPtlJ+DCc-l*Mt6PBotfovUUUu?8!S;*%Pl}p!4Qgi zg~5!U@NUN2fopw479z=R)WH=EvC6@uTp(U&3DS zF3L#ru;}}6$JGNWV~~x0A&q%d=AR)B>2FGSb`%HI(ya4xCf`19UMB3CZ) zD&iTF`2DibKO(eebb9C@+E%~gfK0f*LmtgIyEJk>R}FPMOtt-lH2nyTIY$d9?0$?oEOR?L?~yv^krPmb5o2^cpi z{R|lI62>c>S1;OyYXWD`T+oXX;zy()GhhfML!tKx!;@^a8}%&olq;VM7L6}2;4?`t zqe3qSJqb0^KItW!ICsa_ZHy-oOQM$3LvG`_9PiV{So#1isf&64H~6~Zm1D48kGQ0= zkWx%5%c>}gPfwjgwvdjYrzkm=#&{(~b`PSrv$QpW`b{dw*%hMSN&^hAc+r-C9rE=Cc1W2cLbK5nn zK@p)nfrpgz0zQ-K?aOI|Gxqrm1XiQC<5hQ#eN^uPuq7epJH*i|$S| zS@B)<E+=j ztJDV+L-I@*|F6Z?u+VDSFajRBqR>)MEfQr5T-Agc*Va`mY*xg1LQTXp4d+@yjc&%) zm8Pb~HrAChyXDHcOl~jlmA|tJ5~pmV_ivOcEH#@inDX3b{Z^`!{qt#Mtlln9yZxEJ zmn!XOS~wcf;%J~_wwS8L)VNYM?nX395Y#M3_0Y{Z;*lI*+fbNoNZrnj5jWE%2WtQj z^re}2wl=au>%ksi%k3yiv86Ya?P7L2yZZo7%A|sUU2`?nx+BgWd>>O9VOqDKv`iYU zHo{mIN!^coS{JAKBpFO^A6%^Wgc?)B(e-G|yC4rF1CjyBz>Ex>p!;GHPWpVFzb;X6 zm*B&6t|;3GZm}gryZRBr(`6MNw7L zHq`i9R8LmKJ_qwKiL`TJD zMn9T=Z48yaYE}9+-oj#tl*)s5SO=dnnz!PPlw} zO@q-+6fpHa741_d>faC`yt|(`_CmT=CT^uPNUe|HJip9NcTbD@_GB?FBad#8-q42S)#R*=#%GY0=WDUi516! zI=CirzHO1q&()#fj_ZO{@Ty4XAlErG_t|UK8Kb2iRq*PTv5S?_NSVE>(<}b9hJJKn z%REMY4ePMezABpQ;TZXO^PbUQL+?^vzc*j{h5Z@gpVk+jPVIa4Z`*Y8dhbpiZ&n@l z{9u?fX3Wnk<@}4{a^DZy<#__9(*Bvz6qvLM^gksOP^92$iAL3G-1|I^kXjGal@wMmN47q$h z4TCCZ;RVT5-?6G#oG`y`*Qp^2(E5)pxc*}cuK%?K*FWShwEou?T>oneuK)D~*FWShwEou@T>t9}uK$e%*FWSh zwEj01T>l$$um2=|X^XbxufFRZ@b9Gi+W?`T|JJ>bynmA&B;VoZ{0AJ9-LJdXf1Gsp zM{E~L+8?unH^lS5Ox~vp$zLh7^S0#Q{*WCfzvN!}`G3dQmgK(&mW;U9lRy1mH{C~y zyXX14caiV2?vaNl!Oxrb*+KGEelBpo#?Rf~!w)5Y^r4&1`L(e{#5#)s|A_W2Vx9?NPha_l#@WMh&OxYQzFnD^-b&03!R9#Zs6 zVvh-U{Lp*0BF;zmbRU0>SQ@=9&gp)-keRq{_N@OtMy9-%ep8Tj2KSZiV=8y1SUBtD zAK0HWRqbA3S^KX=6RKLOJcC1P>> zY@4@@o{x1}ywt%5(|nuYrxj(I?=#EurOL@(Bp%q$@&4N^7*3KV$Ui(u-m^R#AE5rV)SVJtcQVq5P+%2)f_F63nRr}Q9>?f7 zM#tX@ENKz-+U@OPHGS1tUe#0;Zxhg>0LK>=aN_}(z26$l-}9F?XazxID_yNy_UnqV zl`gS^y47j)>8}X!cPPqIWwpJ$wRCXp@M`m&=rt4Hv1{+*du@4jNxRm-5&`3Cclm78 zg)F6HKr$d1kPJu$Bmt0m*=5Kr$d1kPJu$ zBmNrTbq%1Vr?zHCZ0~Gw5|0>d_A$b5yv%+9!{s&!*Ojb9;1XuDhdVUE7LA5*r&B=JN||6rD(Do9xQQilWD8?7g94jE*FmrwUjKlMF}(Bm3FuE=4sBLr{rLMQkef;mAX?3nEQ8gM< zH=y?)LmwzCNLl04%eeTTH*{{AkzRrG`ywB<~sGU8_9uFl=zW?5@*@1WdntS~X j*7~3uKNv}u7`ZRnt4Nm{zK^p9b@u34ue1LLjcZR1 literal 0 HcmV?d00001 diff --git a/file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_empty_programName.nc b/file_checker_exec/src/test/netcdf-test-files/TEST_META_0004/1902735_meta_empty_programName.nc new file mode 100644 index 0000000000000000000000000000000000000000..8f648b1b21add62f9233eb29f0822bae10eff0d8 GIT binary patch literal 83516 zcmeHQ&2uBib;nwg^|7DPmz7ACCW>N{y977`fF!UoZGZr{i-`CT0PaRkB6tW4$+fxP1S5LoR|N8ao*ROkkOm_QBC=_}WpQrG78lNY#=~}K{%NKGu!FBeC| zzIZLJCfDiGCHmsmG&LHhQ_3Rrq?<0f#*&37YjI7BCg>~_x{J>fZn|}PGBr4lMRBYQ z&Na%0ggx%2XE{7EIQIne`}BC|3v|C&FQ+T%0-Y1ECyMoIu2?Nq`1yrmJyR-f=dTTt zg`UT~=Zf{6^lmY8{rK$=W%g9DUdUIg`BJfpGk1FyvP#u_4HrRCz4}(QmZP*(c*v<$ z(#7iFs(bw$?mdamV~**x3>;u1+%Kf<154R&S-PXN4M%V4j;`#REXi53(?jyUV_F@N z{)tSfk}vJ#3C$OKR^M*8nNeO(4f3Mop~nx+o@3cZbWHc(iK@}Hu$m03iJG={RgGU& zliyStwxN@R*A?$}vZh6^uEnp$;@?zSde2e%UEng5rG{mjR?F;hz<9EyIA+^W80@ZX zHH==*>>MnU$k0=^v2WN$2N&5nVOTnJobJ`t)py^0H=?8H^kDnIiCFf*YSwD>+eXJ> zaFF(ye$TM$ZN1aiTlL$9-ShGANGzgJre`x&=Qf_fEhdCyTqGXCNT6i4!&-!C=EbJb zu$stjB%dcUrEI#cZX|We4Lq4mcaQIv32P5vo0iD{YHCE=NF<`G@u-$ysuwzobX)jP z8%oz}ZAKnkg<|BiXb~s}quKDAqn}gI?QkpBq;{7v92FC}gwOuali%34<_Fz5EYS zo@E$!%e12hXTkTPz{i^;kUD7Q!eoR#MT}wM>0)^&T_gRe7k3L=IWngVC)wm_Jbr1L znY4b#{C3|^%qBI_ebcb%`EeLuzF8=7t1?KeTvgJ^JZy}^SxQ%~m8vUBsj`(R6$⪚WQ%Lu1(iL5*vPvyo%d|UaDOQDZ4%b=HFSl{_LA*j5Xahz2^eGaL;%K+5(=#n#tREeZ`B2LU#6WzhgyBLVUEEFY_z<}ERkYJd7+xwc_iZAAp!!1l zQ$K|Ki`zRTxG>dRB@YzE5-zd&3gY08s)lXCOYQXAdxkA4PFRN7%KuBqdb(PJGn1}l z>)e@gO)0|=#KCsefiI)mP2o#%Fpi}(jb6hx_h3t*PEF?fyY3cwg{-;^y>aMvj8x$LKmfliI>Fe%pb;(mO_jS-BvY zsZfYH{3P=l#<(YuN&Pt>2G$A5#E1E)>3SwttW`W8mEs0e&PnwVWBz*sE+0&f*-;vY z80ifRyF$apFdH@wMvTaAtgRnE{$b`bunedx?Jn|tyqp)5u{ID?Pp=Nwli6vQU6>FP z15J#_4|I&F32vbL6y(2;bdRTtr9%36pFK%Wl38ID^v;o@cdWMFGL4=B;|;^$1&hmboIuq9@R2g zu-WZuDin$mhVueLIh}dK9X`!eM^`ZJ-!~8XHuI0ku1^OPz)1*rVvhpPmk}kZRZ2TM zxk`PjME0J1n0mRAFQhBX>zb|KQ3Ow2+idIL31fT5wpuN8LVFha0>}!&qySSE>0TL+ zshY!ebV;5s7}OVfb=Sk_f;yzJsAj`O_+LGS%j=$p2qV1;!WJIePfsBadCtP$`$+fN z6r6q%XTiBT7Uy(AXTkZ8zKJxv_Z0-E0uE<#BLB@C66Fq+Z~SM1j&81)HTR9V6^3nq7G35DZx6F3WX9x z!1>H>wN^riXC$5!ST}C@8+}A#5oKW3YDF<4MnqZi1A~L8w5=v$Bz(m0h8kw6n?x4) z&hjYsy~L7UVzH#9-CAZ@5YsfeE$fJau$1SRc;tP?yS_#kFLI2CD4{;H%%8wzrrT7X z<6@A1vIEMTe$yLsu`Wh=_t5CTc_y%KKxA}`f39g9*oIN>ShjOWdEZ7K+N`%t7D;#Q z(V35L+{G=niTnB;_nhq2nbhF^sNTBwe{cTIP0s8a#_C_I;rx;)XQ_D2Ur=hplgjzp z4&uWz6m+zlXL&gdgy{*2D93O)_wUj@+Qj|gat`j#TF$?uym&d^%&@H4*EGLy`Ar1! zO$VWf4yG0Q9Sm$R&|E|V5+2Yv?DyMtNPo`{FxO}0`#B%qJx8|z7Iafd$G7d1 za!XC;9K*R=7VJ|0McXuPmydIcpo)3hbM3s|%+2f5Ss$KEWj9~VxdG-`{HU_P<2HCNK4W8a$R`cGYpy%fu={4uU=eUP3_-?!;ONYN zTM30W5g!S?;=^6ZZRaWoKIiIC0&+2UjGW3q<6F`J>f^`tO*cdtD6ljhc*6=an}+ZN zS|FRH^h$skHFKYrfSD2u?)c1aU>y*=O%-34a>cBep}vaXzj$$sv??plo zwsCrWpEm95g#BqhcA|fm4*+p*TH9MjJk9BQe(rtYUa4IzTJX3Kp%|Jxu#JXc-Zq*m zO66+BaBS1S3Gj^ei=-206ntT$W3<1or?7vC_lX#Cc#92k7-Wk81f{*;rk|=?%OVB= zAIvw-?dpi%7#Mgfn38q-P-KQJ0N+>c0$&#CzB~!vjr7hg_sB@O2;(%}zs#ncNnd6I zIErtK|MUg)bIng6_qj>r;U4jK9v|>M72hiX{NeE+&S+}?Usi||~;hcHd! zO9|o&&(FY7=$}JpzR^Nj!4Y4a;+vgy`vby6cqYZ@uI{=svpmj=&cR}XCF*Lq1?VXl zLQ$_UnDG z*bCl88EGCCeIM?)dO&3ive7SOFptXoGsGeNO$pDA;-I=bqu>i0j?oOxq!b)~(OXI6 z$|YV!JYy2SUlsaCg!YV14;@6?>USKF3HNu%qZwycC(LoJL39xA(A`kTUO~EZF7CRR z;iB>hoe=wR{hHTy{Md)5y2kbe6EL&&HvwEzwc8*1F_*Hr9h}dK`GSbIxm@GP@j5yI z;|8Ul0po4Lc!~4sMZ0iK;0&4zdT~Phh!kW7453sg^d4b&lC5^5o`s%r<&(jp@#Q&u zCh28V=;fd%p+?##y<`*T?)bWm@g!nN)N*>rZ9JFbecBjHAHXGbG4K5rUzfac4A$!r zmsA!~ifLt86=m`1sdLB{(lPWDCCAbjucXNCUi5aBwnk9DL*=+QD93IwUt^ApD2K2W zbUv=VX|Tl(b7%BM0}*YkX`sO{0(Dl4E&dZ8`%p;&^_A?vcM03m18nI`X19`dms&8L zC7y%u{b5?b;y&TM_+a-JRFKyb6PBSLz!^7LY5IwJu(M|^yb_;{&Y$@zu=nedvu`>RkY~6vTX=IC^CqwoECvy`9hG zdFMAPzRP}m4a?X^aM7d|&DQ|{qd*PGf%=p}l8*@Ei{mkRo%5{tBBF2ByWQ3ig=#Uq zJltfJ#(-i-o(bdswb&XKT1^{9z(ZFQS_-N~qHKYynp6|onu>+Zia1Yd(Y1Iit|(ek zjc&x&lzmN&t*S~wcf5@?`fwwS8L)PzzoZbvjq5Y#M3_0Y{Z;*p$)uaA*(x|j0Xic)In z`^r`+x0TyDUEvRiv>kIb-MV%Eg^4N6Fs)lqS|*KFn_(=Ar0&N(ZHQBSk_@J|_b*;i zV`@0M7LA=C3;C#IKr--U%t;KOvTC|d|_u_Z-2`Vqp@Wp^$E zYfkcrd9nAi^j7OgIj|`mf(>$$3`hn(pA688qN=8?tBH72RTbsqH~;lV#!r7y`uMBw zzwmd?FW(vG%+odBbBQQ-#Va?IvenYDl)|t(3!tN1)uxULI@SU}ea1!d`LL{s*;1O* z=Ce5vMxlhd#43}%dcP=Ehh1g3V8h>?Jig`>N}-tc|;WF3Wdv0 zvz15Hu3=zdTYL4?im!5OcP3dXa3?v z`OCDF7PBOoL!)tvitkoP-CYel$Lbg=f4cb&7MIdYP0iZsTSq$HiNuc?>=tWt(?Kr3 zOg}Hs;hx@{MGlok$aj5AQ4RIxo^B7No7V}KPp@e(+KB?D{->gS%0&Ge0)%(>vqslB zoP#=g!=6nCSjKy45GuLUB_IJ#EV-BSI zAaMD-{qYxzuj7qDo0crm+DY`ub2I^5{)oh?V?iBUlQ`eD$mQo7&~V3fL8^FFq;rt( z9GZLVHS4U=(vPZmb<5bn%4np_-PY+9|9VqDIGk2b;VgMZg=KHgOKmGzf&vrsQwMyZ9w>J`Tqb!bueH5pA=5$z?^E@qkQN<)c@%C zn*gEM^X+_rM97D@bf?LOKr9-SVM~1NIX6QtpHIV}3R-wUGTnEq8h)T)e%-ED2V><^ z130CT7?+=^Wy}3`*FWwk?eF)Dd6}Kj^83es6{Bn5MOFBK?nrR1I>^hv+dW0jy~6wS zpSQoQmfplqE6#u1Au#aryW`*OeyfES;IYJh&ZAx-ebD|{|3mUmXV~ol5c=;l$>On| zwtT4fj3WDyBLrc|?tjzj%xefVNxmmn!y8)eaBwdD!YuOLSj1e!3;UlL<=c%Q2B4eSs2_sRE>KUd|OMgBaMZwC3p%J=Dyj>gvi zfdBa_Utsy8^EE!R$X{svM_HpE7@yOw|LB72Kepidhx~=se{8|^A6sz!#}{1xkiXFS zk1x3X;|s3;wFTEd>vOOF6n<%ow$!hG;2!Yr zl>6HNp^tv&UP#@&&JI#<^KQ#O& zaKFaS-QU9xrGEN>o6h--yZ=CO_djO4Q0kZNxhRj=dvY)FbR1XeeV5qO62Jc8f3Snp z-nZD^d;aG?aue|HQ8}p>+#9JZ-wQcBy_b(UKAm^}hreM7QX(BMzjt4hQ>5ekdG|Ta zlt`C%EO?zE4=|s8sGXO8Fwe1=bxzp@uk-OQEm*`livjf-$Z_^!<7{%Ay;wh6j}?C`yH8`Qs#|%f&Ly+^h;uo33&X_d#)|Mh56Rm;_U+PnPF z96Tx7R;*?OrZKBlyw9DVrKm)o8%|ll)90{?2?WlVkqvIGIe>aSOtBhzTSphN6(#yOh1CjyB zfMh^2AQ_MhNCqSWk^#wpWI!_Ta4@hxZv21!z2(cjZ`;n27E!O<+$z;Fm!0KRO;zzW z0WAt}d|?4M9)Q{V&B6RVe`$kO5HvS4wT5NCt{9t{GCOEkoo1i@iV%N?qAXQc+sm6v z2UiX+@4p?rV&Xe?ekWI!??8ITM}1|$QL0m*=5Kr$d1kPJu$K06Gs_xm@oM1MW5 zt|g5tYIH?mZ~JeC*CVm@cuY+iVRg;D7~KqGML=vL5!*1r8s6(?FZ^$AL=wq(JP{X9 zXVTi{S|qWS+*nWGnnn+2((K`c7Ei<|A=VMFUjiV}T2zf`xW=U5cL8uMww_3C3?AOX z!?DPE4A&BXqv7GSx~WCh644EfU4aZpjYX2$ng%3cHBML9W3hEDxrRhq?6X6=L?RiG z3`hnf1CjyBfMh^2AQ_MhNCqSWl7UlYKvy@ziO6~~is8CDYSy*QXe7D5j$uB(z(&!@ zq_)AXtgk3~jK<#UD#qwYvT>?_r7+2WWI!??8ITM}1|$QL0m*=5Kr$d1kPJu$?wJAh zc0Wz)Z)_yvu_%V~>#r;9m3>U6N7wMmzsj%C+xwg0WMplFUrfBN9Iyoe(O4`RqdEN* zL-$AzO#zvf05UBEJ0q?oK=xybv+uTX@6B6mx;V48ITM}1|$QL0m*=5 zKr$d1kPJu$BmXK3#ESkBlrIA&EL^MYEFA(edYwkeIOo9{mVZP#i7qpoqgef zApQh}Nd5W;84ac5eB1{%11w*iJmQJI-u&W<8=viqibVKct$Zh8gk4BsI=#7A9I`OKK0v z);60nR!(zRY!bjgE(s7I3pkem0TKi`&6zt^sxr3na)TIqbneHh>TLUUgNo zMUiaINYp}}*8-(rsB7j>Cy%IlGhUPWQtB-ps$mDy5y2brcu`FS|WLq&NS^YJ}3Ni%k*S=aK4zt zu|7CYP&Op&Wk0>h;l$uP5G?Q0cP!6rnVzX{+9JtmyW2zZzGpjK zmHvcLt`^E`1w!*u&*{5OKQqef)F3ZPuD!f%_dLhlrDMAPSu&nnnvbXE6RCP4bvt$A zc6|B!degN`lJI-FxSdGOCzk8+rQ6Bn+sVZD^|smb^!^TTS^Cwcj^kW`%1rOxs8t5?VIh!L(A=jczAv>mY_^e8&3Bjp2004gk+p29_EoiH}dm| zm}r^jTUOI)A-kb`P8#KGrV+oH+@jpTlil+7_t^afWz{k_-Kt{}J-Ma3@pBu9VAnLz0P?D7lveFWY9fwc$7q!jjRZ zBFap%{{%A53Y%tBa~V=oT)-xb6ZVtpgk)Q~vng~i&<*jpHmZKk-N#leX0vzhkev_- zqcBpve1Vjw1;+IX?dZX2@V%+T2{4_ntYzxdej26q;!2LpslZ7# zc@mGW=Y>h@ckLhcE!}RBif-DLOV5wu@$FBFWocCgiS^rh=2n3=dMvW;focBlk?#3Q zy-w+gPtrZYIj)Vz>aN-Cb!?a|ryIhlU(Hlk%eCuzxw>MMi^c1@3(`q!`D*Ut^<2rgPtOi> zG|qNj&AS#_R=2rJ%DM;1rt5SBKGCZp&lka?=XXIO{};C{*ZU)q7L66U8v9SAyEwAP z_wkayqV!>0onEXsJ)3$d^p3JJNqi(%B>!uq8|Yy^Q!K0ruEOnm98a$quxDFv0*EH^ zCtT6R3fZId@b!`XO;U7r5p9m(EWCiPvw_Xn+aId-HV*6AI=Vt(d&zbPh$C&q7>tYb zLyUM^ zR);f_sb(9}net7kz!1ejzUIM~G2NE(r6d^7(OXup>Dn8xrD#qq;rsjU7I}rDx-7G~ z?RSh+SIy(?@hRTFgvwd;(~fI*Oz?!Uz2`dZHaejV2Ymr#MPbr`>E}rI&S*@v z9Im5F3Vgw+zA&h}9!3|`A&o>e9j)n00g6??_Vbrdou+5L`rzenyJg49V^&PR8U_XjQSUe{#7N|b-w!oRQ#Ut% z4t%F&6#GeHNtZ<|>FRpjxTc6{SvzfKmx8dA=ZJXZQ^vdACyeJMMnsfQpIPBg;Ie4j zRG*__kiWAA%DjFn7;}j(Mt`(zb>Tb{SU(^#JjOrMvbJ2yYIGgf+orr9q7Q8~I<|>FYL@Ba_ZFQ{^sORM36k`9k6 z=an_Yho>m$a5+!Qa#{$}6BJdBz2)3|O!sJ0_xF}_aDUozeocAFa(--xti{(Pzwp|} z2;|!yLJ?g|EA+b<*kH(GUH7LDNCVoA-}?RhMzz1u{-6j?MCl663%&mhvc^1Crdn?( zRS`CpBu>J9eZQ`3+AgL>Xaom!Q3|9ypi$VLQg=QeY-b0U8`JWADa3crGhKiM-IUvC z-98|6Vt z=fT6+hHU`lIj7?b8y!E^v=6Rg|7r-2QC%<8a(;k$8b7L{@c0TJ#AjTL4&|g_aLspT znr`3jSt0`Nhat%L4;&rfiNdV|_unGjJ0aZFTs~Jt@Hy8&BOn(;#>lA*G`^k0={;2j z3M`EV-gM@LO+$DB8YpHdgA!my&EAwH5T*o!J2~?kSr&r#!N20`LavlmGt^I_bMyOk z&Vm7k>!{{J!d@fq$?1xtCx?a6qwLI6hZ~{D0Z43JMA;n8B%RUi9j$pAt4ufnJfFS)jhfkEg zUQ;m$_+X)N?v9E0jfH`?jwxBc4@G9!BJjP5Bp;Fw_SQIj_cCki(j%kBMHnZw{qKos zXKF9g0UX9R!hf3kM@_p=7%z<@5BG?_v-m{u_f7UY;!BU>3(rr%k#<#^d+#fxRUFC1DWTa}zds;MglAlg?)JJrGb`h~=o}m|SfZ|0 zT7aI8Ar$orgBd^N-Hf&cznzH1Vx{YP0`s=Mb426KHkzx-5`eG`my_ypPMiDjm)O(s z3n(M`mx^~)Mw*93--kPXJD@T~+2}V6%%ckb3~|V?D&g5-98{NcI=-;s7-}&0-mh@{ zQm~T9mrJ}-`<=w^cUAi%LVH%XhYq6S^t&F&g!{Y4qZwsa$INjpL2MLm?XjkPO4!c$ zxEpGQi^``ktNkcnA<&&L_PtYGBm06en8o^=2(GExKm8(%xtz_d;e1-m=TyAS=NeCr zZlhx`-k|hTVB8>#7bLGivKp6Qe?n3J*2XGx*T?D1H8}f$++PoDsq57=Qfi z&-o9xy9jJ)h>yF)Q}w6p3+G2 zcZBiH(HH|~VOo4KwCugdDp0mYC!6~_PmO021&)xGlwz?iyDOH&iE zq*!npPbKh|x)ER2#d#u`SdK3xmy-!yU%C~)fxCL@)~%&w+<#WLLbZ@BtQUjgcNak7 zgl+i#YNaMpt9-;f#)Rj;?YA=3d*$kcLYD64Cfxn@--6!7Gx4Rd1+7{SZLwZ70VTzj zDI}NU@%dybUya9;`yU%_k4v%Cjc}@)sgz#1bH7$7WnojpccwoUHYSf(4~(a)yFy;q zYo4`(W!JW)<1GU$ovvo5m(MA|UnXDI*D%*=_d7aX7PzV3dm>trSv>tjPwY)xSXvz4 zX!j-^d1fRR6Y==1`FMOeJ~9DcWCoZ4W?&2hwL9g3lQt&Jq{|0=-nf%9?&h*OR_f|< ztz;3W^*iVilktT_Vu4<9n}mSxF$2uNabj;h>f|Or0KNnTdle3aXReX$E z#iV!)oE8_@Sd@4;W^yX|VX<{5Ygs#oBOELQ^2ItXX$ER-8$Ws9FLX1uTO6!d@Y^8fI=$W5 z_JL#MA6ZW@M!x8FXYPEUSxfn{X0hV#p#@)*#AjM9;fI**jOc`VjV3z8!`1{TzihYf zVWmWegrn{S4qt4e+4*$wu%!<2lkzM5&Wg zgg6kE@bCr879iy-#silRzeCaU0&j3;;#K|clV20>yUrefEPqM-)p=zUpgGM9m~QShna`?PQLV5_u9{ERKe5L;?@MUaU z%?G0Q_s!nSU64KHzlR^0!ppqvpc0^p$}&lB;ILzZQa+YDQK_B&5rlj~wIB4qcXnH@ z*~hS##{J>JSYyUx5m|m!|K-iip5=w2VO0y~w8#(3Sr60iS0pI;f&Vqe|3FI!#t0%( zdPok5ly5lQu5ai`K6;^9lvR~EyjSIy_BYT!X%J@)L&}%pj$Q$!d=Yr*nr+n%L(5(b zta?q%Y!En|{N$|VXKlPiM^j-l6BKTAp<`Koia$dIYo4>Cs$h0LXGpy2e@4i!wEIWk z0;N~ev?h5j{iWDz!T!%~(sk`4`D+Df@w$tqr9Tvx2iLERK2PuZ*VBLT3vrP4Pqlq} z`9rJncCbs!AI?e3{M8L5KTU68V@v<3-2blJySg|?|M;=L|Jfh-dx<;!*W2PeDA#3i zI>5Ce&uzIc$o(z3mw43gJf!{0n!=gRKNeS1{_?h#{>5A3F#V~2CBT2eKmX|Kzxtd1 zsQvH1{nU8ur<2#y{%tM&f`6deE6-Qbd(TI!tE9J*f7xIB+UARXZT3>EgE!X7#@$Ad ze*Qgd%LG65EPlvo{6Yg5x(0swyfXZpI;Zs7S|Jl$er68P{!hMM^8Jn~mJnH^Pr|AihO!BR!$!3!8HO=#t+QHTZ4D9!4 z|8W`&2T4Qz*jFJJfEi#0m;q*h8DIvO0cL<1UU`D0L=nL_-3haw&_ literal 0 HcmV?d00001 From fae06324dc3ca46c553751e32353b3a5e7f893e2 Mon Sep 17 00:00:00 2001 From: Yvan Lubac Date: Tue, 16 Dec 2025 10:57:21 +0100 Subject: [PATCH 3/5] add DK for coriolis DAC --- .../main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java b/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java index 543eb8b..fa4b251 100644 --- a/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java +++ b/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java @@ -151,7 +151,7 @@ public static enum DACS { static { DacCenterCodes.put(DACS.AOML, "AO MB NA PM SI UW WH"); DacCenterCodes.put(DACS.BODC, "BO"); - DacCenterCodes.put(DACS.CORIOLIS, "AW GE IO IF LV RU SP VL"); + DacCenterCodes.put(DACS.CORIOLIS, "AW GE IO IF LV RU SP VL DK"); DacCenterCodes.put(DACS.CSIO, "HZ"); DacCenterCodes.put(DACS.CSIRO, "CS"); DacCenterCodes.put(DACS.INCOIS, "IN"); From ced603d88df7e8e75703c9cc43fc2acef5f5a5aa Mon Sep 17 00:00:00 2001 From: Yvan Lubac Date: Tue, 16 Dec 2025 10:57:59 +0100 Subject: [PATCH 4/5] prepare 2.9.5 release --- file_checker_exec/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/file_checker_exec/pom.xml b/file_checker_exec/pom.xml index 19f840e..4a33159 100644 --- a/file_checker_exec/pom.xml +++ b/file_checker_exec/pom.xml @@ -4,7 +4,7 @@ 4.0.0 fr.ifremer file_checker_exec - 2.9.5-SNAPSHOT + 2.9.5 Argo NetCDF file format checker From 33bdb70337e04f7616ba3efabc37e881a512bf2a Mon Sep 17 00:00:00 2001 From: Yvan Lubac Date: Tue, 16 Dec 2025 14:44:40 +0100 Subject: [PATCH 5/5] add EA for coriolis dac --- .../main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java b/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java index fa4b251..97dc5df 100644 --- a/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java +++ b/file_checker_exec/src/main/java/fr/coriolis/checker/specs/ArgoReferenceTable.java @@ -151,7 +151,7 @@ public static enum DACS { static { DacCenterCodes.put(DACS.AOML, "AO MB NA PM SI UW WH"); DacCenterCodes.put(DACS.BODC, "BO"); - DacCenterCodes.put(DACS.CORIOLIS, "AW GE IO IF LV RU SP VL DK"); + DacCenterCodes.put(DACS.CORIOLIS, "AW GE IO IF LV RU SP VL DK EA"); DacCenterCodes.put(DACS.CSIO, "HZ"); DacCenterCodes.put(DACS.CSIRO, "CS"); DacCenterCodes.put(DACS.INCOIS, "IN");