readded confs, some basic exception handling, and reworking conf now
parent
82d768e3c1
commit
b36e6acabd
|
@ -0,0 +1,4 @@
|
||||||
|
./cmake-build-debug
|
||||||
|
cmake-build-debug
|
||||||
|
.idea
|
||||||
|
./.idea
|
|
@ -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"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"plan": [
|
||||||
|
{ "name": "independent test", "depends on": null },
|
||||||
|
{ "name": "dependent test", "depends on": [ "independent test", null, null ] }
|
||||||
|
]
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
15
examplar.cpp
15
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 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;
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
|
||||||
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;
|
||||||
}
|
}
|
|
@ -12,25 +12,25 @@
|
||||||
|
|
||||||
class JSON_Loader
|
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
|
||||||
|
|
|
@ -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] ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*/
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
*/
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue