readded confs, some basic exception handling, and reworking conf now

master
Chris Punches 2017-06-11 15:14:45 -04:00
parent 82d768e3c1
commit b36e6acabd
11 changed files with 142 additions and 74 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
./cmake-build-debug
cmake-build-debug
.idea
./.idea

4
conf/config.json Normal file
View File

@ -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"
}

6
conf/plans/test.plan Normal file
View File

@ -0,0 +1,6 @@
{
"plan": [
{ "name": "independent test", "depends on": null },
{ "name": "dependent test", "depends on": [ "independent test", null, null ] }
]
}

22
conf/units/all_test.units Normal file
View File

@ -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
}
]
}

View File

@ -6,20 +6,24 @@ int main( )
{ {
// A Plan is made up of Tasks, and a Suite is made up of Units. // 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. // 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. // 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 definitions_file = configuration.get_units_path();
std::string plan_file = configuration.get_plan_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 ); Task current_task = plan.get_task( i );
@ -40,6 +44,7 @@ int main( )
} }
std::cout << std::endl; std::cout << std::endl;
} }
*/
return 0; return 0;
} }

View File

@ -1,15 +1,28 @@
#include "Conf.h" #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::Conf( std::string filename ): JSON_Loader()
{ {
// Conf is always loaded from file. // load the conf file.
this->load_json_file( filename, true ); this->load_json_file( filename, true );
// always load plan_path, it is required to function. // find the path to the plan file
this->get_key( this->plan_path, "plan_path", true, false ); if (! this->get_key( this->plan_path, "plan_path", true) ) { throw CONF_PLANPATH_INVALID(); }
// always load units_path, it is required to function. // find the path to the unit definitions file
this->get_key( this->units_path, "units_path", true, false ); if (! this->get_key( this->units_path, "units_path", true) ) { throw CONF_UNITSPATH_INVALID(); }
}; };
std::string Conf::get_plan_path() std::string Conf::get_plan_path()

View File

@ -1,17 +1,32 @@
//
// Created by phanes on 4/22/17.
//
#include "JSON_Loader.h" #include "JSON_Loader.h"
#include "helpers.h" #include "helpers.h"
#include <stdexcept>
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() JSON_Loader::JSON_Loader()
{ {
// empty this->populated = false;
} }
// loads json from a file into a deserializable type and sets to private member json_root // 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. // reads from a file into a Json::Value type.
Json::Reader json_reader; 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 // first, check if the file exists
if (! exists( filename ) ) if (! exists( filename ) )
{ {
std::cerr << "File '" << filename << "' does not exist."; std::cerr << "File '" << filename << "' does not exist." << std::endl;
// exit with failure signal throw JSON_Loader_FileNotFound();
return 1;
} }
// create the ifstream file handle // create the ifstream file handle
@ -36,8 +50,8 @@ int JSON_Loader::load_json_file( std::string filename, bool verbose )
if (! parsingSuccessful ) if (! parsingSuccessful )
{ {
std::cerr << "Failed to parse '" << filename << "':\n\t" << json_reader.getFormattedErrorMessages(); std::cerr << "Failed to parse '" << filename << "':\n\t" << json_reader.getFormattedErrorMessages();
// exit with failure signal throw JSON_Loader_InvalidJSON();
return 1;
} else { } else {
// if in verbose mode, give the user an "it worked" message // if in verbose mode, give the user an "it worked" message
if (verbose) 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; std::cout << "Parsed '" << filename << "' with " << this->json_root.size() << " element(s)." << std::endl;
} }
} }
// exit successfully // exit successfully and set flag that this can be used now.
return 0; this->populated = true;
} }
// loads json from std::string into a serialized type and sets to private member json_root // 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. // reads from a string into a Json::Value type.
Json::Reader json_reader; Json::Reader json_reader;
@ -67,30 +81,34 @@ int JSON_Loader::load_json_string( std::string input, bool verbose )
if (! parsingSuccessful ) if (! parsingSuccessful )
{ {
std::cerr << "Failed to parse adhoc JSON value." << std::endl << input << std::endl << std::endl << json_reader.getFormattedErrorMessages(); std::cerr << "Failed to parse adhoc JSON value." << std::endl << input << std::endl << std::endl << json_reader.getFormattedErrorMessages();
// exit with failure signal throw JSON_Loader_InvalidJSON();
return 1;
} else { } else {
// if in verbose mode, give the user an "it worked" message // if in verbose mode, give the user an "it worked" message
if ( verbose ) if ( verbose )
{ {
std::cout << "Successfully parsed JSON string with " << this->json_root.size() << " elements. Value:" << std::endl; 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 // exit successfully
return 0; this->populated = true;
} }
// returns the serialized representation of json_root // returns the serialized representation of json_root
Json::Value JSON_Loader::as_serialized() Json::Value JSON_Loader::as_serialized()
{ {
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
return this->json_root; return this->json_root;
} }
// returns the string representation of json_root // returns the string representation of json_root
std::string JSON_Loader::as_string() std::string JSON_Loader::as_string()
{ {
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
return this->json_root.asString(); 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 // the Jason::Value object to assign the fetched value to
// verbosity flag // verbosity flag
// exit or not on failure // 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 ) ) 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 ]; input = this->json_root[ key ];
return 0; return 0;
} else { }
// key was not found // key was not found
// shouldn't the be handled further up?
if ( verbose ) if ( verbose )
{ {
// verbose mode tells the user what key we were looking for. // verbose mode tells the user what key we were looking for.
std::cerr << "Failed to find key '" << key << "'." << std::endl; std::cerr << "Failed to find key '" << key << "'." << std::endl;
}
// exit code for failure
return 1; 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);
}
}
}

View File

@ -14,23 +14,23 @@ class JSON_Loader
{ {
private: private:
Json::Value json_root; Json::Value json_root;
bool populated;
public: public:
// constructor // constructor
JSON_Loader(); JSON_Loader();
// load from json file // load from json file
int load_json_file( std::string filename, bool verbose ); void load_json_file( std::string filename, bool verbose );
// load from std::string json // load from std::string json
int load_json_string( std::string input, bool verbose ); void load_json_string( std::string input, bool verbose );
// return as a JSONCPP serialized object // return as a JSONCPP serialized object
Json::Value as_serialized(); Json::Value as_serialized();
std::string as_string(); std::string as_string();
// safely handle key retrieval (if we want it to be safe) // 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);
int get_key( Json::Value &input, std::string key, bool verbose, bool safety);
}; };
#endif //FTESTS_JLOADER_H #endif //FTESTS_JLOADER_H

View File

@ -1,5 +1,5 @@
#include "Plan.h" #include "Plan.h"
/*
int Plan::num_tasks() int Plan::num_tasks()
// returns the number of tasks in a Plan // 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) Task Plan::get_task(std::string provided_name)
/*
* returns a task from a Plan object by name * returns a task from a Plan object by name
* this will need reworked. maybe should return int, populate a pointer. * this will need reworked. maybe should return int, populate a pointer.
* error handling is the concern here. * error handling is the concern here.
*/
{ {
Task * returnable; Task * returnable;
bool foundMatch = false; bool foundMatch = false;
@ -42,9 +41,9 @@ Task Plan::get_task(std::string provided_name)
} }
Plan::Plan( std::string filename ): JSON_Loader() 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<Task> } * Plan { vector<Task> }
*/
{ {
// plan always loads from file // plan always loads from file
this->load_json_file( filename ); this->load_json_file( filename );
@ -56,3 +55,4 @@ Plan::Plan( std::string filename ): JSON_Loader()
this->tasks.push_back( Task( raw_tasks[index] ) ); this->tasks.push_back( Task( raw_tasks[index] ) );
} }
}; };
*/

View File

@ -1,10 +1,9 @@
#include "Suite.h" #include "Suite.h"
/*
Suite::Suite(): JSON_Loader() {}
Suite::Suite( std::string filename ): 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 loads a file and deserializes the Unit JSON object to Unit types as a vector member
* Suite { vector<Unit> } * Suite { vector<Unit> }
*/
{ {
load_file( filename ); 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) Unit Suite::get_unit(std::string provided_name)
/*
* returns a unit from a unitholder object by name * returns a unit from a unitholder object by name
* this will need reworked. maybe should return int, populate a pointer. * this will need reworked. maybe should return int, populate a pointer.
* error handling is the concern here. * error handling is the concern here.
*/
{ {
Unit * returnable; Unit * returnable;
bool foundMatch = false; bool foundMatch = false;
@ -48,3 +47,4 @@ Unit Suite::get_unit(std::string provided_name)
} }
return * returnable; return * returnable;
} }
*/

View File

@ -5,8 +5,8 @@
#define FTESTS_LOADERS_H #define FTESTS_LOADERS_H
#include "JSON_Loader.h" #include "JSON_Loader.h"
#include "Suite.h" //#include "Suite.h"
#include "Plan.h" //#include "Plan.h"
#include "Conf.h" #include "Conf.h"
#endif //FTESTS_LOADERS_H #endif //FTESTS_LOADERS_H