Open CI Scripts: Initial Commit
* build_helper: Python script which builds sets
of configurations from a json file input
* checkpatch: Bash scripts helping with running checkpatch
* cppcheck: Bash script helping with running cppcheck
* lava_helper: Python script which generates a lava job
definition and parses the output of a lava dispatcher
* tfm_ci_pylib: Generic Python module for Open CI
* configs: Directory storing reference configurations
Change-Id: Ibda0cbfeb5b004b35fef3c2af4cb5c012f2672b4
Signed-off-by: Galanakis, Minos <minos.galanakis@linaro.org>
diff --git a/tfm_ci_pylib/structured_task.py b/tfm_ci_pylib/structured_task.py
new file mode 100644
index 0000000..b97cae9
--- /dev/null
+++ b/tfm_ci_pylib/structured_task.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+
+""" structured_task.py:
+
+ A generic abstraction class for executing a task with prerequesites and
+ post execution action """
+
+from __future__ import print_function
+
+__copyright__ = """
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+ """
+__author__ = "Minos Galanakis"
+__email__ = "minos.galanakis@linaro.org"
+__project__ = "Trusted Firmware-M Open CI"
+__status__ = "stable"
+__version__ = "1.0"
+
+import abc
+import time
+import multiprocessing
+
+
+class structuredTask(multiprocessing.Process):
+ """ A class that defined well structured chained execution of commands """
+
+ __metaclass__ = abc.ABCMeta
+
+ def __init__(self, name):
+
+ self._stopevent = multiprocessing.Event()
+ self._exec_sleep_period = 1.0
+ self._join_timeout = 1.0
+ self._exec_timeout = 0.0
+ self._task_name = name
+
+ # multiprocessing safe shared memory variables
+ self._mprc_manager = multiprocessing.Manager()
+
+ # Dictionary used to store objects between stages
+ self._mprc_stash = self._mprc_manager.dict()
+
+ # Integer variable that stores status of flow
+ self._mprc_status = multiprocessing.Value('i', False)
+ super(structuredTask, self).__init__(name=name)
+
+ # Perform initialization
+ # If user code raises exception, class memory will not be allocated
+ # Variables can be safely shared in the pre stages, use stash for
+ # next stages
+ self.pre_exec(self.pre_eval())
+
+ # Class API/Interface
+
+ @abc.abstractmethod
+ def pre_eval(self):
+ """ Tests that need to be run in set-up state """
+
+ @abc.abstractmethod
+ def pre_exec(self, eval_ret):
+ """ Tasks that set-up execution enviroment """
+
+ @abc.abstractmethod
+ def task_exec(self):
+ """ Main tasks """
+
+ @abc.abstractmethod
+ def post_eval(self, eval_ret):
+ """ Tests that need to be run after main task """
+
+ @abc.abstractmethod
+ def post_exec(self):
+ """ Tasks that are run after main task """
+
+ def stash(self, key, data):
+ """ Store object in a shared memory interface """
+
+ self._mprc_stash[key] = data
+
+ def unstash(self, key):
+ """ Retrieve object from a shared memory interface """
+
+ try:
+ return self._mprc_stash[key]
+ except KeyError:
+ return None
+
+ def get_name(self):
+ """" Return name label of class """
+ return self._task_name
+
+ def get_status(self):
+ """ Return the status of the execution flow """
+ with self._mprc_status.get_lock():
+ return self._mprc_status.value
+
+ def set_status(self, status):
+ """ Return the status of the execution flow """
+ with self._mprc_status.get_lock():
+ self._mprc_status.value = status
+
+ def run(self):
+ try:
+
+ # Run Core code
+ while not self._stopevent.is_set():
+ self.task_exec()
+ time.sleep(self._exec_sleep_period)
+ break
+ # print("Stop Event Detected")
+ # TODO Upgrade reporting to a similar format
+ print("%s ==> Stop Event Detected" % self.get_name())
+
+ # Post stage
+ # If something faifs in post the user should set the correct status
+ self.set_status(0)
+ print("%s ==> Stop Event Set OK Status" % self.get_name())
+ except Exception as exc:
+ print(("ERROR: Stopping %s "
+ "with Exception: \"%s\"") % (self.get_name(), exc))
+ self.set_status(1)
+ # Always call post, and determine success failed by get_status
+ self.post_exec(self.post_eval())
+
+ def _t_stop(self):
+ """ Internal class stop to be called through thread """
+ print("Thead is alive0 %s" % self.is_alive())
+ if(self.is_alive()):
+ print("%s =========> STOP" % self.get_name())
+ self._stopevent.set()
+ print("Thead is alive %s" % self.is_alive())
+ print("Stop Event Triggered")
+
+ def stop(self):
+ """ External stop to be called by user code """
+
+ self._t_stop()
+ super(structuredTask, self).join(self._join_timeout)