Skip to content

Commit

Permalink
Integrate json schema validation to detect typos in the settings file.
Browse files Browse the repository at this point in the history
  • Loading branch information
mlrnicq1 committed Dec 31, 2024
1 parent 09932e6 commit c8a4abb
Show file tree
Hide file tree
Showing 6 changed files with 383 additions and 154 deletions.
21 changes: 20 additions & 1 deletion inc/Util/FileParsing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/phoenix/object.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <cassert>
#include <cstdint>
#include <filesystem>
#include <fstream>
Expand All @@ -25,9 +26,27 @@ namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace js = boost::json;

enum class TriStateBit { no_value, zero_value, one_value, random_value, undefined_value };
enum class TriStateBit {
no_value,
zero_value,
one_value,
random_value,
undefined_value
};
enum class ValueType { arary, variable, standard };

class JsonSchema {
public:
JsonSchema(const std::string& key, const std::string& type);
JsonSchema(const std::string& key, const std::string& type, const std::vector<JsonSchema>& children);
void Validate(const boost::json::object& json_object);

private:
std::string key_;
std::string type_;
std::vector<JsonSchema> children_;
};

class InputAssignment {
public:
bool is_inverted_;
Expand Down
69 changes: 1 addition & 68 deletions inc/Util/Settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <vector>

#include "Util/CpuCoreSelector.hpp"
#include "Util/FileParsing.hpp"
#include "Util/SettingsSchema.hpp"
#include "Util/Sharing.hpp"
// #include "Hardware/Fault.hpp"
#include "Types.hpp"
Expand Down Expand Up @@ -226,70 +226,3 @@ class Settings {
void ParseSideChannelAnalysisSettings(const boost::json::object& json_object, const std::string& identifier, SideChannelAnalysisSettings& settings);
void ParseFaultInjectionSettings(const boost::json::object& json_object, const std::string& identifier, FaultInjectionSettings& settings);
};

namespace SettingNames {

extern const std::string BASE;
extern const std::string EXPONENT;
extern const std::string IS_ADDITIVE;
extern const std::string EXCLUDED_ELEMENTS;
extern const std::string IRREDUCIBLE_POLYNOMIAL;
extern const std::string INPUT_FINITE_FIELD;
extern const std::string OUTPUT_FINITE_FIELD;

extern const std::string NUMBER_OF_THREADS;
extern const std::string COMPACT_DISTRIBUTIONS;
extern const std::string MINIMIZE_PROBING_SETS;
extern const std::string REMOVE_FULL_PROBING_SETS;
extern const std::string NUMBER_OF_ENTRIES_IN_REPORT;
extern const std::string NUMBER_OF_PROBING_SETS_PER_STEP;
extern const std::string PERFORMANCE;

extern const std::string CLOCK_SIGNAL_NAME;
extern const std::string HARDWARE;

extern const std::string COMPILER_FLAGS;
extern const std::string LOCATION_OF_CIPHER;
extern const std::string NUMBER_OF_PIPELINE_STAGES;
extern const std::string SOFTWARE;

extern const std::string WAVEFORM_SIMULATION;
extern const std::string NUMBER_OF_CLOCK_CYCLES;
extern const std::string END_WAIT_CYCLES;
extern const std::string END_CONDITION;
extern const std::string GROUPS;
extern const std::string ALWAYS_RANDOM_INPUTS;
extern const std::string OUTPUT_SHARES;
extern const std::string EXPECTED_OUTPUT;
extern const std::string INPUT_SEQUENCE;
extern const std::string FAULT_DETECTION_FLAGS;
extern const std::string NUMBER_OF_SIMULATIONS;
extern const std::string NUMBER_OF_SIMULATIONS_PER_STEP;
extern const std::string NUMBER_OF_SIMULATIONS_PER_WRITE;
extern const std::string SIMULATION;

extern const std::string ALPHA_THRESHOLD;
extern const std::string BETA_THRESHOLD;
extern const std::string EFFECT_SIZE;
extern const std::string ORDER_OF_TEST;
extern const std::string RELAXED_MODEL;
extern const std::string TRANSITIONAL_LEAKAGE;
extern const std::string VARIATE;
extern const std::string DISTANCE;
extern const std::string CLOCK_CYCLES;
extern const std::string PROBE_PLACEMENT;
extern const std::string EXTENSION_ROUTES;
extern const std::string OBSERVED_EXTENSIONS;
extern const std::string SIDE_CHANNEL_ANALYSIS;

extern const std::string MAXIMUM_NUMBER_OF_FAULTS_PER_RUN;
extern const std::string MINIMUM_NUMBER_OF_FAULTS_PER_RUN;
extern const std::string MAXIMUM_NUMBER_OF_FAULTS_PER_CYCLE;
extern const std::string MINIMUM_NUMBER_OF_FAULTS_PER_CYCLE;
extern const std::string FAULTED_CLOCK_CYCLES;
extern const std::string FAULT_TYPE;
extern const std::string FAULT_LOCATIONS;
extern const std::string FAULT_INJECTION;
extern const std::string FAULT_ANALYSIS;

} // namespace SettingNames
77 changes: 77 additions & 0 deletions inc/Util/SettingsSchema.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#pragma once

#include "Util/FileParsing.hpp"

namespace SettingNames {
extern const std::string FAULT_INJECTION;
extern const std::string FAULTED_CLOCK_CYCLES;
extern const std::string FAULT_LOCATIONS;
extern const std::string FAULT_TYPE;
extern const std::string MAXIMUM_NUMBER_OF_FAULTS_PER_CYCLE;
extern const std::string MAXIMUM_NUMBER_OF_FAULTS_PER_RUN;
extern const std::string MINIMUM_NUMBER_OF_FAULTS_PER_CYCLE;
extern const std::string MINIMUM_NUMBER_OF_FAULTS_PER_RUN;
extern const std::string FAULT_ANALYSIS;

extern const std::string INPUT_FINITE_FIELD;
extern const std::string OUTPUT_FINITE_FIELD;
extern const std::string BASE;
extern const std::string EXCLUDED_ELEMENTS;
extern const std::string EXPONENT;
extern const std::string IRREDUCIBLE_POLYNOMIAL;
extern const std::string IS_ADDITIVE;

extern const std::string PERFORMANCE;
extern const std::string COMPACT_DISTRIBUTIONS;
extern const std::string MINIMIZE_PROBING_SETS;
extern const std::string NUMBER_OF_ENTRIES_IN_REPORT;
extern const std::string NUMBER_OF_PROBING_SETS_PER_STEP;
extern const std::string NUMBER_OF_THREADS;
extern const std::string REMOVE_FULL_PROBING_SETS;

extern const std::string HARDWARE;
extern const std::string CLOCK_SIGNAL_NAME;

extern const std::string SIDE_CHANNEL_ANALYSIS;
extern const std::string ALPHA_THRESHOLD;
extern const std::string BETA_THRESHOLD;
extern const std::string CLOCK_CYCLES;
extern const std::string DISTANCE;
extern const std::string EFFECT_SIZE;
extern const std::string EXTENSION_ROUTES;
extern const std::string OBSERVED_EXTENSIONS;
extern const std::string ORDER_OF_TEST;
extern const std::string PROBE_PLACEMENT;
extern const std::string RELAXED_MODEL;
extern const std::string TRANSITIONAL_LEAKAGE;
extern const std::string VARIATE;

extern const std::string SOFTWARE;
extern const std::string COMPILER_FLAGS;
extern const std::string LOCATION_OF_CIPHER;
extern const std::string PIPELINE_STAGES;

extern const std::string SIMULATION;
extern const std::string ALWAYS_RANDOM_INPUTS;
extern const std::string END_CONDITION;
extern const std::string END_WAIT_CYCLES;
extern const std::string EXPECTED_OUTPUT;
extern const std::string FAULT_DETECTION_FLAGS;
extern const std::string GROUPS;
extern const std::string INPUT_SEQUENCE;
extern const std::string NUMBER_OF_CLOCK_CYCLES;
extern const std::string NUMBER_OF_SIMULATIONS;
extern const std::string NUMBER_OF_SIMULATIONS_PER_STEP;
extern const std::string NUMBER_OF_SIMULATIONS_PER_WRITE;
extern const std::string OUTPUT_SHARES;
extern const std::string WAVEFORM_SIMULATION;
} // namespace SettingNames

extern JsonSchema fault_injection_schema;
extern JsonSchema hardware_schema;
extern JsonSchema input_finite_field_schema;
extern JsonSchema output_finite_field_schema;
extern JsonSchema performance_schema;
extern JsonSchema side_channel_analysis_schema;
extern JsonSchema simulation_schema;
extern JsonSchema settings_schema;
83 changes: 75 additions & 8 deletions src/Util/FileParsing.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
#include "Util/FileParsing.hpp"

JsonSchema::JsonSchema(const std::string& key, const std::string& type)
: key_(key), type_(type) {}

JsonSchema::JsonSchema(const std::string& key, const std::string& type,
const std::vector<JsonSchema>& children)
: key_(key), type_(type), children_(children) {}

void JsonSchema::Validate(const boost::json::object& json_object) {
std::string error_context = "Error while validating JSON: ";
std::string key, type;
for (const auto& pair : json_object) {
key = pair.key_c_str();

assert(std::is_sorted(children_.begin(), children_.end(),
[](const JsonSchema& a, const JsonSchema& b) {
return a.key_ < b.key_;
}) &&
"Error while parsing the JSON object: Children are not sorted!");

auto child = std::find_if(
children_.begin(), children_.end(),
[&key](const JsonSchema& scheme) { return scheme.key_ == key; });

if (child != children_.end()) {
type = child->type_;
if (child->children_.empty()) {
if (type == "int") {
uint64_t variable;
SetValue(json_object, key, variable);
} else if (type == "double") {
double variable;
SetValue(json_object, key, variable);
} else if (type == "string") {
std::string variable;
SetValue(json_object, key, variable);
} else if (type == "bool") {
bool variable;
SetValue(json_object, key, variable);
} else if (type == "array") {
boost::json::array variable;
SetValue(json_object, key, variable);
} else {
throw std::invalid_argument(error_context + "Unknown data type \"" +
type + "\" for key \"" + key +
"\" in JSON scheme!");
}
} else {
if (type == "array") {
boost::json::array json_array;
SetValue(json_object, key, json_array);
for (const auto& array_element : json_array) {
child->children_[0].Validate(array_element.as_object());
}
} else if (type == "object") {
boost::json::object variable;
SetValue(json_object, key, variable);
child->Validate(variable);
} else {
throw std::invalid_argument(error_context + "Unknown data type \"" +
type_ + "\" in JSON scheme!");
}
}
} else {
throw std::invalid_argument(error_context + "Key \"" + key +
"\" not found!");
}
}
}

IntegerRangeGrammar::IntegerRangeGrammar(uint64_t maximum_value)
: IntegerRangeGrammar::base_type(range_) {
range_ =
Expand Down Expand Up @@ -189,9 +258,8 @@ InputAssignment InputAssignmentGrammar::Parse(
result_.signal_values_.clear();

if (!qi::phrase_parse(begin, end, *this, qi::space)) {
std::string error_message =
"Error while parsing the input assignment: \"" + input_assignment_string +
"\". Invalid syntax!";
std::string error_message = "Error while parsing the input assignment: \"" +
input_assignment_string + "\". Invalid syntax!";
throw std::invalid_argument(error_message);
}

Expand Down Expand Up @@ -326,9 +394,8 @@ std::vector<std::string> SignalNameGrammar::Parse(
bool success = qi::phrase_parse(begin, end, *this, qi::space);

if (!success || (begin != end)) {
std::string error_message =
"Error while parsing signal name: \"" + signal_name_string +
"\". Invalid syntax!";
std::string error_message = "Error while parsing signal name: \"" +
signal_name_string + "\". Invalid syntax!";
throw std::invalid_argument(error_message);
}

Expand Down Expand Up @@ -390,7 +457,7 @@ bool SetValue(const js::object& json_object, const std::string& key,
if (json_object.at(key).as_int64() >= 0) {
variable = (uint64_t)json_object.at(key).as_int64();
} else {
error_message = "Error while copying the value of the key \"" + key +
error_message = "Error while parsing the value of the key \"" + key +
"\": Value is negative.";
throw std::runtime_error(error_message);
}
Expand All @@ -410,7 +477,7 @@ bool SetValue(const js::object& json_object, const std::string& key,
CheckValueType(json_object, key, js::kind::object);
variable = json_object.at(key).as_object();
} else {
error_message = "Error while copying the value of the key \"" + key +
error_message = "Error while parsing the value of the key \"" + key +
"\": Unsupported data type.";
throw std::runtime_error(error_message);
}
Expand Down
Loading

0 comments on commit c8a4abb

Please sign in to comment.