Examplar’s Data Structure Confirmed/Implemented

I had forgotten how slowly C++ development moves when your specialization is not in C++ development (and mine totally is not — actually, what is mine?).

At this point I’m bundling a small json parsing implementation with Examplar to avoid creating a runtime dependency.

There really ought not be any other library inclusion needs besides some simple subprocess spawning logic for triggering a task‘s unit‘s target executable and healer executable, as well as grabbing the expected output from the execution of targets/healers specified in the test unit file which has a path defined in config.json.

If that’s a little compact, this may make more sense:

[code]
===========================================================================
Output
===========================================================================
/home/phanes/Development/internal/ftests/cmake-build-debug/ftests
—————————————————————————
Parsed config.json with 2 elements.
Parsed ./conf/units/all_test.units with 1 elements.
Parsed ./conf/test.plan with 1 elements.
Found task name in "./conf/test.plan": gcc is present

Associated Unit name: gcc is present
Associated Unit target: ./ubuntu/xenial/check_gcc_present.run
Associated Unit healer: ./ubuntu/xenial/install_gcc
Associated Unit heals: true

Found task name in "./conf/test.plan": gcc can compile

Associated Unit name: gcc can compile
Associated Unit target: ./ubuntu/xenial/check_gcc_compiles.run
Associated Unit healer: echo pass
Associated Unit heals: false

Process finished with exit code 0

===========================================================================
Input
===========================================================================
—————————————————————————
config.json
—————————————————————————
{
"units_path": "./conf/units/all_test.units",
"plan_path": "./conf/test.plan"
}

—————————————————————————
./conf/units/all_test.units
—————————————————————————
{
"units": [
{
"name": "gcc is present",
"target": "./ubuntu/xenial/check_gcc_present.run",
"output": "present",
"rectifier": "./ubuntu/xenial/install_gcc",
"active": true,
"required": true,
"rectify": true
},
{
"name": "gcc can compile",
"target": "./ubuntu/xenial/check_gcc_compiles.run",
"output": "can compile",
"rectifier": "echo pass",
"active": true,
"required": true,
"rectify": false
}
]
}

—————————————————————————
./conf/test.plan
—————————————————————————
{
"plan": [
{ "name": "gcc is present", "depends on": [ null ] },
{ "name": "gcc can compile", "depends on": [ "gcc is present" ] }
]
}
[/code]

Once Examplar is complete, SURRO will be able to be built modularly to accommodate profiles, which are just a set of tasks (a plan) and units (what the plan executes) provided to run in different environments and will be community contributions.

I am delighted by this as it means other types of projects which have nothing to do with SURRO or Foster will be quite well facilitated by the design.

One thing that will need to be done (in a future iteration, I do not need this feature myself yet), is to have units_path in config.json be a directory path full of json files defining their units that are then amalgamated to produce a cascading style of configuration for the user.

While I do not need that or want to use that myself, seriously, I do think that this will make breaking unit definitions into sets, like desktop_packages.unit and base_system.unit will be useful later for building Foster as that project evolves (so long as I stop creating needs for tools that don’t exist yet).

So from here is to polish up the encapsulation needs, create a subprocess handling set of classes to manage the flow in a rigid manner according to plan, and from there we’ll want to give it:

  • A default path set for config.json.
  • Cascading unit definitions (eventually).
  • A unix-style command-line interface (a simple one).

On the PR front, I’ve got exciting news that I can’t share yet.