Skip to content

Commit

Permalink
#810 Add the possibility to zip the inputs and outputs for N simulation
Browse files Browse the repository at this point in the history
Signed-off-by: Dimitri Baron <[email protected]>
  • Loading branch information
barondim committed Dec 17, 2024
1 parent 901fea6 commit 4aad721
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 16 deletions.
4 changes: 4 additions & 0 deletions etc/Dictionaries/DFLError_en_GB.dic
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
//

//------------------ Inputs -------------------------
AlreadyInitializedNetworkFileInput = network file is already initialized
AlreadyInitializedConfigFileInput = config file is already initialized
AlreadyInitializedContingenciesInput = contingencies file is already initialized
NoConfigFileFound = no config file found
ErrorConfigFileRead = error while reading configuration file: %1%
StartingPointModeDoesntExist = starting point mode %1% doesn't exist
SettingFileWithoutAssemblingFile = %1% contains a setting file but not an assembling file
Expand Down
21 changes: 15 additions & 6 deletions scripts/envDFL.sh
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,22 @@ launch() {
if [ ! -f "$2" ]; then
error_exit "IIDM network file $2 doesn't exist"
fi
if [ ! -f "$3" ]; then
error_exit "DFL configuration file $3 doesn't exist"

if [[ "$2" == *.zip ]]; then
echo "$DYNAFLOW_LAUNCHER_INSTALL_DIR/bin/DynaFlowLauncher --log-level $DYNAFLOW_LAUNCHER_LOG_LEVEL --input-archive $2"

$DYNAFLOW_LAUNCHER_INSTALL_DIR/bin/DynaFlowLauncher \
--log-level $DYNAFLOW_LAUNCHER_LOG_LEVEL \
--input-archive $2
else
if [ ! -f "$3" ]; then
error_exit "DFL configuration file $3 doesn't exist"
fi
$DYNAFLOW_LAUNCHER_INSTALL_DIR/bin/DynaFlowLauncher \
--log-level $DYNAFLOW_LAUNCHER_LOG_LEVEL \
--network $2 \
--config $3
fi
$DYNAFLOW_LAUNCHER_INSTALL_DIR/bin/DynaFlowLauncher \
--log-level $DYNAFLOW_LAUNCHER_LOG_LEVEL \
--network $2 \
--config $3
}

launch_gdb() {
Expand Down
1 change: 1 addition & 0 deletions sources/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ target_link_libraries(dfl_Common

PRIVATE
Boost::filesystem
libZIP::libZIP
)
add_library(DynaFlowLauncher::common ALIAS dfl_Common)
install(FILES ${CMAKE_SOURCE_DIR}/etc/Dictionaries/DFLLog_en_GB.dic ${CMAKE_SOURCE_DIR}/etc/Dictionaries/DFLError_en_GB.dic DESTINATION share)
Expand Down
2 changes: 1 addition & 1 deletion sources/Common/include/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#pragma once

#include <boost/optional.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
Expand Down Expand Up @@ -44,6 +43,7 @@ class Options {
std::string contingenciesFilePath; ///< Contingencies filepath for security analysis
std::string configPath; ///< Launcher configuration filepath
std::string dynawoLogLevel; ///< chosen log level
std::string zipArchive;
};

/**
Expand Down
107 changes: 98 additions & 9 deletions sources/Common/src/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@
*/

#include "Options.h"

#include "Log.h"
#include "version.h"

#include <libzip/ZipInputStream.h>

#include <DYNFileSystemUtils.h>

#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <sstream>


namespace dfl {
namespace common {

Expand Down Expand Up @@ -81,14 +88,16 @@ Options::basename(const std::string& filepath) {
return path.filename().replace_extension().generic_string();
}

Options::Options() : desc_{}, config_{"", "", "", "", defaultLogLevel_} {
desc_.add_options()("help,h", "Display help message")(
"log-level", po::value<ParsedLogLevel>(),
(std::string("Dynawo logger level (allowed values are ERROR, WARN, INFO, DEBUG): default is ") + defaultLogLevel_).c_str())(
"network", po::value<std::string>(&config_.networkFilePath)->required(), "Network file path to process (IIDM support only)")(
"contingencies", po::value<std::string>(&config_.contingenciesFilePath), "Contingencies file path to process (Security Analysis)")(
"config", po::value<std::string>(&config_.configPath)->required(), "launcher Configuration file to use")("version,v", "Display version")(
"nsa", "Run steady state calculation followed by security analysis. Requires contingencies file to be defined.");
Options::Options() : desc_{}, config_{"", "", "", "", defaultLogLevel_, ""} {
desc_.add_options()
("help,h", "Display help message")
("log-level", po::value<ParsedLogLevel>(),
(std::string("Dynawo logger level (allowed values are ERROR, WARN, INFO, DEBUG): default is ") + defaultLogLevel_).c_str())
("network", po::value<std::string>(&config_.networkFilePath), "Network file path to process (IIDM support only)")
("contingencies", po::value<std::string>(&config_.contingenciesFilePath), "Contingencies file path to process (Security Analysis)")
("config", po::value<std::string>(&config_.configPath), "launcher Configuration file to use")
("version,v", "Display version")("nsa", "Run steady state calculation followed by security analysis. Requires contingencies file to be defined.")
("input-archive", po::value<std::string>(&config_.zipArchive), "zip archive");
}

Options::Request
Expand All @@ -106,8 +115,86 @@ Options::parse(int argc, char* argv[]) {
return Request::VERSION;
}

if (!vm.count("network") && !vm.count("config") && !vm.count("input-archive")) {
DYN::Trace::error(dfl::common::Log::getTag()) << "No input provided" << DYN::Trace::endline;
return Request::HELP;
}

int option_error = false;
if ((vm.count("network") && !vm.count("config")) || (vm.count("config") && !vm.count("network"))) {
option_error = true;
DYN::Trace::error(dfl::common::Log::getTag()) << "--network and --config must be used together" << DYN::Trace::endline;
}

if ((vm.count("network") || vm.count("config")) && vm.count("input-archive")) {
option_error = true;
DYN::Trace::error(dfl::common::Log::getTag()) << "--network and --config options can't be used with --input-archive" << DYN::Trace::endline;
}

po::notify(vm);

if (option_error) {
return Request::ERROR;
}

if (!config_.networkFilePath.empty() && !config_.configPath.empty()) {
// nothing to do
} else if (!config_.zipArchive.empty()) {
std::vector<std::string> zipArchiveFiles;
boost::shared_ptr<zip::ZipFile> archive = zip::ZipInputStream::read(config_.zipArchive);
std::string archiveParentPath = boost::filesystem::path(config_.zipArchive).parent_path().string();
for (std::map<std::string, boost::shared_ptr<zip::ZipEntry>>::const_iterator itE = archive->getEntries().begin();
itE != archive->getEntries().end(); ++itE) {
std::string name = itE->first;
std::string data(itE->second->getData());
std::ofstream file;
std::string filepath = createAbsolutePath(name, archiveParentPath);
file.open(createAbsolutePath(name, archiveParentPath).c_str(), std::ios::binary);
file << data;
file.close();
zipArchiveFiles.push_back(filepath);
}
for (const std::string& zipArchiveFile : zipArchiveFiles) {
if (extensionEquals(zipArchiveFile, ".iidm")) {
if (!config_.networkFilePath.empty()) {
throw Error(AlreadyInitializedNetworkFileInput);
}
config_.networkFilePath = zipArchiveFile;
} else if (extensionEquals(zipArchiveFile, ".json")) {
boost::property_tree::ptree tree;
boost::property_tree::read_json(zipArchiveFile, tree);

boost::property_tree::ptree::const_assoc_iterator configTreeIt = tree.find("dfl-config");
if (configTreeIt != tree.not_found()) {
if (!config_.configPath.empty()) {
throw Error(AlreadyInitializedConfigFileInput);
}
config_.configPath = zipArchiveFile;
}

boost::property_tree::ptree::const_assoc_iterator contingenciesTreeIt = tree.find("contingencies");
if (contingenciesTreeIt != tree.not_found()) {
if (!config_.contingenciesFilePath.empty()) {
throw Error(AlreadyInitializedContingenciesInput);
}
config_.contingenciesFilePath = zipArchiveFile;
}
} else {
throw Error(ErrorConfigFileRead, zipArchiveFile);
}
}
} else {
throw std::logic_error("Wrong boolean value.");
}

if (config_.configPath.empty()) {
throw Error(NoConfigFileFound);
}

// if (config_.contingenciesFilePath.empty()) {
// throw std::runtime_error("ERREUR");
// }

// These are not binded automatically
if (vm.count("log-level") > 0) {
config_.dynawoLogLevel = vm["log-level"].as<ParsedLogLevel>().logLevelDefinition;
Expand All @@ -124,6 +211,8 @@ Options::parse(int argc, char* argv[]) {
} else {
return Request::RUN_SIMULATION_N;
}
} catch (const DYN::Error& err) {
throw;
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return Request::ERROR;
Expand Down
101 changes: 101 additions & 0 deletions tests/common/TestOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#include "Options.h"
#include "Tests.h"
#include "DFLError_keys.h"

#include <gtest_dynawo.h>

#include <sstream>

Expand Down Expand Up @@ -56,6 +59,14 @@ TEST(Options, missingCONFIG) {
ASSERT_EQ(dfl::common::Options::Request::ERROR, options.parse(2, argv));
}

TEST(Options, noInputProvided) {
dfl::common::Options options;

char programName[] = {"DynaFlowLauncher"};
char* argv[] = {programName};
ASSERT_EQ(dfl::common::Options::Request::HELP, options.parse(1, argv));
}

TEST(Options, nominal) {
dfl::common::Options options;

Expand Down Expand Up @@ -91,6 +102,60 @@ TEST(Options, wrongLogLevel) {
ASSERT_EQ(dfl::common::Options::Request::ERROR, status);
}

TEST(Options, nominalArchive) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/nominalArchive/nominalArchive.zip"};
char* argv[] = {argv0, argv1};
auto status = options.parse(2, argv);
ASSERT_EQ(dfl::common::Options::Request::RUN_SIMULATION_N, status);
}

TEST(Options, nominalArchiveLogLevel) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/nominalArchiveLogLevel/nominalArchiveLogLevel.zip"};
char argv2[] = {"--log-level=DEBUG"};
char* argv[] = {argv0, argv1, argv2};
auto status = options.parse(3, argv);
ASSERT_EQ(dfl::common::Options::Request::RUN_SIMULATION_N, status);
}

TEST(Options, nominalArchiveWrongLogLevel) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/nominalArchiveWrongLogLevel/nominalArchiveWrongLogLevel.zip"};
char argv2[] = {"--log-level=NO_LEVEL"}; // this level is not defined
char* argv[] = {argv0, argv1, argv2};
auto status = options.parse(3, argv);
ASSERT_EQ(dfl::common::Options::Request::ERROR, status);
}

TEST(Options, InvalidCombination_NetworkFileAndInputArchive) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--network=test.iidm"};
char argv2[] = {"--input-archive=res/test.zip"};
char* argv[] = {argv0, argv1, argv2};
auto status = options.parse(3, argv);
ASSERT_EQ(dfl::common::Options::Request::ERROR, status);
}

TEST(Options, InvalidCombination_ConfigFileAndInputArchive) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--config=test.json"};
char argv2[] = {"--input-archive=res/test.zip"};
char* argv[] = {argv0, argv1, argv2};
auto status = options.parse(3, argv);
ASSERT_EQ(dfl::common::Options::Request::ERROR, status);
}

/* Systematic Analysis */

TEST(Options, systematicAnalysis) {
Expand Down Expand Up @@ -219,3 +284,39 @@ TEST(Options, NSAWrongLogLevel) {
auto status = options.parse(6, argv);
ASSERT_EQ(dfl::common::Options::Request::ERROR, status);
}

TEST(Options, AlreadyInitializedNetworkFile) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/AlreadyInitializedNetworkFile/2NetworksArchive.zip"};
char* argv[] = {argv0, argv1};
ASSERT_THROW_DYNAWO(options.parse(2, argv), DYN::Error::GENERAL, dfl::KeyError_t::AlreadyInitializedNetworkFileInput);
}

TEST(Options, AlreadyInitializedConfigFileInput) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/AlreadyInitializedConfigFile/2ConfigFilesArchive.zip"};
char* argv[] = {argv0, argv1};
ASSERT_THROW_DYNAWO(options.parse(2, argv), DYN::Error::GENERAL, dfl::KeyError_t::AlreadyInitializedConfigFileInput);
}

TEST(Options, AlreadyInitializedContingenciesInput) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/AlreadyInitializedContingencies/2ContingenciesFilesArchive.zip"};
char* argv[] = {argv0, argv1};
ASSERT_THROW_DYNAWO(options.parse(2, argv), DYN::Error::GENERAL, dfl::KeyError_t::AlreadyInitializedContingenciesInput);
}

TEST(Options, NoConfigFileFound) {
dfl::common::Options options;

char argv0[] = {"DynaFlowLauncher"};
char argv1[] = {"--input-archive=res/NoConfigFileFound/FakeConfig.zip"};
char* argv[] = {argv0, argv1};
ASSERT_THROW_DYNAWO(options.parse(2, argv), DYN::Error::GENERAL, dfl::KeyError_t::NoConfigFileFound);
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 4aad721

Please sign in to comment.