From c87a56eb371d6bc254fece6b670733664005f3e0 Mon Sep 17 00:00:00 2001 From: Chris Punches Date: Mon, 26 Jun 2017 22:27:24 -0400 Subject: [PATCH] ready to implement external execution aspect of task --- conf/units/all_test.units | 9 +++++++++ examplar.cpp | 6 +++++- src/loaders/Conf.cpp | 4 ++-- src/loaders/Conf.h | 2 +- src/loaders/Plan.cpp | 18 +++++++++++++++++- src/loaders/Plan.h | 5 ++++- src/loaders/Task.cpp | 22 ++++++++++++++++++++++ src/loaders/Task.h | 3 +++ 8 files changed, 63 insertions(+), 6 deletions(-) diff --git a/conf/units/all_test.units b/conf/units/all_test.units index f3abb05..6f76a54 100644 --- a/conf/units/all_test.units +++ b/conf/units/all_test.units @@ -18,6 +18,15 @@ "required": true, "rectify": true }, + { + "name": "A DEFINITION THAT IS NOT USED", + "target": "/bin/pwd", + "output": "pass", + "rectifier": "/bin/pwd", + "active": true, + "required": true, + "rectify": true + }, { "name": "dependent test", "target": "/home/phanes/tests/test-script-pass.sh", diff --git a/examplar.cpp b/examplar.cpp index a6c88b2..dc8959e 100644 --- a/examplar.cpp +++ b/examplar.cpp @@ -7,7 +7,7 @@ int main( ) bool verbose = true; // A Plan is made up of Tasks, and a Suite is made up of Units. // A Plan declares what units are executed and a Suite declares the definitions of those units. - Conf configuration = Conf("/home/phanes/Development/internal/Examplar/conf/config.json"); + Conf configuration = Conf("/home/phanes/Development/internal/Examplar/conf/config.json", verbose ); // load the configuration file which contains filepaths to definitions of a plan and definitions of units. std::string definitions_file = configuration.get_units_path(); @@ -21,5 +21,9 @@ int main( ) plan.load_definitions( available_definitions, verbose ); + std::cout << "Ready to execute all tasks in Plan." << std::endl; + + plan.execute( verbose ); + return 0; } \ No newline at end of file diff --git a/src/loaders/Conf.cpp b/src/loaders/Conf.cpp index e5a6113..f9dec5d 100644 --- a/src/loaders/Conf.cpp +++ b/src/loaders/Conf.cpp @@ -16,10 +16,10 @@ class CONF_UNITSPATH_INVALID: public std::runtime_error { public: /// 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. -Conf::Conf( std::string filename ): JSON_Loader() +Conf::Conf( std::string filename, bool verbose ): JSON_Loader() { // load the conf file. - this->load_json_file( filename, true ); + this->load_json_file( filename, verbose ); // find the path to the plan file if (this->get_serialized(this->plan_path, "plan_path", true) != 0 ) { throw CONF_PLANPATH_INVALID(); } diff --git a/src/loaders/Conf.h b/src/loaders/Conf.h index 6bacb77..dd7ef1d 100644 --- a/src/loaders/Conf.h +++ b/src/loaders/Conf.h @@ -13,7 +13,7 @@ private: Json::Value units_path; public: - Conf( std::string filename ); + Conf( std::string filename, bool verbose ); std::string get_plan_path(); std::string get_units_path(); }; diff --git a/src/loaders/Plan.cpp b/src/loaders/Plan.cpp index dcada4c..3786389 100644 --- a/src/loaders/Plan.cpp +++ b/src/loaders/Plan.cpp @@ -106,4 +106,20 @@ void Plan::load_definitions( Suite unit_definitions, bool verbose ) // then have that task attach a copy of tmp_U this->tasks[i].load_definition( tmp_U, verbose ); } -} \ No newline at end of file +} + +/// Plan::execute() - Iterates through all tasks in a plan and executes them. +/// +/// \param verbose +void Plan::execute( bool verbose ) +{ + // for each task in this plan + for ( int i = 0; i < this->tasks.size(); i++ ) + { + if ( verbose ) { + std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl; + } + this->tasks[i].execute( verbose ); + } +} + diff --git a/src/loaders/Plan.h b/src/loaders/Plan.h index aaad95d..97e55a4 100644 --- a/src/loaders/Plan.h +++ b/src/loaders/Plan.h @@ -28,7 +28,10 @@ class Plan: public JSON_Loader void load_definitions( Suite unit_definitions, bool verbose ); // 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 + void execute( bool verbose ); }; #endif //FTESTS_PLAN_H diff --git a/src/loaders/Task.cpp b/src/loaders/Task.cpp index 2a269e2..9e1ebff 100644 --- a/src/loaders/Task.cpp +++ b/src/loaders/Task.cpp @@ -5,6 +5,12 @@ class Task_InvalidDataStructure: public std::runtime_error { public: Task_InvalidDataStructure(): std::runtime_error("Task: Attempted to access a member of a Task that is not set.") {} }; +/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON. +class Task_NotReady: public std::runtime_error { public: + Task_NotReady(): std::runtime_error("Task: Attempted to access a unit of a Task that is not defined.") {} +}; + + /// 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. Task::Task() { @@ -73,4 +79,20 @@ bool Task::is_complete() { /// Task::has_definition - Indicator if the task has attached its definition from a Suite. bool Task::has_definition() { return this->defined; +} + +/// Task::execute - execute a task's unit definition. +void Task::execute( bool verbose ) +{ + // throw if unit not coupled + if (! this->has_definition() ) { throw Task_NotReady(); } + + if ( verbose ) + { + std::cout << "\t Using unit \"" << this->definition.get_name() << "\"." << std::endl; + std::cout << "\t Executing target \"" << this->definition.get_target() << "\"." << std::endl; + } + + + } \ No newline at end of file diff --git a/src/loaders/Task.h b/src/loaders/Task.h index e5679ca..e9aee91 100644 --- a/src/loaders/Task.h +++ b/src/loaders/Task.h @@ -39,6 +39,9 @@ class Task // fetch the name of a task std::string get_name(); + + // execute this task's definition + void execute( bool verbose ); }; #endif //FTESTS_TASK_H