diff --git a/cmake/TestMain.cmake b/cmake/TestMain.cmake index 9b841010..0099c472 100644 --- a/cmake/TestMain.cmake +++ b/cmake/TestMain.cmake @@ -8,7 +8,10 @@ # if(${USE_ZIP} STREQUAL "YES") - execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json) + # clean-up : delete the zip archive and the previous unzipped files + execute_process(COMMAND rm -f res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json) + + execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/res_to_zip/TestIIDM_${TEST_NAME}.iidm res/res_to_zip/config_${TEST_NAME}.json) set(_command ${EXE} --network=TestIIDM_${TEST_NAME}.iidm --config=config_${TEST_NAME}.json --input-archive=res/${TEST_NAME}.zip) else() set(_command ${EXE} --network=res/TestIIDM_${TEST_NAME}.iidm --config=res/config_${TEST_NAME}.json) diff --git a/cmake/TestMainNSA.cmake b/cmake/TestMainNSA.cmake index 60d222b7..d61499e6 100644 --- a/cmake/TestMainNSA.cmake +++ b/cmake/TestMainNSA.cmake @@ -8,7 +8,10 @@ # if(${USE_ZIP} STREQUAL "YES") - execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json res/contingencies_${TEST_NAME}.json) + # clean-up : delete the zip archive and the previous unzipped files + execute_process(COMMAND rm -f res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json res/contingencies_${TEST_NAME}.json) + + execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/res_to_zip/TestIIDM_${TEST_NAME}.iidm res/res_to_zip/config_${TEST_NAME}.json res/res_to_zip/contingencies_${TEST_NAME}.json) set(_dfl_cmd ${EXE} --network=TestIIDM_${TEST_NAME}.iidm --config=config_${TEST_NAME}.json --contingencies=contingencies_${TEST_NAME}.json --input-archive=res/${TEST_NAME}.zip --nsa) else() set(_dfl_cmd ${EXE} --network=res/TestIIDM_${TEST_NAME}.iidm --config=res/config_${TEST_NAME}.json --contingencies=res/contingencies_${TEST_NAME}.json --nsa) diff --git a/cmake/TestMainSA.cmake b/cmake/TestMainSA.cmake index 6dbbb8c8..e553795a 100644 --- a/cmake/TestMainSA.cmake +++ b/cmake/TestMainSA.cmake @@ -8,7 +8,10 @@ # if(${USE_ZIP} STREQUAL "YES") - execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json res/contingencies_${TEST_NAME}.json) + # clean-up : delete the zip archive and the previous unzipped files + execute_process(COMMAND rm -f res/${TEST_NAME}.zip res/TestIIDM_${TEST_NAME}.iidm res/config_${TEST_NAME}.json res/contingencies_${TEST_NAME}.json) + + execute_process(COMMAND zip -j res/${TEST_NAME}.zip res/res_to_zip/TestIIDM_${TEST_NAME}.iidm res/res_to_zip/config_${TEST_NAME}.json res/res_to_zip/contingencies_${TEST_NAME}.json) set(_dfl_cmd ${EXE} --network=TestIIDM_${TEST_NAME}.iidm --config=config_${TEST_NAME}.json --contingencies=contingencies_${TEST_NAME}.json --input-archive=res/${TEST_NAME}.zip) else () set(_dfl_cmd ${EXE} --network=res/TestIIDM_${TEST_NAME}.iidm --config=res/config_${TEST_NAME}.json --contingencies=res/contingencies_${TEST_NAME}.json) diff --git a/etc/Dictionaries/DFLError_en_GB.dic b/etc/Dictionaries/DFLError_en_GB.dic index 6f012db8..7382241d 100644 --- a/etc/Dictionaries/DFLError_en_GB.dic +++ b/etc/Dictionaries/DFLError_en_GB.dic @@ -44,3 +44,5 @@ ConnexityError = slack node of id %1% not present in main conn NetworkHasNoRegulatingGenerator = network file %1% has no generator regulating voltage in the main connex component SlackNodeNotFound = no slack node found for network '%1%' FailToOpenLogFile = failed to open %1% log file +FileNotFound = file %1 not found +LibZipError = zip error for file %1 : %2 diff --git a/scripts/diff.py b/scripts/diff.py index 7648eada..23b1763c 100644 --- a/scripts/diff.py +++ b/scripts/diff.py @@ -56,13 +56,14 @@ def get_argparser(): except KeyError: pass + results_root = os.path.realpath(os.path.join(options.root, "resultsTestsTmp", options.testdir)) + reference_root = os.path.realpath(os.path.join(options.root, "reference", options.testdir)) + if options.output_zip: - zip_archive_parent_directory = os.path.join(options.root, "resultsTestsTmp", options.testdir) - zip_archive_path = os.path.join(zip_archive_parent_directory, options.output_zip) - unzipped_archive_path = zip_archive_parent_directory + zip_archive_path = os.path.join(results_root, options.output_zip) try: with zipfile.ZipFile(zip_archive_path, "r") as zip_ref: - zip_ref.extractall(unzipped_archive_path) + zip_ref.extractall(results_root) except FileNotFoundError: print("[ERROR] " + zip_archive_path + " is missing") nb_differences += 1 @@ -73,72 +74,63 @@ def get_argparser(): is_constraints_generated = (buildType == "Debug" or (buildType == "Release" and "CONSTRAINTS" in chosen_outputs)) is_lost_equipement_generated = (buildType == "Debug" or (buildType == "Release" and "LOSTEQ" in chosen_outputs)) - results_root = os.path.realpath(os.path.join(options.root, "resultsTestsTmp", options.testdir)) - reference_root = os.path.realpath(os.path.join(options.root, "reference", options.testdir)) - - outputiidm_result_paths = list() - outputiidm_result_paths.append(os.path.realpath(os.path.join(results_root, "outputs/finalState/outputIIDM.xml"))) + outputiidm_result_path = os.path.realpath(os.path.join(results_root, "outputs/finalState/outputIIDM.xml")) outputiidm_reference_path = os.path.realpath(os.path.join(reference_root, "outputIIDM.xml")) if not os.path.exists(outputiidm_reference_path): print("Reference path " + outputiidm_reference_path + " does not exist : not checked") else: - for outputiidm_result_path in outputiidm_result_paths: - if options.verbose: - print("comparing " + outputiidm_result_path + " and " + outputiidm_reference_path) + if options.verbose: + print("comparing " + outputiidm_result_path + " and " + outputiidm_reference_path) - (nb_differences_local, msg) = iidmDiff.OutputIIDMCloseEnough(outputiidm_result_path, outputiidm_reference_path) - if nb_differences_local > 0: - print("[ERROR] " + outputiidm_result_path + ": " + msg) - elif options.verbose: - print("No difference") - nb_differences += nb_differences_local + (nb_differences_local, msg) = iidmDiff.OutputIIDMCloseEnough(outputiidm_result_path, outputiidm_reference_path) + if nb_differences_local > 0: + print("[ERROR] " + outputiidm_result_path + ": " + msg) + elif options.verbose: + print("No difference") + nb_differences += nb_differences_local # dyd and par nb_differences += compare_dyd_and_par_files(results_root, reference_root, options.verbose) if is_constraints_generated: #constraints - constraints_result_paths = list() - constraints_result_paths.append(os.path.realpath(os.path.join(results_root, "outputs/constraints/constraints.xml"))) + constraints_result_path = os.path.realpath(os.path.join(results_root, "outputs/constraints/constraints.xml")) constraints_reference_path = os.path.realpath(os.path.join(reference_root, "constraints.xml")) if not os.path.exists(constraints_reference_path): print("Reference path " + constraints_reference_path + " does not exist : not checked") else: - for constraints_result_path in constraints_result_paths: - if options.verbose: - print("comparing " + constraints_result_path + " and " + constraints_reference_path) - - (nb_differences_local, msg) = constraintsDiff.output_constraints_close_enough(constraints_result_path, constraints_reference_path) - if nb_differences_local > 0: - print("[ERROR] constraints file " + constraints_result_path + " different from reference file " + constraints_reference_path) - print(msg) - elif options.verbose: - print("No difference") - nb_differences += nb_differences_local + if options.verbose: + print("comparing " + constraints_result_path + " and " + constraints_reference_path) + + (nb_differences_local, msg) = constraintsDiff.output_constraints_close_enough(constraints_result_path, constraints_reference_path) + if nb_differences_local > 0: + print("[ERROR] constraints file " + constraints_result_path + " different from reference file " + constraints_reference_path) + print(msg) + elif options.verbose: + print("No difference") + nb_differences += nb_differences_local if is_lost_equipement_generated: #lost equipments - lost_equipments_result_paths = list() - lost_equipments_result_paths.append(os.path.realpath(os.path.join(results_root, "outputs/lostEquipments/lostEquipments.xml"))) + lost_equipments_result_path = os.path.realpath(os.path.join(results_root, "outputs/lostEquipments/lostEquipments.xml")) lost_equipments_reference_path = os.path.realpath(os.path.join(reference_root, "lostEquipments.xml")) if not os.path.exists(lost_equipments_reference_path): print("Reference path " + lost_equipments_reference_path + " does not exist : not checked") else: - for lost_equipments_result_path in lost_equipments_result_paths: - if options.verbose: - print("comparing " + lost_equipments_result_path + " and " + lost_equipments_reference_path) - - # compare line per line with universal newline, stop at first diff - with open(lost_equipments_result_path) as f1, open(lost_equipments_reference_path) as f2: - identical = all(l1 == l2 for l1, l2 in zip_longest(f1, f2)) - if identical: - print("No difference") - else: - print("[ERROR] lost equipments file " + lost_equipments_result_path + " different from reference file " + lost_equipments_reference_path) - nb_differences += 1 + if options.verbose: + print("comparing " + lost_equipments_result_path + " and " + lost_equipments_reference_path) + + # compare line per line with universal newline, stop at first diff + with open(lost_equipments_result_path) as f1, open(lost_equipments_reference_path) as f2: + identical = all(l1 == l2 for l1, l2 in zip_longest(f1, f2)) + if identical: + print("No difference") + else: + print("[ERROR] lost equipments file " + lost_equipments_result_path + " different from reference file " + lost_equipments_reference_path) + nb_differences += 1 else: raise UnknownBuildType(buildType) diff --git a/scripts/diffContingencies.py b/scripts/diffContingencies.py index 90af59e9..37d64f0d 100644 --- a/scripts/diffContingencies.py +++ b/scripts/diffContingencies.py @@ -48,17 +48,6 @@ def compare_file(options, contingency_folder, chosen_outputs): if buildType == "Debug" or buildType == "Release" or buildType == "Coverage": - if options.output_zip: - zip_archive_parent_directory = os.path.join(options.root, "resultsTestsTmp", options.testdir) - zip_archive_path = os.path.join(zip_archive_parent_directory, options.output_zip) - unzipped_archive_path = zip_archive_parent_directory - try: - with zipfile.ZipFile(zip_archive_path, "r") as zip_ref: - zip_ref.extractall(unzipped_archive_path) - except FileNotFoundError: - print("[ERROR] " + zip_archive_path + " is missing") - nb_differences += 1 - if buildType == "Debug" or (buildType == "Release" and "STEADYSTATE" in chosen_outputs) or buildType == "Coverage": # output IIDM result_path = full_path( @@ -158,6 +147,15 @@ def full_path(a, *paths): results_root = full_path(options.root, "resultsTestsTmp", options.testdir) reference_root = full_path(options.root, "reference", options.testdir) + if options.output_zip: + zip_archive_path = os.path.join(results_root, options.output_zip) + try: + with zipfile.ZipFile(zip_archive_path, "r") as zip_ref: + zip_ref.extractall(results_root) + except FileNotFoundError: + print("[ERROR] " + zip_archive_path + " is missing") + total_diffs += 1 + print(results_root) for folder in os.listdir(results_root): if os.path.isdir(os.path.join(results_root, folder)): diff --git a/sources/Common/include/Options.h b/sources/Common/include/Options.h index 1fdd4c0c..1cec4dee 100644 --- a/sources/Common/include/Options.h +++ b/sources/Common/include/Options.h @@ -20,17 +20,11 @@ * @brief Options header file */ -namespace zip { -class ZipFile; -} - /// @brief Namespace for dynaflow launcher components namespace dfl { /// @brief Namespace for common components to dynawo-launcher namespace common { -namespace po = boost::program_options; - /** * @brief Manager for input programm options * @@ -94,19 +88,6 @@ class Options { */ Request parse(int argc, char* argv[]); - /** - * @brief Check whether all required files are present in the specified archive - * - * This method checks if the zip archive contains all files required for execution, such as the network file, - * configuration file, and optionally the contingencies file. - * - * @param vm A variables map containing the input arguments passed to Dynaflow-launcher. It is used to determine if the optional contingencies file is required. - * @param archive A shared pointer to the zip archive to be checked. - * - * @returns true if one or more required files are missing, false otherwise - */ - bool areRequiredFilesMissing(const po::variables_map& vm, const boost::shared_ptr& archive) const; - /** * @brief Retrieves description of options * diff --git a/sources/main.cpp b/sources/main.cpp index 0a364d31..affde514 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -156,7 +157,7 @@ void dumpZipArchive(std::unordered_map &mapOutputFiles boost::shared_ptr archive = zip::ZipFileFactory::newInstance(); const std::string archivePath = createAbsolutePath("outputs.zip", outputPath.generic_string()); - if (!runtimeConfig.contingenciesFilePath.empty()) + if (!runtimeConfig.contingenciesFilePath.empty() && boost::filesystem::exists(archivePath)) archive = zip::ZipInputStream::read(archivePath); for (const std::pair &outputFile : mapOutputFilesData) { archive->addEntry(outputFile.first, outputFile.second); @@ -204,7 +205,26 @@ int main(int argc, char *argv[]) { boost::filesystem::path contingencyPath(runtimeConfig.contingenciesFilePath); if (!runtimeConfig.zipArchivePath.empty()) { if (mpiContext.isRootProc()) { - boost::shared_ptr archive = zip::ZipInputStream::read(runtimeConfig.zipArchivePath); + boost::shared_ptr archive; + try { + try { + archive = zip::ZipInputStream::read(runtimeConfig.zipArchivePath); + } catch (const zip::ZipException& e) { + switch (e.getErrorCode()) { + case zip::Error::Code::LIBARCHIVE_INTERNAL_ERROR: + throw Error(LibZipError, runtimeConfig.zipArchivePath, e.what()); + case zip::Error::Code::FILE_NOT_FOUND: + throw Error(FileNotFound, e.what()); + default: + // other libzip errors + throw; + } + } + } catch (std::exception& e) { + std::cerr << "Initialization failed: " << e.what() << std::endl; + return EXIT_FAILURE; + } + std::string archiveParentPath = boost::filesystem::path(runtimeConfig.zipArchivePath).parent_path().string(); for (std::map>::const_iterator archiveIt = archive->getEntries().begin(); archiveIt != archive->getEntries().end(); ++archiveIt) { diff --git a/tests/main/res/TestIIDM_launch_archive.iidm b/tests/main/res/res_to_zip/TestIIDM_launch_archive.iidm similarity index 100% rename from tests/main/res/TestIIDM_launch_archive.iidm rename to tests/main/res/res_to_zip/TestIIDM_launch_archive.iidm diff --git a/tests/main/res/config_launch_archive.json b/tests/main/res/res_to_zip/config_launch_archive.json similarity index 100% rename from tests/main/res/config_launch_archive.json rename to tests/main/res/res_to_zip/config_launch_archive.json diff --git a/tests/main_n_sa/res/TestIIDM_launch_archive.iidm b/tests/main_n_sa/res/res_to_zip/TestIIDM_launch_archive.iidm similarity index 100% rename from tests/main_n_sa/res/TestIIDM_launch_archive.iidm rename to tests/main_n_sa/res/res_to_zip/TestIIDM_launch_archive.iidm diff --git a/tests/main_n_sa/res/config_launch_archive.json b/tests/main_n_sa/res/res_to_zip/config_launch_archive.json similarity index 100% rename from tests/main_n_sa/res/config_launch_archive.json rename to tests/main_n_sa/res/res_to_zip/config_launch_archive.json diff --git a/tests/main_n_sa/res/contingencies_launch_archive.json b/tests/main_n_sa/res/res_to_zip/contingencies_launch_archive.json similarity index 100% rename from tests/main_n_sa/res/contingencies_launch_archive.json rename to tests/main_n_sa/res/res_to_zip/contingencies_launch_archive.json diff --git a/tests/main_sa/res/TestIIDM_launch_archive.iidm b/tests/main_sa/res/res_to_zip/TestIIDM_launch_archive.iidm similarity index 100% rename from tests/main_sa/res/TestIIDM_launch_archive.iidm rename to tests/main_sa/res/res_to_zip/TestIIDM_launch_archive.iidm diff --git a/tests/main_sa/res/config_launch_archive.json b/tests/main_sa/res/res_to_zip/config_launch_archive.json similarity index 100% rename from tests/main_sa/res/config_launch_archive.json rename to tests/main_sa/res/res_to_zip/config_launch_archive.json diff --git a/tests/main_sa/res/contingencies_launch_archive.json b/tests/main_sa/res/res_to_zip/contingencies_launch_archive.json similarity index 100% rename from tests/main_sa/res/contingencies_launch_archive.json rename to tests/main_sa/res/res_to_zip/contingencies_launch_archive.json