logging reflow
parent
11829aca39
commit
839c3d398a
|
@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 3.5)
|
||||||
project(examplar)
|
project(examplar)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++1z -O0 -DDEBUG=1")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++1z -O0 -DDEBUG=1")
|
||||||
set(SOURCE_FILES examplar.cpp src/loaders/loaders.cpp src/loaders/loaders.h src/json/jsoncpp.cpp src/loaders/JSON_Loader.cpp src/loaders/JSON_Loader.h src/loaders/helpers.cpp src/loaders/helpers.h src/loaders/Suite.cpp src/loaders/Suite.h src/loaders/Plan.cpp src/loaders/Plan.h src/loaders/Conf.cpp src/loaders/Conf.h src/loaders/Unit.cpp src/loaders/Unit.h src/loaders/Task.cpp src/loaders/Task.h src/sproc/Sproc.cpp src/sproc/Sproc.h)
|
set(SOURCE_FILES examplar.cpp src/loaders/abstract/loaders.cpp src/loaders/abstract/loaders.h src/json/jsoncpp.cpp src/loaders/low_level/JSON_Loader.cpp src/loaders/low_level/JSON_Loader.h src/loaders/misc/helpers.cpp src/loaders/misc/helpers.h src/loaders/abstract/Suite.cpp src/loaders/abstract/Suite.h src/loaders/abstract/Plan.cpp src/loaders/abstract/Plan.h src/loaders/abstract/Conf.cpp src/loaders/abstract/Conf.h src/loaders/abstract/Unit.cpp src/loaders/abstract/Unit.h src/loaders/abstract/Task.cpp src/loaders/abstract/Task.h src/Sproc/Sproc.cpp src/Sproc/Sproc.h src/Logger/Logger.cpp src/Logger/Logger.h)
|
||||||
|
|
||||||
add_executable(examplar ${SOURCE_FILES})
|
add_executable(examplar ${SOURCE_FILES})
|
85
examplar.cpp
85
examplar.cpp
|
@ -19,28 +19,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "src/json/json.h"
|
|
||||||
#include "src/loaders/loaders.h"
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <syslog.h>
|
|
||||||
#include "src/loaders/helpers.h"
|
|
||||||
|
|
||||||
/*
|
#include "src/json/json.h"
|
||||||
* TODO Commandline switches
|
#include "src/loaders/abstract/loaders.h"
|
||||||
*/
|
#include "src/Logger/Logger.h"
|
||||||
|
#include "src/loaders/misc/helpers.h"
|
||||||
|
|
||||||
void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
printf("examplar [ -h | --help ] [ -v | --verbose ] [ -e | --execution-context EXECUTION_CONTEXT ][ -c | --config CONFIG_PATH ]\n\n");
|
printf("examplar [ -h | --help ] [ -v | --verbose ] [ -e | --execution-context EXECUTION_CONTEXT ][ -c | --config CONFIG_PATH ]\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char * argv[] )
|
int main( int argc, char * argv[] )
|
||||||
{
|
{
|
||||||
int flags, opt;
|
int opt;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool show_help = false;
|
bool show_help = false;
|
||||||
|
|
||||||
|
@ -70,15 +64,15 @@ int main( int argc, char * argv[] )
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
||||||
opt = getopt_long (argc, argv, "vhec:", long_options, &option_index);
|
opt = getopt_long( argc, argv, "vhec:", long_options, &option_index );
|
||||||
|
|
||||||
if (opt == -1)
|
if ( opt == -1 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (opt)
|
switch ( opt )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (long_options[option_index].flag !=0)
|
if ( long_options[option_index].flag !=0 )
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
show_help = true;
|
show_help = true;
|
||||||
|
@ -86,80 +80,81 @@ int main( int argc, char * argv[] )
|
||||||
verbose = true;
|
verbose = true;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
config_path = std::string(optarg);
|
config_path = std::string( optarg );
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
print_usage();
|
print_usage();
|
||||||
exit(1);
|
exit( 1 );
|
||||||
case 'e':
|
case 'e':
|
||||||
cli_context_supplied = true;
|
cli_context_supplied = true;
|
||||||
execution_context = std::string(optarg);
|
execution_context = std::string( optarg );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( show_help == true )
|
if ( show_help )
|
||||||
{
|
{
|
||||||
print_usage();
|
print_usage();
|
||||||
exit(0);
|
exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
setlogmask( LOG_UPTO( LOG_INFO ) );
|
int L_LEVEL = E_INFO;
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
L_LEVEL = E_DEBUG;
|
||||||
|
} else {
|
||||||
|
L_LEVEL = E_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
openlog( "Examplar", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_PERROR | LOG_LOCAL1 );
|
Logger slog = Logger( L_LEVEL, "Examplar" );
|
||||||
|
|
||||||
// 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_path, verbose );
|
Conf configuration = Conf(config_path, L_LEVEL );
|
||||||
|
|
||||||
// if the user set this option as a commandline argument
|
|
||||||
if ( cli_context_supplied == true )
|
|
||||||
{
|
|
||||||
// override the conf file's specified execution context
|
|
||||||
configuration.set_execution_context( execution_context );
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if context override
|
// check if context override
|
||||||
|
|
||||||
if ( configuration.has_context_override() )
|
if ( configuration.has_context_override() )
|
||||||
{
|
{
|
||||||
// if so, set the CWD.
|
// if so, set the CWD.
|
||||||
chdir( configuration.get_execution_context().c_str() );
|
chdir( configuration.get_execution_context().c_str() );
|
||||||
std::ostringstream infostring;
|
slog.log( E_DEBUG, "Set execution context: " + get_working_path() );
|
||||||
infostring << "Execution context: " << get_working_path() << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the user set this option as a commandline argument
|
||||||
|
if ( cli_context_supplied )
|
||||||
|
{
|
||||||
|
// override the conf file's specified execution context
|
||||||
|
configuration.set_execution_context( execution_context );
|
||||||
|
slog.log( E_DEBUG, "Set execution context from commandline: " + execution_context );
|
||||||
|
}
|
||||||
|
|
||||||
// load the filepaths to definitions of a plan and definitions of units.
|
// load the 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 available_definitions;
|
Suite available_definitions = Suite( L_LEVEL );
|
||||||
available_definitions.load_units_file( definitions_file, verbose );
|
available_definitions.load_units_file( definitions_file );
|
||||||
|
|
||||||
Plan plan( &configuration );
|
Plan plan = Plan( &configuration, L_LEVEL );
|
||||||
plan.load_plan_file( plan_file, verbose );
|
plan.load_plan_file( plan_file );
|
||||||
|
|
||||||
plan.load_definitions( available_definitions, verbose );
|
plan.load_definitions( available_definitions );
|
||||||
|
|
||||||
std::cout << "Ready to execute all tasks in Plan." << std::endl;
|
slog.log( E_DEBUG, "Ready to execute all tasks in Plan." );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
plan.execute( verbose );
|
plan.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( std::exception& e)
|
catch ( std::exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << e.what() << std::endl;
|
slog.log( E_FATAL, e.what() );
|
||||||
syslog( LOG_ERR, e.what() );
|
|
||||||
closelog();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
closelog();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Created by bagira on 6/13/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
Logger::Logger( int LOG_LEVEL, std::string mask )
|
||||||
|
{
|
||||||
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
|
this->mask = mask.c_str();
|
||||||
|
|
||||||
|
setlogmask( LOG_UPTO( this->LOG_LEVEL ) );
|
||||||
|
openlog( this->mask, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_PERROR | LOG_LOCAL1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::log( int LOG_LEVEL, std::string msg )
|
||||||
|
{
|
||||||
|
std::string ERR = "XXXX";
|
||||||
|
|
||||||
|
if ( LOG_LEVEL <= this->LOG_LEVEL )
|
||||||
|
{
|
||||||
|
switch ( LOG_LEVEL )
|
||||||
|
{
|
||||||
|
case E_DEBUG: ERR = "DBUG"; break;
|
||||||
|
case E_FATAL: ERR = "FATL"; break;
|
||||||
|
case E_INFO: ERR = "INFO"; break;
|
||||||
|
case E_WARN: ERR = "WARN"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string s_msg = "[" + ERR + "] " + msg;
|
||||||
|
syslog( this->LOG_LEVEL, s_msg.c_str() );
|
||||||
|
|
||||||
|
if ( LOG_LEVEL == E_FATAL | LOG_LEVEL == E_WARN )
|
||||||
|
{
|
||||||
|
std::cerr << "[" << this->get_8601() << "]\t[" << this->mask << "]\t[" << ERR << "]\t" << msg.c_str() << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "[" << this->get_8601() << "]\t[" << this->mask << "]\t[" << ERR << "]\t" << msg.c_str() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logger::get_8601()
|
||||||
|
{
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto itt = std::chrono::system_clock::to_time_t(now);
|
||||||
|
std::ostringstream ss;
|
||||||
|
// ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
||||||
|
ss << std::put_time(localtime(&itt), "%Y-%m-%d_%H:%M:%S");
|
||||||
|
return ss.str();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// Created by bagira on 6/13/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef EXAMPLAR_LOGGER_H
|
||||||
|
#define EXAMPLAR_LOGGER_H
|
||||||
|
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
enum L_LVL {
|
||||||
|
E_INFO,
|
||||||
|
E_FATAL,
|
||||||
|
E_WARN,
|
||||||
|
E_DEBUG
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
Logger( int LOG_LEVEL, std::string mask );
|
||||||
|
void log( int LOG_LEVEL, std::string msg );
|
||||||
|
|
||||||
|
private:
|
||||||
|
int LOG_LEVEL;
|
||||||
|
const char * mask;
|
||||||
|
std::string get_8601();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //EXAMPLAR_LOGGER_H
|
|
@ -66,21 +66,23 @@ protected:
|
||||||
/// TODO Expand to detect when a directory path is supplied for units_path or plan_path and import all Tasks and Units.
|
/// TODO Expand to detect when a directory path is supplied for units_path or plan_path and import all Tasks and Units.
|
||||||
///
|
///
|
||||||
/// \param filename - The filename to load the configuration from.
|
/// \param filename - The filename to load the configuration from.
|
||||||
Conf::Conf( std::string filename, bool verbose ): JSON_Loader()
|
Conf::Conf( std::string filename, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "examplar::conf" )
|
||||||
{
|
{
|
||||||
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
|
|
||||||
// prepare context spaghetti
|
// prepare context spaghetti
|
||||||
this->override_context = false;
|
this->override_context = false;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// load the conf file.
|
// load the conf file.
|
||||||
this->load_json_file( filename, verbose );
|
this->load_json_file( filename );
|
||||||
}
|
}
|
||||||
catch (std::exception) {
|
catch (std::exception) {
|
||||||
throw ConfigLoadException("Could not find '" + filename + "'.");
|
this->slog.log( E_FATAL, "Unable to locate configuration file: '" + filename + "'." );
|
||||||
|
throw ConfigLoadException("Config file not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->get_serialized(this->config_version, "config_version" ,true) != 0)
|
if (this->get_serialized(this->config_version, "config_version" ) != 0)
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("config_version string is not set in the config file supplied: " + filename);
|
throw ConfigLoadException("config_version string is not set in the config file supplied: " + filename);
|
||||||
}
|
}
|
||||||
|
@ -90,38 +92,36 @@ Conf::Conf( std::string filename, bool verbose ): JSON_Loader()
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the path to the plan file
|
// find the path to the plan file
|
||||||
if (this->get_serialized(this->plan_path, "plan_path", true) != 0 )
|
if (this->get_serialized(this->plan_path, "plan_path" ) != 0 )
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("plan_path string is not set in the config file supplied:" + filename);
|
throw ConfigLoadException("plan_path string is not set in the config file supplied:" + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the path to the unit definitions file
|
// find the path to the unit definitions file
|
||||||
if (this->get_serialized(this->units_path, "units_path", true) != 0 )
|
if (this->get_serialized(this->units_path, "units_path" ) != 0 )
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename);
|
throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this->get_serialized(this->override_execution_context, "execution_context_override", true) != 0 )
|
if ( this->get_serialized(this->override_execution_context, "execution_context_override" ) != 0 )
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename);
|
throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename);
|
||||||
} else {
|
} else {
|
||||||
this->override_context = true;
|
this->override_context = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this->get_serialized(this->execution_context, "execution_context", true) != 0 )
|
if ( this->get_serialized(this->execution_context, "execution_context" ) != 0 )
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename);
|
throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename);
|
||||||
} else {
|
} else {
|
||||||
this->execution_context_literal = this->execution_context.asString();
|
this->execution_context_literal = this->execution_context.asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this->get_serialized(this->env_vars_file, "env_vars_file", true) != 0 )
|
if ( this->get_serialized(this->env_vars_file, "env_vars_file" ) != 0 )
|
||||||
{
|
{
|
||||||
throw ConfigLoadException("env_vars_file is not set in the config file supplied: " + filename);
|
throw ConfigLoadException("env_vars_file is not set in the config file supplied: " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the conf file.
|
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the conf file.
|
||||||
|
@ -137,7 +137,6 @@ std::string Conf::get_execution_context() {
|
||||||
/// Conf::get_plan_path - Retrieves the path to the Plan definition file from the application configuration file.
|
/// Conf::get_plan_path - Retrieves the path to the Plan definition file from the application configuration file.
|
||||||
std::string Conf::get_plan_path() { return this->plan_path.asString(); }
|
std::string Conf::get_plan_path() { return this->plan_path.asString(); }
|
||||||
|
|
||||||
|
|
||||||
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
||||||
std::string Conf::get_units_path() { return this->units_path.asString(); }
|
std::string Conf::get_units_path() { return this->units_path.asString(); }
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
|
|
||||||
#ifndef FTESTS_CONF_H
|
#ifndef FTESTS_CONF_H
|
||||||
#define FTESTS_CONF_H
|
#define FTESTS_CONF_H
|
||||||
#include "JSON_Loader.h"
|
#include "../low_level/JSON_Loader.h"
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include "../../Logger/Logger.h"
|
||||||
|
|
||||||
|
|
||||||
#define STRINGIZE2(s) #s
|
#define STRINGIZE2(s) #s
|
||||||
|
@ -47,17 +48,20 @@ private:
|
||||||
std::string execution_context_literal;
|
std::string execution_context_literal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Conf( std::string filename, bool verbose );
|
Conf( std::string filename, int LOG_LEVEL );
|
||||||
std::string get_plan_path();
|
|
||||||
std::string get_units_path();
|
|
||||||
|
|
||||||
bool has_context_override();
|
bool has_context_override();
|
||||||
|
|
||||||
|
std::string get_plan_path();
|
||||||
|
std::string get_units_path();
|
||||||
std::string get_execution_context();
|
std::string get_execution_context();
|
||||||
|
|
||||||
void set_execution_context( std::string );
|
void set_execution_context( std::string );
|
||||||
|
|
||||||
std::string get_env_vars_file();
|
std::string get_env_vars_file();
|
||||||
|
private:
|
||||||
|
int LOG_LEVEL;
|
||||||
|
Logger slog;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,40 +120,39 @@ protected:
|
||||||
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
|
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
|
||||||
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
|
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
|
||||||
/// definitions to execute, and if Units together form a Suite, Tasks together form a Plan.
|
/// definitions to execute, and if Units together form a Suite, Tasks together form a Plan.
|
||||||
Plan::Plan( Conf * configuration ): JSON_Loader()
|
Plan::Plan( Conf * configuration, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "examplar::plan" )
|
||||||
{
|
{
|
||||||
this->configuration = configuration;
|
this->configuration = configuration;
|
||||||
};
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
/// Plan::load_plan_file - Uses the json_root buffer on each run to append intact Units as they're deserialized from
|
/// Plan::load_plan_file - Uses the json_root buffer on each run to append intact Units as they're deserialized from
|
||||||
/// the provided file.
|
/// the provided file.
|
||||||
///
|
///
|
||||||
/// \param filename - The filename to load the plan from.
|
/// \param filename - The filename to load the plan from.
|
||||||
/// \param verbose - Whether to print verbose output to STDOUT.
|
/// \param verbose - Whether to print verbose output to STDOUT.
|
||||||
void Plan::load_plan_file(std::string filename, bool verbose)
|
void Plan::load_plan_file( std::string filename )
|
||||||
{
|
{
|
||||||
// plan always loads from file
|
// plan always loads from file
|
||||||
this->load_json_file( filename, verbose );
|
this->load_json_file( filename );
|
||||||
|
|
||||||
// staging buffer
|
// staging buffer
|
||||||
Json::Value jbuff;
|
Json::Value jbuff;
|
||||||
|
|
||||||
// fill the jbuff staging buffer wih a json::value object in the supplied filename
|
// fill the jbuff staging buffer wih a json::value object in the supplied filename
|
||||||
if ( this->get_serialized( jbuff, "plan", verbose ) == 0 )
|
if ( this->get_serialized( jbuff, "plan" ) == 0 )
|
||||||
{
|
{
|
||||||
this->json_root = jbuff;
|
this->json_root = jbuff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate through the json::value members that have been loaded. append to this->tasks vector
|
// iterate through the json::value members that have been loaded. append to this->tasks vector
|
||||||
// buffer for tasks to append:
|
// buffer for tasks to append:
|
||||||
Task tmp_T;
|
Task tmp_T = Task( this->LOG_LEVEL );
|
||||||
for ( int index = 0; index < this->json_root.size(); index++ )
|
for ( int index = 0; index < this->json_root.size(); index++ )
|
||||||
{
|
{
|
||||||
tmp_T.load_root( this->json_root[ index ], verbose );
|
tmp_T.load_root( this->json_root[ index ] );
|
||||||
this->tasks.push_back( tmp_T );
|
this->tasks.push_back( tmp_T );
|
||||||
if ( verbose ) {
|
this->slog.log( LOG_INFO, "Added task \"" + tmp_T.get_name() + "\" to Plan." );
|
||||||
std::cout << "Added task \"" << tmp_T.get_name() << "\" to Plan." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,10 +176,10 @@ void Plan::get_task(Task & result, int index )
|
||||||
///
|
///
|
||||||
/// \param unit_definitions - The Suite to load definitions from.
|
/// \param unit_definitions - The Suite to load definitions from.
|
||||||
/// \param verbose - Whether to print verbose information to STDOUT.
|
/// \param verbose - Whether to print verbose information to STDOUT.
|
||||||
void Plan::load_definitions( Suite unit_definitions, bool verbose )
|
void Plan::load_definitions( Suite unit_definitions )
|
||||||
{
|
{
|
||||||
// placeholder Unit
|
// placeholder Unit
|
||||||
Unit tmp_U;
|
Unit tmp_U = Unit( this->LOG_LEVEL );
|
||||||
|
|
||||||
// for every task in the plan:
|
// for every task in the plan:
|
||||||
for (int i = 0; i < this->tasks.size(); i++ )
|
for (int i = 0; i < this->tasks.size(); i++ )
|
||||||
|
@ -189,7 +188,7 @@ void Plan::load_definitions( Suite unit_definitions, bool verbose )
|
||||||
unit_definitions.get_unit( tmp_U, this->tasks[i].get_name() );
|
unit_definitions.get_unit( tmp_U, this->tasks[i].get_name() );
|
||||||
|
|
||||||
// then have that task attach a copy of tmp_U
|
// then have that task attach a copy of tmp_U
|
||||||
this->tasks[i].load_definition( tmp_U, verbose );
|
this->tasks[i].load_definition( tmp_U );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +212,7 @@ void Plan::get_task(Task & result, std::string provided_name )
|
||||||
}
|
}
|
||||||
if (! foundMatch )
|
if (! foundMatch )
|
||||||
{
|
{
|
||||||
std::cerr << "Task name \"" << provided_name << "\" was referenced but not defined!" << std::endl;
|
this->slog.log( E_FATAL, "Task name \"" + provided_name + "\" was referenced but not defined!" );
|
||||||
throw Plan_InvalidTaskName();
|
throw Plan_InvalidTaskName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,14 +225,14 @@ void Plan::get_task(Task & result, std::string provided_name )
|
||||||
bool Plan::all_dependencies_complete(std::string name)
|
bool Plan::all_dependencies_complete(std::string name)
|
||||||
{
|
{
|
||||||
// get the task by name
|
// get the task by name
|
||||||
Task named_task;
|
Task named_task = Task( this->LOG_LEVEL );
|
||||||
this->get_task( named_task, name );
|
this->get_task( named_task, name );
|
||||||
|
|
||||||
// get the dependencies of that task
|
// get the dependencies of that task
|
||||||
std::vector<std::string> deps = named_task.get_dependencies();
|
std::vector<std::string> deps = named_task.get_dependencies();
|
||||||
|
|
||||||
// create an empty task to assign values to during iteration
|
// create an empty task to assign values to during iteration
|
||||||
Task tmpTask;
|
Task tmpTask = Task( this->LOG_LEVEL );
|
||||||
// iterate through its dependencies
|
// iterate through its dependencies
|
||||||
for ( int i = 0; i < deps.size(); i++ )
|
for ( int i = 0; i < deps.size(); i++ )
|
||||||
{
|
{
|
||||||
|
@ -250,26 +249,26 @@ bool Plan::all_dependencies_complete(std::string name)
|
||||||
/// Plan::execute() - Iterates through all tasks in a plan and executes them.
|
/// Plan::execute() - Iterates through all tasks in a plan and executes them.
|
||||||
///
|
///
|
||||||
/// \param verbose
|
/// \param verbose
|
||||||
void Plan::execute( bool verbose )
|
void Plan::execute()
|
||||||
{
|
{
|
||||||
// for each task in this plan
|
// for each task in this plan
|
||||||
for ( int i = 0; i < this->tasks.size(); i++ )
|
for ( int i = 0; i < this->tasks.size(); i++ )
|
||||||
{
|
{
|
||||||
if (this->all_dependencies_complete(this->tasks[i].get_name()) )
|
if (this->all_dependencies_complete(this->tasks[i].get_name()) )
|
||||||
{
|
{
|
||||||
if ( verbose )
|
|
||||||
{
|
this->slog.log( E_INFO, "Executing task \"" + this->tasks[i].get_name() + "\"." );
|
||||||
std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
this->tasks[i].execute( this->configuration, verbose );
|
this->tasks[i].execute( this->configuration );
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
throw Plan_Task_GeneralExecutionException( "Plan Task: \"" + this->tasks[i].get_name() + "\" reported: " + e.what() );
|
this->slog.log( E_FATAL, "Plan Task: \"" + this->tasks[i].get_name() + "\" reported: " + e.what() );
|
||||||
|
throw Plan_Task_GeneralExecutionException("Could not execute task.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not all deps met for this task
|
// not all deps met for this task
|
||||||
throw Plan_Task_Missing_Dependency( "Plan Task \"" + this->tasks[i].get_name() + "\" was specified in the Plan but not executed due to missing dependencies. Please revise your plan." );
|
this->slog.log( E_FATAL, "Plan Task \"" + this->tasks[i].get_name() + "\" was specified in the Plan but not executed due to missing dependencies. Please revise your plan." );
|
||||||
|
throw Plan_Task_Missing_Dependency( "Unmet dependency for task." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,10 +22,11 @@
|
||||||
#define FTESTS_PLAN_H
|
#define FTESTS_PLAN_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../json/json.h"
|
#include "../../json/json.h"
|
||||||
#include "JSON_Loader.h"
|
#include "../low_level/JSON_Loader.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
|
#include "../../Logger/Logger.h"
|
||||||
|
|
||||||
class Plan: public JSON_Loader
|
class Plan: public JSON_Loader
|
||||||
{
|
{
|
||||||
|
@ -35,10 +36,10 @@ class Plan: public JSON_Loader
|
||||||
Conf * configuration;
|
Conf * configuration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Plan( Conf * configuration );
|
Plan( Conf * configuration, int LOG_LEVEL );
|
||||||
|
|
||||||
// append this->tasks from JSON file
|
// append this->tasks from JSON file
|
||||||
void load_plan_file( std::string filename, bool verbose );
|
void load_plan_file( std::string filename );
|
||||||
|
|
||||||
// fetch a task from this->tasks
|
// fetch a task from this->tasks
|
||||||
void get_task( Task & result, std::string provided_name );
|
void get_task( Task & result, std::string provided_name );
|
||||||
|
@ -47,15 +48,19 @@ class Plan: public JSON_Loader
|
||||||
void get_task( Task & result, int index );
|
void get_task( Task & result, int index );
|
||||||
|
|
||||||
// load unit definitions from a provided suite and import them into individual tasks
|
// load unit definitions from a provided suite and import them into individual tasks
|
||||||
void load_definitions( Suite unit_definitions, bool verbose );
|
void load_definitions( Suite unit_definitions );
|
||||||
|
|
||||||
// fetch a corresponding Unit to a Task
|
// fetch a corresponding Unit to a Task
|
||||||
// void get_definition_from_task(Unit & result, Task input, bool verbose );
|
// void get_definition_from_task(Unit & result, Task input, bool verbose );
|
||||||
|
|
||||||
// execute all tasks in this plan
|
// execute all tasks in this plan
|
||||||
void execute( bool verbose );
|
void execute();
|
||||||
|
|
||||||
bool all_dependencies_complete(std::string name);
|
bool all_dependencies_complete(std::string name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int LOG_LEVEL;
|
||||||
|
Logger slog;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FTESTS_PLAN_H
|
#endif //FTESTS_PLAN_H
|
|
@ -79,24 +79,13 @@ protected:
|
||||||
/// human processes to allow modularly developed profiles of test suites. As inferred, Unit is expected to be one of
|
/// human processes to allow modularly developed profiles of test suites. As inferred, Unit is expected to be one of
|
||||||
/// the two types that are only instantiated once per application run, though it is designed to be used more than once
|
/// the two types that are only instantiated once per application run, though it is designed to be used more than once
|
||||||
/// if the implementor so desires.
|
/// if the implementor so desires.
|
||||||
Suite::Suite(): JSON_Loader() {};
|
Suite::Suite( int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "examplar::suite" )
|
||||||
|
|
||||||
|
|
||||||
bool is_file( std::string path)
|
|
||||||
{
|
{
|
||||||
struct stat buf;
|
this->LOG_LEVEL;
|
||||||
stat( path.c_str(), &buf );
|
|
||||||
return S_ISREG(buf.st_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_dir( std::string path )
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
stat( path.c_str(), &buf );
|
|
||||||
return S_ISDIR(buf.st_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_units_from_dir( std::vector<std::string> * files, std::string path )
|
void Suite::get_units_from_dir( std::vector<std::string> * files, std::string path )
|
||||||
{
|
{
|
||||||
DIR* dirFile = opendir( path.c_str() );
|
DIR* dirFile = opendir( path.c_str() );
|
||||||
if ( dirFile )
|
if ( dirFile )
|
||||||
|
@ -107,11 +96,20 @@ void get_units_from_dir( std::vector<std::string> * files, std::string path )
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (( hFile = readdir( dirFile )) != NULL )
|
while (( hFile = readdir( dirFile )) != NULL )
|
||||||
{
|
{
|
||||||
if ( !strcmp( hFile->d_name, "." )) continue;
|
if ( !strcmp( hFile->d_name, "." ))
|
||||||
if ( !strcmp( hFile->d_name, ".." )) continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( !strcmp( hFile->d_name, ".." ))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// hidden files
|
// hidden files
|
||||||
if ( hFile->d_name[0] == '.' ) continue;
|
if ( hFile->d_name[0] == '.' )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// dirFile.name is the name of the file. Do whatever string comparison
|
// dirFile.name is the name of the file. Do whatever string comparison
|
||||||
// you want here. Something like:
|
// you want here. Something like:
|
||||||
|
@ -123,18 +121,17 @@ void get_units_from_dir( std::vector<std::string> * files, std::string path )
|
||||||
}
|
}
|
||||||
closedir( dirFile );
|
closedir( dirFile );
|
||||||
} else {
|
} else {
|
||||||
std::cout << "file not found" << std::endl;
|
this->slog.log( E_DEBUG, "File not found: " + path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Suite::load_units_file - Uses the json_root buffer on each run to append intact Units as they're
|
/// Suite::load_units_file - Uses the json_root buffer on each run to append intact Units as they're
|
||||||
/// deserialized from the provided file.
|
/// deserialized from the provided file.
|
||||||
///
|
///
|
||||||
/// \param units_path - The file to pull the JSON-formatted units from.
|
/// \param units_path - The file to pull the JSON-formatted units from.
|
||||||
/// \param verbose - Whether to print verbose output to STDOUT.
|
/// \param verbose - Whether to print verbose output to STDOUT.
|
||||||
void Suite::load_units_file( std::string units_path, bool verbose )
|
void Suite::load_units_file( std::string units_path )
|
||||||
{
|
{
|
||||||
std::vector<std::string> unit_files;
|
std::vector<std::string> unit_files;
|
||||||
|
|
||||||
|
@ -149,28 +146,26 @@ void Suite::load_units_file( std::string units_path, bool verbose )
|
||||||
unit_files.push_back( units_path );
|
unit_files.push_back( units_path );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream infostring;
|
this->slog.log( E_INFO, "Unit files found: " + std::to_string( unit_files.size() ) );
|
||||||
infostring << "Unit files found: " << unit_files.size() << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cerr << infostring.str();
|
|
||||||
|
|
||||||
for ( int i = 0; i < unit_files.size(); i++ )
|
for ( int i = 0; i < unit_files.size(); i++ )
|
||||||
{
|
{
|
||||||
// will use json_root buffer on each run to append to this->units vector as valid units are found.
|
// will use json_root buffer on each run to append to this->units vector as valid units are found.
|
||||||
this->load_json_file( unit_files[i], verbose );
|
this->load_json_file( unit_files[i] );
|
||||||
|
|
||||||
// staging buffer
|
// staging buffer
|
||||||
Json::Value jbuff;
|
Json::Value jbuff;
|
||||||
|
|
||||||
// fill the jbuff staging buffer with a json::value object in the supplied units_path
|
// fill the jbuff staging buffer with a json::value object in the supplied units_path
|
||||||
if ( this->get_serialized( jbuff, "units", verbose ) == 0)
|
if ( this->get_serialized( jbuff, "units" ) == 0)
|
||||||
{
|
{
|
||||||
this->json_root = jbuff;
|
this->json_root = jbuff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate through the json::value members that have been loaded. append to this->units vector
|
// iterate through the json::value members that have been loaded. append to this->units vector
|
||||||
// buffer for units to append:
|
// buffer for units to append:
|
||||||
Unit tmp_U;
|
Unit tmp_U = Unit( this->LOG_LEVEL );
|
||||||
|
|
||||||
for ( int index = 0; index < this->json_root.size(); index++ )
|
for ( int index = 0; index < this->json_root.size(); index++ )
|
||||||
{
|
{
|
||||||
// assemble the unit from json_root using the built-in value operator
|
// assemble the unit from json_root using the built-in value operator
|
||||||
|
@ -178,20 +173,13 @@ void Suite::load_units_file( std::string units_path, bool verbose )
|
||||||
if ( tmp_U.get_active() ) {
|
if ( tmp_U.get_active() ) {
|
||||||
// append to this->units
|
// append to this->units
|
||||||
this->units.push_back( tmp_U );
|
this->units.push_back( tmp_U );
|
||||||
if ( verbose ) {
|
this->slog.log( E_INFO, "Added unit \"" + tmp_U.get_name() + "\" to Suite.");
|
||||||
std::ostringstream infostring;
|
|
||||||
infostring << "Added unit \"" << tmp_U.get_name() << "\" to Suite." << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Suite::get_unit - returns a contained Unit identified by name attribute.
|
/// Suite::get_unit - returns a contained Unit identified by name attribute.
|
||||||
///
|
///
|
||||||
/// \param result - the unit type receiving the unit's value
|
/// \param result - the unit type receiving the unit's value
|
||||||
|
@ -213,11 +201,8 @@ void Suite::get_unit(Unit & result, std::string provided_name)
|
||||||
|
|
||||||
if (! foundMatch )
|
if (! foundMatch )
|
||||||
{
|
{
|
||||||
std::ostringstream infostring;
|
this->slog.log( E_FATAL, "Unit name \"" + provided_name + "\" was referenced but not defined!" );
|
||||||
infostring << "Unit name \"" << provided_name << "\" was referenced but not defined!" << std::endl;
|
throw SuiteException( "Undefined unit in use." );
|
||||||
syslog(LOG_ERR, infostring.str().c_str() );
|
|
||||||
std::cerr << infostring.str();
|
|
||||||
throw SuiteException( infostring.str() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,11 @@
|
||||||
#define FTESTS_UNITS_H
|
#define FTESTS_UNITS_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../json/json.h"
|
#include "../../json/json.h"
|
||||||
#include "JSON_Loader.h"
|
#include "../low_level/JSON_Loader.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
|
#include "../../Logger/Logger.h"
|
||||||
|
#include "../misc/helpers.h"
|
||||||
|
|
||||||
|
|
||||||
class Suite: public JSON_Loader
|
class Suite: public JSON_Loader
|
||||||
|
@ -34,14 +36,22 @@ class Suite: public JSON_Loader
|
||||||
std::vector<Unit> units;
|
std::vector<Unit> units;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor, empty
|
// constructor
|
||||||
Suite();
|
Suite( int LOG_LEVEL );
|
||||||
|
|
||||||
// load a unit definitions file and add valid unit definitions to this->units
|
// load a unit definitions file and add valid unit definitions to this->units
|
||||||
void load_units_file( std::string filename, bool verbose );
|
void load_units_file( std::string filename );
|
||||||
|
|
||||||
// returns the unit identified by name
|
// returns the unit identified by name
|
||||||
void get_unit(Unit & result, std::string provided_name);
|
void get_unit(Unit & result, std::string provided_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void get_units_from_dir( std::vector<std::string> * files, std::string path );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int LOG_LEVEL;
|
||||||
|
Logger slog;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FTESTS_UNITS_H
|
#endif //FTESTS_UNITS_H
|
|
@ -19,10 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include "../sproc/Sproc.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
|
|
||||||
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
||||||
class Task_InvalidDataStructure: public std::runtime_error {
|
class Task_InvalidDataStructure: public std::runtime_error {
|
||||||
|
@ -82,20 +79,24 @@ protected:
|
||||||
|
|
||||||
/// Task::Task() - Constructor for the Task class. The Task is the building block of a Plan indicating of which Unit to
|
/// Task::Task() - Constructor for the Task class. The Task is the building block of a Plan indicating of which Unit to
|
||||||
/// execute, and its dependencies on other units to have already been completed successfully.
|
/// execute, and its dependencies on other units to have already been completed successfully.
|
||||||
Task::Task()
|
Task::Task( int LOG_LEVEL ):
|
||||||
|
slog( LOG_LEVEL, "examplar::task" ),
|
||||||
|
definition( LOG_LEVEL )
|
||||||
{
|
{
|
||||||
// it hasn't executed yet.
|
// it hasn't executed yet.
|
||||||
this->complete = false;
|
this->complete = false;
|
||||||
|
|
||||||
// it hasn't been matched with a definition yet.
|
// it hasn't been matched with a definition yet.
|
||||||
this->defined = false;
|
this->defined = false;
|
||||||
|
|
||||||
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Task::load_root() - loads json values to private members
|
/// Task::load_root() - loads json values to private members
|
||||||
///
|
///
|
||||||
/// \param loader_root - the Json::Value to populate from.
|
/// \param loader_root - the Json::Value to populate from.
|
||||||
/// \param verbose - Whether to print verbose information to STDOUT.
|
/// \param verbose - Whether to print verbose information to STDOUT.
|
||||||
void Task::load_root(Json::Value loader_root, bool verbose )
|
void Task::load_root(Json::Value loader_root )
|
||||||
{
|
{
|
||||||
if ( loader_root.isMember("name") ) {
|
if ( loader_root.isMember("name") ) {
|
||||||
this->name = loader_root.get("name", "?").asString();
|
this->name = loader_root.get("name", "?").asString();
|
||||||
|
@ -110,16 +111,10 @@ void Task::load_root(Json::Value loader_root, bool verbose )
|
||||||
// iterate through each member of that obj
|
// iterate through each member of that obj
|
||||||
for ( int i = 0; i < des_dep_root.size(); i++ ) {
|
for ( int i = 0; i < des_dep_root.size(); i++ ) {
|
||||||
// add each string to dependencies
|
// add each string to dependencies
|
||||||
if ( des_dep_root[i].asString() != "" ) {
|
if ( des_dep_root[i].asString() != "" )
|
||||||
|
{
|
||||||
this->dependencies.push_back( des_dep_root[i].asString() );
|
this->dependencies.push_back( des_dep_root[i].asString() );
|
||||||
if ( verbose ) {
|
this->slog.log( E_INFO, "Added dependency \"" + des_dep_root[i].asString() + "\" to task \"" + this->get_name() + "\"." );
|
||||||
std::ostringstream infostring;
|
|
||||||
infostring << "Added dependency \"" << des_dep_root[i].asString() << "\" to task \""
|
|
||||||
<< this->get_name() << "\"." << std::endl;
|
|
||||||
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,17 +129,10 @@ std::string Task::get_name()
|
||||||
///
|
///
|
||||||
/// \param selected_unit - The unit to attach.
|
/// \param selected_unit - The unit to attach.
|
||||||
/// \param verbose - Whether to print to STDOUT.
|
/// \param verbose - Whether to print to STDOUT.
|
||||||
void Task::load_definition( Unit selected_unit, bool verbose )
|
void Task::load_definition( Unit selected_unit )
|
||||||
{
|
{
|
||||||
this->definition = selected_unit;
|
this->definition = selected_unit;
|
||||||
if ( verbose ) {
|
this->slog.log( E_INFO, "Loaded definition \"" + selected_unit.get_name() + "\" for task \"" + this->get_name() + "\".");
|
||||||
std::ostringstream infostring;
|
|
||||||
infostring << "Loaded definition \"" << selected_unit.get_name() << "\" for task \""
|
|
||||||
<< this->get_name() << "\"." << std::endl;
|
|
||||||
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
|
||||||
this->defined = true;
|
this->defined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +165,7 @@ bool Task::has_definition()
|
||||||
/// Task::execute - execute a task's unit definition.
|
/// Task::execute - execute a task's unit definition.
|
||||||
/// See the design document for what flow control needs to look like here.
|
/// See the design document for what flow control needs to look like here.
|
||||||
/// \param verbose - Verbosity level - not implemented yet.
|
/// \param verbose - Verbosity level - not implemented yet.
|
||||||
void Task::execute( Conf * configuration, bool verbose )
|
void Task::execute( Conf * configuration )
|
||||||
{
|
{
|
||||||
// DUFFING - If Examplar is broken it's probably going to be in this block.
|
// DUFFING - If Examplar is broken it's probably going to be in this block.
|
||||||
// Somebody come clean this up, eh?
|
// Somebody come clean this up, eh?
|
||||||
|
@ -192,40 +180,26 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
|
|
||||||
// get the name
|
// get the name
|
||||||
std::string task_name = this->definition.get_name();
|
std::string task_name = this->definition.get_name();
|
||||||
|
this->slog.log( E_DEBUG, "\tUsing unit: \"" + task_name + "\"." );
|
||||||
// END PREWORK
|
// END PREWORK
|
||||||
|
|
||||||
// get the target execution command
|
// get the target execution command
|
||||||
std::string target_command = this->definition.get_target();
|
std::string target_command = this->definition.get_target();
|
||||||
|
|
||||||
// if we're in verbose mode, do some verbose things
|
// check if context override
|
||||||
if ( verbose )
|
if ( configuration->has_context_override() )
|
||||||
{
|
{
|
||||||
/*
|
// if so, set the CWD.
|
||||||
infostring = std::ostringstream();
|
chdir( configuration->get_execution_context().c_str() );
|
||||||
infostring << "\tUsing unit \"" << task_name << "\"." << std::endl;
|
this->slog.log( E_INFO, "Setting execution context: " + get_working_path() );
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// check if context override
|
|
||||||
if ( configuration->has_context_override() )
|
|
||||||
{
|
|
||||||
// if so, set the CWD.
|
|
||||||
chdir( configuration->get_execution_context().c_str() );
|
|
||||||
infostring = std::ostringstream();
|
|
||||||
infostring << "\tExecution context: " << get_working_path() << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
infostring = std::ostringstream();
|
|
||||||
infostring << "\tExecuting target \"" << target_command << "\"." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// a[0] execute target
|
// a[0] execute target
|
||||||
// TODO revise variable sourcing strategy
|
// TODO revise variable sourcing strategy
|
||||||
|
|
||||||
|
this->slog.log( E_DEBUG, "Loading environment variable file: " + configuration->get_env_vars_file() );
|
||||||
|
this->slog.log( E_INFO, "Executing target: \"" + target_command + "\"." );
|
||||||
int return_code = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + target_command );
|
int return_code = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + target_command );
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
|
@ -234,13 +208,8 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( return_code == 0 )
|
if ( return_code == 0 )
|
||||||
{
|
{
|
||||||
// d[0].0 ZERO
|
// d[0].0 ZERO
|
||||||
|
this->slog.log( E_INFO, "Target \"" + task_name + "\" succeeded. Marking as complete." );
|
||||||
|
|
||||||
if ( verbose ) {
|
|
||||||
infostring = std::ostringstream();
|
|
||||||
infostring << "\tTarget " << task_name << " succeeded. Marking as complete." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
}
|
|
||||||
this->mark_complete();
|
this->mark_complete();
|
||||||
|
|
||||||
// a[1] NEXT
|
// a[1] NEXT
|
||||||
|
@ -250,12 +219,7 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( return_code != 0 )
|
if ( return_code != 0 )
|
||||||
{
|
{
|
||||||
// d[0].1 NON-ZERO
|
// d[0].1 NON-ZERO
|
||||||
|
this->slog.log( E_WARN, "Target \"" + task_name + "\" failed with exit code " + std::to_string( return_code ) + "." );
|
||||||
infostring = std::ostringstream();
|
|
||||||
infostring << "\tTarget \"" << task_name << "\" failed with exit code " << return_code << "." << std::endl;
|
|
||||||
|
|
||||||
syslog(LOG_ERR, infostring.str().c_str() );
|
|
||||||
std::cerr << infostring.str();
|
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// d[1] Rectify Check
|
// d[1] Rectify Check
|
||||||
|
@ -271,18 +235,13 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// d[2].0 FALSE
|
// d[2].0 FALSE
|
||||||
// a[2] NEXT
|
// a[2] NEXT
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "This task is not required to continue the plan. Moving on." );
|
||||||
infostring << "\tThis task is not required to continue the plan. Moving on." << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if ( this->definition.get_required() )
|
|
||||||
{
|
|
||||||
// d[2].1 TRUE
|
// d[2].1 TRUE
|
||||||
// a[3] EXCEPTION
|
// a[3] EXCEPTION
|
||||||
throw TaskException("Task \"" + task_name + "\" is required, and failed, and rectification is not enabled.");
|
this->slog.log( E_FATAL, "Task \"" + task_name + "\" is required, and failed, and rectification is not enabled." );
|
||||||
|
throw TaskException( "Task failed: " + task_name );
|
||||||
}
|
}
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// end - d[2] Required Check
|
// end - d[2] Required Check
|
||||||
|
@ -293,18 +252,12 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( this->definition.get_rectify() )
|
if ( this->definition.get_rectify() )
|
||||||
{
|
{
|
||||||
// d[1].1 TRUE (Rectify Check)
|
// d[1].1 TRUE (Rectify Check)
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "Rectification pattern is enabled for \"" + task_name + "\"." );
|
||||||
infostring << "\tRectification pattern is enabled for \"" << task_name << "\"." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
// a[4] Execute RECTIFIER
|
// a[4] Execute RECTIFIER
|
||||||
std::string rectifier_command = this->definition.get_rectifier();
|
std::string rectifier_command = this->definition.get_rectifier();
|
||||||
|
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "Executing rectification: " + rectifier_command + "." );
|
||||||
infostring << "\tExecuting rectification: " << rectifier_command << "." << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
int rectifier_error = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + rectifier_command );
|
int rectifier_error = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + rectifier_command );
|
||||||
|
|
||||||
|
@ -314,12 +267,7 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( rectifier_error != 0 )
|
if ( rectifier_error != 0 )
|
||||||
{
|
{
|
||||||
// d[3].1 Non-Zero
|
// d[3].1 Non-Zero
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_WARN, "Rectification of \"" + task_name + "\" failed with exit code " + std::to_string( rectifier_error ) + "." );
|
||||||
infostring << "\tRectification of \"" << task_name << "\" failed with exit code "
|
|
||||||
<< rectifier_error << "." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// d[4] Required Check
|
// d[4] Required Check
|
||||||
|
@ -327,10 +275,7 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( ! this->definition.get_required() ) {
|
if ( ! this->definition.get_required() ) {
|
||||||
// d[4].0 FALSE
|
// d[4].0 FALSE
|
||||||
// a[5] NEXT
|
// a[5] NEXT
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "This task is not required to continue the plan. Moving on." );
|
||||||
infostring << "\tThis task is not required to continue the plan. Moving on." << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +283,8 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// d[4].1 TRUE
|
// d[4].1 TRUE
|
||||||
// a[6] EXCEPTION
|
// a[6] EXCEPTION
|
||||||
throw TaskException("Task \"" + task_name + "\" is required, and failed, then rectified but rectification failed.");
|
this->slog.log( E_FATAL, "Task \"" + task_name + "\" is required, it failed, and then rectification failed. Lost cause." );
|
||||||
|
throw TaskException( "Lost cause, task failure." );
|
||||||
}
|
}
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// end - d[4] Required Check
|
// end - d[4] Required Check
|
||||||
|
@ -349,16 +295,10 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
if ( rectifier_error == 0 )
|
if ( rectifier_error == 0 )
|
||||||
{
|
{
|
||||||
// d[3].0 Zero
|
// d[3].0 Zero
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "Rectification returned successfully." );
|
||||||
infostring << "\tRectification returned successfully." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
// a[7] Re-execute Target
|
// a[7] Re-execute Target
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "Re-Executing target \"" + this->definition.get_target() + "\"." );
|
||||||
infostring << "\tRe-Executing target \"" << this->definition.get_target() << "\"." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
int retry_code = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + target_command );
|
int retry_code = Sproc::execute( "source " + configuration->get_env_vars_file() + " && " + target_command );
|
||||||
|
|
||||||
|
@ -369,20 +309,11 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// d[5].0 ZERO
|
// d[5].0 ZERO
|
||||||
// a[8] NEXT
|
// a[8] NEXT
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "Re-execution was successful." );
|
||||||
infostring << "\tRe-execution was successful." << std::endl;
|
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if ( retry_code != 0 )
|
|
||||||
{
|
|
||||||
// d[5].1 NON-ZERO
|
// d[5].1 NON-ZERO
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_WARN, "Re-execution failed with exit code " + std::to_string( retry_code ) + "." );
|
||||||
infostring << "\tRe-execution failed with exit code " << retry_code << "." << std::endl;
|
|
||||||
syslog(LOG_ERR, infostring.str().c_str() );
|
|
||||||
std::cerr << infostring.str();
|
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// d[6] Required Check
|
// d[6] Required Check
|
||||||
|
@ -391,11 +322,7 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// d[6].0 FALSE
|
// d[6].0 FALSE
|
||||||
// a[9] NEXT
|
// a[9] NEXT
|
||||||
infostring = std::ostringstream();
|
this->slog.log( E_INFO, "This task is not required to continue the plan. Moving on." );
|
||||||
infostring << "\tThis task is not required to continue the plan. Moving on." << std::endl;
|
|
||||||
syslog(LOG_INFO, infostring.str().c_str() );
|
|
||||||
std::cout << infostring.str();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +330,8 @@ void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// d[6].1 TRUE
|
// d[6].1 TRUE
|
||||||
// a[10] EXCEPTION
|
// a[10] EXCEPTION
|
||||||
throw TaskException("Task \"" + task_name + "\" is required, and failed, then rectified but rectifier did not heal the condition causing the target to fail. Cannot proceed with Plan.");
|
this->slog.log( E_FATAL, "Task \"" + task_name + "\" is required, and failed, then rectified but rectifier did not heal the condition causing the target to fail. Cannot proceed with Plan." );
|
||||||
|
throw TaskException( "Lost cause, task failure." );
|
||||||
}
|
}
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// end - d[6] Required Check
|
// end - d[6] Required Check
|
|
@ -22,10 +22,13 @@
|
||||||
#define FTESTS_TASK_H
|
#define FTESTS_TASK_H
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "../json/json.h"
|
#include "../../json/json.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "Suite.h"
|
#include "Suite.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../../Sproc/Sproc.h"
|
||||||
|
#include "../misc/helpers.h"
|
||||||
|
|
||||||
class Task
|
class Task
|
||||||
{
|
{
|
||||||
|
@ -49,13 +52,13 @@ class Task
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
Task();
|
Task( int LOG_LEVEL );
|
||||||
|
|
||||||
// load a json::value into task members (second stage deserialization)
|
// load a json::value into task members (second stage deserialization)
|
||||||
void load_root( Json::Value loader_root, bool verbose );
|
void load_root( Json::Value loader_root );
|
||||||
|
|
||||||
// appends definition unit as child member
|
// appends definition unit as child member
|
||||||
void load_definition( Unit definition, bool verbose );
|
void load_definition( Unit definition );
|
||||||
|
|
||||||
bool is_complete();
|
bool is_complete();
|
||||||
bool has_definition();
|
bool has_definition();
|
||||||
|
@ -64,12 +67,16 @@ class Task
|
||||||
std::string get_name();
|
std::string get_name();
|
||||||
|
|
||||||
// execute this task's definition
|
// execute this task's definition
|
||||||
void execute( Conf * configuration, bool verbose );
|
void execute( Conf * configuration );
|
||||||
|
|
||||||
void mark_complete();
|
void mark_complete();
|
||||||
|
|
||||||
// returns a pointer to the dependencies vector
|
// returns a pointer to the dependencies vector
|
||||||
std::vector<std::string> get_dependencies();
|
std::vector<std::string> get_dependencies();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger slog;
|
||||||
|
int LOG_LEVEL;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FTESTS_TASK_H
|
#endif //FTESTS_TASK_H
|
|
@ -48,7 +48,10 @@ class Unit_DataStructureException: public std::runtime_error { public:
|
||||||
/// required, which is used as a flag to halt or continue if rectifier does not heal the system in such a way that
|
/// required, which is used as a flag to halt or continue if rectifier does not heal the system in such a way that
|
||||||
/// target can run successfully.
|
/// target can run successfully.
|
||||||
/// rectify, which is used as a flag to determine in the rectifier runs.
|
/// rectify, which is used as a flag to determine in the rectifier runs.
|
||||||
Unit::Unit() {}
|
Unit::Unit( int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "examplar::unit" )
|
||||||
|
{
|
||||||
|
this->LOG_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
/// Unit::load_root - Takes a JSON::Value and assigns the members to the Unit being populated.
|
/// Unit::load_root - Takes a JSON::Value and assigns the members to the Unit being populated.
|
||||||
///
|
///
|
||||||
|
@ -92,7 +95,7 @@ int Unit::load_root(Json::Value loader_root)
|
||||||
int Unit::load_string(std::string json_val)
|
int Unit::load_string(std::string json_val)
|
||||||
{
|
{
|
||||||
// serialize
|
// serialize
|
||||||
this->load_json_string( json_val, true );
|
this->load_json_string( json_val );
|
||||||
|
|
||||||
// deserialize
|
// deserialize
|
||||||
this->load_root( this->json_root );
|
this->load_root( this->json_root );
|
|
@ -26,8 +26,9 @@
|
||||||
#ifndef FTESTS_UNIT_H
|
#ifndef FTESTS_UNIT_H
|
||||||
#define FTESTS_UNIT_H
|
#define FTESTS_UNIT_H
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../json/json.h"
|
#include "../../json/json.h"
|
||||||
#include "JSON_Loader.h"
|
#include "../low_level/JSON_Loader.h"
|
||||||
|
#include "../../Logger/Logger.h"
|
||||||
|
|
||||||
class Unit: JSON_Loader
|
class Unit: JSON_Loader
|
||||||
{
|
{
|
||||||
|
@ -59,7 +60,7 @@ private:
|
||||||
bool rectify;
|
bool rectify;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Unit();
|
Unit( int LOG_LEVEL );
|
||||||
|
|
||||||
// loads a serialized jason::value object as a unit
|
// loads a serialized jason::value object as a unit
|
||||||
int load_root( Json::Value loader_root );
|
int load_root( Json::Value loader_root );
|
||||||
|
@ -75,6 +76,10 @@ public:
|
||||||
bool get_active();
|
bool get_active();
|
||||||
bool get_required();
|
bool get_required();
|
||||||
bool get_rectify();
|
bool get_rectify();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int LOG_LEVEL;
|
||||||
|
Logger slog;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FTESTS_UNIT_H
|
#endif //FTESTS_UNIT_H
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef FTESTS_LOADERS_H
|
#ifndef FTESTS_LOADERS_H
|
||||||
#define FTESTS_LOADERS_H
|
#define FTESTS_LOADERS_H
|
||||||
|
|
||||||
#include "JSON_Loader.h"
|
#include "../low_level/JSON_Loader.h"
|
||||||
#include "Suite.h"
|
#include "Suite.h"
|
||||||
#include "Plan.h"
|
#include "Plan.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
|
@ -19,8 +19,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "JSON_Loader.h"
|
#include "JSON_Loader.h"
|
||||||
#include "helpers.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
/// JSON_Loader_NotReady - Exception thrown when a member function is called before data is populated.
|
/// JSON_Loader_NotReady - Exception thrown when a member function is called before data is populated.
|
||||||
class JSON_Loader_NotReady: public std::runtime_error { public:
|
class JSON_Loader_NotReady: public std::runtime_error { public:
|
||||||
|
@ -40,51 +38,10 @@ class JSON_Loader_InvalidJSON: public std::runtime_error { public:
|
||||||
/// JSON_Loader::JSON_Loader - Constructor for JSON_Loader base class. Simply inits to an unpopulated state.
|
/// JSON_Loader::JSON_Loader - Constructor for JSON_Loader base class. Simply inits to an unpopulated state.
|
||||||
///
|
///
|
||||||
/// The JSON_Loader type is a base type. It is meant to provide the functionalities shared between Suite and Plan.
|
/// The JSON_Loader type is a base type. It is meant to provide the functionalities shared between Suite and Plan.
|
||||||
JSON_Loader::JSON_Loader()
|
JSON_Loader::JSON_Loader( int LOG_LEVEL ): slog( LOG_LEVEL, "examplar::json_loader" )
|
||||||
{
|
{
|
||||||
this->populated = false;
|
this->populated = false;
|
||||||
}
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
|
|
||||||
/// JSON_Loader::load_json_file - Loads JSON from a filepath into a serialized representation assigned as a local member
|
|
||||||
/// intended to be used as a buffer for further operations by base methods and derived class methods.
|
|
||||||
///
|
|
||||||
/// \param filename -
|
|
||||||
/// \param 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;
|
|
||||||
|
|
||||||
// the a deserialized json type to contain what's read by the reader
|
|
||||||
Json::Value json_root;
|
|
||||||
|
|
||||||
// first, check if the file exists
|
|
||||||
if (! exists( filename ) )
|
|
||||||
{
|
|
||||||
std::cerr << "File '" << filename << "' does not exist." << std::endl;
|
|
||||||
throw JSON_Loader_FileNotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the ifstream file handle
|
|
||||||
std::ifstream json_file_ifstream( filename, std::ifstream::binary );
|
|
||||||
|
|
||||||
// use the reader to parse the ifstream to the local property
|
|
||||||
bool parsingSuccessful = json_reader.parse( json_file_ifstream, this->json_root );
|
|
||||||
|
|
||||||
if (! parsingSuccessful )
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to parse '" << filename << "':\n\t" << json_reader.getFormattedErrorMessages();
|
|
||||||
throw JSON_Loader_InvalidJSON();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// if in verbose mode, give the user an "it worked" message
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
std::cout << "Parsed '" << filename << "' with " << this->json_root.size() << " element(s)." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Flag as ready for consumption.
|
|
||||||
this->populated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON_Loader::load_json_string - loads json from std::string into a json::value type and sets to protected member
|
/// JSON_Loader::load_json_string - loads json from std::string into a json::value type and sets to protected member
|
||||||
|
@ -92,7 +49,7 @@ void JSON_Loader::load_json_file( std::string filename, bool verbose )
|
||||||
///
|
///
|
||||||
/// \param input - The JSON-formatted string to serialize
|
/// \param input - The JSON-formatted string to serialize
|
||||||
/// \param verbose - Whether or not to print verbose information to STDOUT.
|
/// \param verbose - Whether or not to print verbose information to STDOUT.
|
||||||
void JSON_Loader::load_json_string( std::string input, bool verbose )
|
void JSON_Loader::load_json_string( std::string input )
|
||||||
{
|
{
|
||||||
// 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;
|
||||||
|
@ -108,18 +65,52 @@ void 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();
|
this->slog.log( E_FATAL, "Failed to parse adhoc JSON value: " + json_reader.getFormattedErrorMessages() );
|
||||||
|
throw JSON_Loader_InvalidJSON();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->slog.log( E_DEBUG, "Successfully parsed JSON string with " + std::to_string( this->json_root.size() ) + "elements. Value: '" + input + "'." );
|
||||||
|
}
|
||||||
|
// flag as ready for consumption
|
||||||
|
this->populated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// JSON_Loader::load_json_file - Loads JSON from a filepath into a serialized representation assigned as a local member
|
||||||
|
/// intended to be used as a buffer for further operations by base methods and derived class methods.
|
||||||
|
///
|
||||||
|
/// \param filename -
|
||||||
|
/// \param verbose
|
||||||
|
void JSON_Loader::load_json_file( std::string filename )
|
||||||
|
{
|
||||||
|
// reads from a file into a Json::Value type.
|
||||||
|
Json::Reader json_reader;
|
||||||
|
|
||||||
|
// the a deserialized json type to contain what's read by the reader
|
||||||
|
Json::Value json_root;
|
||||||
|
|
||||||
|
// first, check if the file exists
|
||||||
|
if (! exists( filename ) )
|
||||||
|
{
|
||||||
|
this->slog.log( E_FATAL, "File '" + filename + "' does not exist." );
|
||||||
|
throw JSON_Loader_FileNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the ifstream file handle
|
||||||
|
std::ifstream json_file_ifstream( filename, std::ifstream::binary );
|
||||||
|
|
||||||
|
// use the reader to parse the ifstream to the local property
|
||||||
|
bool parsingSuccessful = json_reader.parse( json_file_ifstream, this->json_root );
|
||||||
|
|
||||||
|
if (! parsingSuccessful )
|
||||||
|
{
|
||||||
|
this->slog.log( E_FATAL, "Failed to parse file '" + filename + "': " + json_reader.getFormattedErrorMessages() );
|
||||||
throw JSON_Loader_InvalidJSON();
|
throw JSON_Loader_InvalidJSON();
|
||||||
|
|
||||||
} 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 )
|
this->slog.log( E_DEBUG, "Parsed '" + filename + "' with " + std::to_string( this->json_root.size() ) + " element(s)." );
|
||||||
{
|
|
||||||
std::cout << "Successfully parsed JSON string with " << this->json_root.size() << " elements. Value:" << std::endl;
|
|
||||||
std::cout << input << std::endl << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// flag as ready for consumption
|
// Flag as ready for consumption.
|
||||||
this->populated = true;
|
this->populated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +129,7 @@ std::string JSON_Loader::as_string()
|
||||||
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
||||||
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
||||||
/// \return - Boolean indicator of success or failure (0|1)
|
/// \return - Boolean indicator of success or failure (0|1)
|
||||||
int JSON_Loader::get_serialized(Json::Value &input, std::string key, bool verbose)
|
int JSON_Loader::get_serialized(Json::Value &input, std::string key )
|
||||||
{
|
{
|
||||||
// throw if the class is not ready to be used.
|
// throw if the class is not ready to be used.
|
||||||
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
||||||
|
@ -151,11 +142,10 @@ int JSON_Loader::get_serialized(Json::Value &input, std::string key, bool verbos
|
||||||
}
|
}
|
||||||
|
|
||||||
// key was not found
|
// key was not found
|
||||||
if ( verbose )
|
|
||||||
{
|
// verbose mode tells the user what key we were looking for.
|
||||||
// verbose mode tells the user what key we were looking for.
|
this->slog.log( E_FATAL, "Failed to find key '" + key + "'." );
|
||||||
std::cerr << "Failed to find key '" << key << "'." << std::endl;
|
|
||||||
}
|
|
||||||
// exit code for failure
|
// exit code for failure
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
|
@ -19,11 +19,13 @@
|
||||||
*/
|
*/
|
||||||
#ifndef FTESTS_JLOADER_H
|
#ifndef FTESTS_JLOADER_H
|
||||||
#define FTESTS_JLOADER_H
|
#define FTESTS_JLOADER_H
|
||||||
#include "../json/json.h"
|
#include "../../json/json.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "../misc/helpers.h"
|
||||||
|
#include "../../Logger/Logger.h"
|
||||||
|
|
||||||
class JSON_Loader
|
class JSON_Loader
|
||||||
{
|
{
|
||||||
|
@ -33,13 +35,13 @@ class JSON_Loader
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
JSON_Loader();
|
JSON_Loader( int LOG_LEVEL );
|
||||||
|
|
||||||
// load from json file
|
// load from json file
|
||||||
void load_json_file( std::string filename, bool verbose );
|
void load_json_file( std::string filename );
|
||||||
|
|
||||||
// load from std::string json
|
// load from std::string json
|
||||||
void load_json_string( std::string input, bool verbose );
|
void load_json_string( std::string input );
|
||||||
|
|
||||||
// return as a JSONCPP serialized object
|
// return as a JSONCPP serialized object
|
||||||
// deprecated -- these aren't really used.
|
// deprecated -- these aren't really used.
|
||||||
|
@ -47,6 +49,10 @@ class JSON_Loader
|
||||||
std::string as_string();
|
std::string as_string();
|
||||||
|
|
||||||
// safely handle deserialized type retrieval (if we want it to be safe)
|
// safely handle deserialized type retrieval (if we want it to be safe)
|
||||||
int get_serialized(Json::Value &input, std::string key, bool verbose);
|
int get_serialized(Json::Value &input, std::string key );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger slog;
|
||||||
|
int LOG_LEVEL;
|
||||||
};
|
};
|
||||||
#endif //FTESTS_JLOADER_H
|
#endif //FTESTS_JLOADER_H
|
|
@ -31,3 +31,17 @@ std::string get_working_path()
|
||||||
char temp[MAXPATHLEN];
|
char temp[MAXPATHLEN];
|
||||||
return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") );
|
return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_file( std::string path)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
stat( path.c_str(), &buf );
|
||||||
|
return S_ISREG(buf.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir( std::string path )
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
stat( path.c_str(), &buf );
|
||||||
|
return S_ISDIR(buf.st_mode);
|
||||||
|
}
|
|
@ -29,5 +29,7 @@
|
||||||
bool exists (const std::string& name);
|
bool exists (const std::string& name);
|
||||||
|
|
||||||
std::string get_working_path();
|
std::string get_working_path();
|
||||||
|
bool is_file( std::string );
|
||||||
|
bool is_dir( std::string );
|
||||||
|
|
||||||
#endif //FTESTS_HELPERS_H
|
#endif //FTESTS_HELPERS_H
|
Loading…
Reference in New Issue