From b36e6acabd3108ffeb50ba1804889b2bc86cc425 Mon Sep 17 00:00:00 2001 From: Chris Punches Date: Sun, 11 Jun 2017 15:14:45 -0400 Subject: [PATCH] readded confs, some basic exception handling, and reworking conf now --- .gitignore | 4 ++ conf/config.json | 4 ++ conf/plans/test.plan | 6 +++ conf/units/all_test.units | 22 ++++++++++ examplar.cpp | 15 ++++--- src/loaders/Conf.cpp | 23 +++++++--- src/loaders/JSON_Loader.cpp | 88 +++++++++++++++++++++---------------- src/loaders/JSON_Loader.h | 30 ++++++------- src/loaders/Plan.cpp | 10 ++--- src/loaders/Suite.cpp | 10 ++--- src/loaders/loaders.h | 4 +- 11 files changed, 142 insertions(+), 74 deletions(-) create mode 100644 .gitignore create mode 100644 conf/config.json create mode 100644 conf/plans/test.plan create mode 100644 conf/units/all_test.units diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a421d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +./cmake-build-debug +cmake-build-debug +.idea +./.idea diff --git a/conf/config.json b/conf/config.json new file mode 100644 index 0000000..0efa20c --- /dev/null +++ b/conf/config.json @@ -0,0 +1,4 @@ +{ + "units_path": "/home/phanes/Development/internal/ftests/conf/units/all_test.units", + "plan_path": "/home/phanes/Development/internal/ftests/conf/plans/test.plan" +} diff --git a/conf/plans/test.plan b/conf/plans/test.plan new file mode 100644 index 0000000..446edb9 --- /dev/null +++ b/conf/plans/test.plan @@ -0,0 +1,6 @@ +{ + "plan": [ + { "name": "independent test", "depends on": null }, + { "name": "dependent test", "depends on": [ "independent test", null, null ] } + ] +} diff --git a/conf/units/all_test.units b/conf/units/all_test.units new file mode 100644 index 0000000..50636f8 --- /dev/null +++ b/conf/units/all_test.units @@ -0,0 +1,22 @@ +{ + "units": [ + { + "name": "independent test", + "target": "/home/phanes/tests/test-script-pass.sh", + "output": "pass", + "rectifier": "/home/phanes/tests/test-script-rectifier.sh", + "active": true, + "required": true, + "rectify": true + }, + { + "name": "dependent test", + "target": "/home/phanes/tests/test-script-pass.sh", + "output": "pass", + "rectifier": "/home/phanes/tests/test-script-rectifier.sh", + "active": true, + "required": true, + "rectify": false + } + ] +} diff --git a/examplar.cpp b/examplar.cpp index 6ec34c5..4ced1fe 100644 --- a/examplar.cpp +++ b/examplar.cpp @@ -6,20 +6,24 @@ int main( ) { // A Plan is made up of Tasks, and a Suite is made up of Units. // A Plan declares what units are executed and a Suite declares the definitions of those units. - Conf configuration = Conf( "config.json" ); + Conf configuration = Conf("/home/phanes/Development/internal/ftests/conf/config.json"); // load the configuration file which contains filepaths to definitions of a plan and definitions of units. std::string definitions_file = configuration.get_units_path(); std::string plan_file = configuration.get_plan_path(); - Suite * unit_definitions = new Suite(); - unit_definitions->load_file( definitions_file ); + std::cout << definitions_file << std::endl << plan_file << std::endl; - Plan plan = Plan( plan_file ); - for ( int i = 0; i < plan.num_tasks(); ++i ) +// Suite * unit_definitions = new Suite(); + +// unit_definitions->load_file( definitions_file ); + +// Plan plan = Plan( plan_file ); + +/* for ( int i = 0; i < plan.num_tasks(); ++i ) { Task current_task = plan.get_task( i ); @@ -40,6 +44,7 @@ int main( ) } std::cout << std::endl; } +*/ return 0; } \ No newline at end of file diff --git a/src/loaders/Conf.cpp b/src/loaders/Conf.cpp index e4c5c5a..2a8b9c3 100644 --- a/src/loaders/Conf.cpp +++ b/src/loaders/Conf.cpp @@ -1,15 +1,28 @@ #include "Conf.h" +class CONF_PLANPATH_INVALID: public std::runtime_error +{ +public: + CONF_PLANPATH_INVALID(): std::runtime_error("conf: The supplied path for the plan definition file is invalid.") {} +}; + +class CONF_UNITSPATH_INVALID: public std::runtime_error +{ +public: + CONF_UNITSPATH_INVALID(): std::runtime_error("conf: The supplied path for the unit definition file is invalid.") {} +}; + + Conf::Conf( std::string filename ): JSON_Loader() { - // Conf is always loaded from file. + // load the conf file. this->load_json_file( filename, true ); - // always load plan_path, it is required to function. - this->get_key( this->plan_path, "plan_path", true, false ); + // find the path to the plan file + if (! this->get_key( this->plan_path, "plan_path", true) ) { throw CONF_PLANPATH_INVALID(); } - // always load units_path, it is required to function. - this->get_key( this->units_path, "units_path", true, false ); + // find the path to the unit definitions file + if (! this->get_key( this->units_path, "units_path", true) ) { throw CONF_UNITSPATH_INVALID(); } }; std::string Conf::get_plan_path() diff --git a/src/loaders/JSON_Loader.cpp b/src/loaders/JSON_Loader.cpp index 4f644d7..86183a4 100644 --- a/src/loaders/JSON_Loader.cpp +++ b/src/loaders/JSON_Loader.cpp @@ -1,17 +1,32 @@ -// -// Created by phanes on 4/22/17. -// - #include "JSON_Loader.h" #include "helpers.h" +#include + +class JSON_Loader_NotReady: public std::runtime_error +{ +public: + JSON_Loader_NotReady(): std::runtime_error("JSON_Loader: Tried to access JSON without actually populating JSON.") {} +}; + +class JSON_Loader_FileNotFound: public std::runtime_error +{ +public: + JSON_Loader_FileNotFound(): std::runtime_error("JSON_Loader: The requested file could not be found.") {} +}; + +class JSON_Loader_InvalidJSON: public std::runtime_error +{ +public: + JSON_Loader_InvalidJSON(): std::runtime_error("JSON_Loader: The JSON provided could not be parsed.") {} +}; JSON_Loader::JSON_Loader() { - // empty + this->populated = false; } // loads json from a file into a deserializable type and sets to private member json_root -int JSON_Loader::load_json_file( std::string filename, bool verbose ) +void JSON_Loader::load_json_file( std::string filename, bool verbose ) { // reads from a file into a Json::Value type. Json::Reader json_reader; @@ -22,9 +37,8 @@ int JSON_Loader::load_json_file( std::string filename, bool verbose ) // first, check if the file exists if (! exists( filename ) ) { - std::cerr << "File '" << filename << "' does not exist."; - // exit with failure signal - return 1; + std::cerr << "File '" << filename << "' does not exist." << std::endl; + throw JSON_Loader_FileNotFound(); } // create the ifstream file handle @@ -36,8 +50,8 @@ int JSON_Loader::load_json_file( std::string filename, bool verbose ) if (! parsingSuccessful ) { std::cerr << "Failed to parse '" << filename << "':\n\t" << json_reader.getFormattedErrorMessages(); - // exit with failure signal - return 1; + throw JSON_Loader_InvalidJSON(); + } else { // if in verbose mode, give the user an "it worked" message if (verbose) @@ -45,12 +59,12 @@ int JSON_Loader::load_json_file( std::string filename, bool verbose ) std::cout << "Parsed '" << filename << "' with " << this->json_root.size() << " element(s)." << std::endl; } } - // exit successfully - return 0; + // exit successfully and set flag that this can be used now. + this->populated = true; } // loads json from std::string into a serialized type and sets to private member json_root -int JSON_Loader::load_json_string( std::string input, bool verbose ) +void JSON_Loader::load_json_string( std::string input, bool verbose ) { // reads from a string into a Json::Value type. Json::Reader json_reader; @@ -67,30 +81,34 @@ int JSON_Loader::load_json_string( std::string input, bool verbose ) if (! parsingSuccessful ) { std::cerr << "Failed to parse adhoc JSON value." << std::endl << input << std::endl << std::endl << json_reader.getFormattedErrorMessages(); - // exit with failure signal - return 1; + throw JSON_Loader_InvalidJSON(); + } else { // if in verbose mode, give the user an "it worked" message if ( verbose ) { std::cout << "Successfully parsed JSON string with " << this->json_root.size() << " elements. Value:" << std::endl; - std::cout << input << std::endl; + std::cout << input << std::endl << std::endl; } } // exit successfully - return 0; + this->populated = true; } // returns the serialized representation of json_root Json::Value JSON_Loader::as_serialized() { + if ( ! this->populated ) { throw JSON_Loader_NotReady(); } + return this->json_root; } // returns the string representation of json_root std::string JSON_Loader::as_string() { + if ( ! this->populated ) { throw JSON_Loader_NotReady(); } + return this->json_root.asString(); } @@ -98,29 +116,25 @@ std::string JSON_Loader::as_string() // the Jason::Value object to assign the fetched value to // verbosity flag // exit or not on failure -int JSON_Loader::get_key( Json::Value &input, std::string key, bool verbose, bool safety) +int JSON_Loader::get_key( Json::Value &input, std::string key, bool verbose) { + // throw if the class is not ready to be used. + if ( ! this->populated ) { throw JSON_Loader_NotReady(); } + if ( this->json_root.isMember( key ) ) { - // key was found so return it + // key was found so return it to the passed input ref input = this->json_root[ key ]; return 0; - } else { - // key was not found - if ( verbose ) - { - // verbose mode tells the user what key we were looking for. - std::cerr << "Failed to find key '" << key << "'." << std::endl; - return 1; - } - - if ( ! safety ) - { - // if we're not ignoring fatal errors - std::cout << "Exiting." << std::endl; - // exit code for failure - // this should probably be a 'throw'.... - exit(1); - } } + + // key was not found + // shouldn't the be handled further up? + if ( verbose ) + { + // verbose mode tells the user what key we were looking for. + std::cerr << "Failed to find key '" << key << "'." << std::endl; + } + // exit code for failure + return 1; } \ No newline at end of file diff --git a/src/loaders/JSON_Loader.h b/src/loaders/JSON_Loader.h index 6e4040a..4ce2a66 100644 --- a/src/loaders/JSON_Loader.h +++ b/src/loaders/JSON_Loader.h @@ -12,25 +12,25 @@ class JSON_Loader { -private: - Json::Value json_root; + private: + Json::Value json_root; + bool populated; -public: - // constructor - JSON_Loader(); + public: + // constructor + JSON_Loader(); - // load from json file - int load_json_file( std::string filename, bool verbose ); + // load from json file + void load_json_file( std::string filename, bool verbose ); - // load from std::string json - int load_json_string( std::string input, bool verbose ); + // load from std::string json + void load_json_string( std::string input, bool verbose ); - // return as a JSONCPP serialized object - Json::Value as_serialized(); - std::string as_string(); + // return as a JSONCPP serialized object + Json::Value as_serialized(); + std::string as_string(); - // safely handle key retrieval (if we want it to be safe) - // next iter should be: - int get_key( Json::Value &input, std::string key, bool verbose, bool safety); + // safely handle key retrieval (if we want it to be safe) + int get_key( Json::Value &input, std::string key, bool verbose); }; #endif //FTESTS_JLOADER_H diff --git a/src/loaders/Plan.cpp b/src/loaders/Plan.cpp index 9e732b3..dd0691b 100644 --- a/src/loaders/Plan.cpp +++ b/src/loaders/Plan.cpp @@ -1,5 +1,5 @@ #include "Plan.h" - +/* int Plan::num_tasks() // returns the number of tasks in a Plan { @@ -13,11 +13,10 @@ Task Plan::get_task(int index) } Task Plan::get_task(std::string provided_name) -/* * returns a task from a Plan object by name * this will need reworked. maybe should return int, populate a pointer. * error handling is the concern here. - */ + { Task * returnable; bool foundMatch = false; @@ -42,9 +41,9 @@ Task Plan::get_task(std::string provided_name) } Plan::Plan( std::string filename ): JSON_Loader() -/* Plan loads a file and deserializes the Unit JSON object to Task types as a vector member + Plan loads a file and deserializes the Unit JSON object to Task types as a vector member * Plan { vector } - */ + { // plan always loads from file this->load_json_file( filename ); @@ -56,3 +55,4 @@ Plan::Plan( std::string filename ): JSON_Loader() this->tasks.push_back( Task( raw_tasks[index] ) ); } }; +*/ \ No newline at end of file diff --git a/src/loaders/Suite.cpp b/src/loaders/Suite.cpp index 01b1cfd..7433dfd 100644 --- a/src/loaders/Suite.cpp +++ b/src/loaders/Suite.cpp @@ -1,10 +1,9 @@ #include "Suite.h" - -Suite::Suite(): JSON_Loader() {} +/* Suite::Suite( std::string filename ): JSON_Loader() /* Suite loads a file and deserializes the Unit JSON object to Unit types as a vector member * Suite { vector } - */ + { load_file( filename ); }; @@ -22,11 +21,11 @@ int Suite::load_file(std::string filename): JSON_Loader( filename ) } Unit Suite::get_unit(std::string provided_name) -/* + * returns a unit from a unitholder object by name * this will need reworked. maybe should return int, populate a pointer. * error handling is the concern here. - */ + { Unit * returnable; bool foundMatch = false; @@ -48,3 +47,4 @@ Unit Suite::get_unit(std::string provided_name) } return * returnable; } +*/ \ No newline at end of file diff --git a/src/loaders/loaders.h b/src/loaders/loaders.h index e0b7261..9f4f0e0 100644 --- a/src/loaders/loaders.h +++ b/src/loaders/loaders.h @@ -5,8 +5,8 @@ #define FTESTS_LOADERS_H #include "JSON_Loader.h" -#include "Suite.h" -#include "Plan.h" +//#include "Suite.h" +//#include "Plan.h" #include "Conf.h" #endif //FTESTS_LOADERS_H