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/lava_rpc_connector.py b/tfm_ci_pylib/lava_rpc_connector.py
new file mode 100644
index 0000000..269cbbf
--- /dev/null
+++ b/tfm_ci_pylib/lava_rpc_connector.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+
+""" lava_rpc_connector.py:
+
+ class that extends xmlrpc in order to add LAVA specific functionality.
+ Used in managing communication with the back-end. """
+
+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 xmlrpc.client
+import time
+
+
+class LAVA_RPC_connector(xmlrpc.client.ServerProxy, object):
+
+ def __init__(self,
+ username,
+ token,
+ hostname,
+ rest_prefix="RPC2",
+ https=False):
+
+ # If user provides hostname with http/s prefix
+ if "://" in hostname:
+ htp_pre, hostname = hostname.split("://")
+ server_addr = "%s://%s:%s@%s/%s" % (htp_pre,
+ username,
+ token,
+ hostname,
+ rest_prefix)
+ self.server_url = "%s://%s" % (htp_pre, hostname)
+ else:
+ server_addr = "%s://%s:%s@%s/%s" % ("https" if https else "http",
+ username,
+ token,
+ hostname,
+ rest_prefix)
+ self.server_url = "%s://%s" % ("https" if https else "http",
+ hostname)
+
+ self.server_job_prefix = "%s/scheduler/job/%%s" % self.server_url
+ super(LAVA_RPC_connector, self).__init__(server_addr)
+
+ def _rpc_cmd_raw(self, cmd, params=None):
+ """ Run a remote comand and return the result. There is no constrain
+ check on the syntax of the command. """
+
+ cmd = "self.%s(%s)" % (cmd, params if params else "")
+ return eval(cmd)
+
+ def ls_cmd(self):
+ """ Return a list of supported commands """
+
+ print("\n".join(self.system.listMethods()))
+
+ def get_job_results(self, job_id, yaml_out_file=None):
+ results = self.results.get_testjob_results_yaml(job_id)
+ if yaml_out_file:
+ with open(yaml_out_file, "w") as F:
+ F.write(results)
+ return results
+
+ def get_job_state(self, job_id):
+ return self.scheduler.job_state(job_id)["job_state"]
+
+ def get_job_status(self, job_id):
+ return self.scheduler.job_status(job_id)["job_status"]
+
+ def cancel_job(self, job_id):
+ """ Cancell job with id=job_id. Returns True if successfull """
+
+ return self.scheduler.jobs.cancel(job_id)
+
+ def validate_job_yaml(self, job_definition, print_err=False):
+ """ Validate a job definition syntax. Returns true is server considers
+ the syntax valid """
+
+ try:
+ with open(job_definition) as F:
+ input_yaml = F.read()
+ self.scheduler.validate_yaml(input_yaml)
+ return True
+ except Exception as E:
+ if print_err:
+ print(E)
+ return False
+
+ def submit_job(self, job_definition):
+ """ Will submit a yaml definition pointed by job_definition after
+ validating it againist the remote backend. Returns resulting job id,
+ and server url for job"""
+
+ try:
+ if not self.validate_job_yaml(job_definition):
+ print("Served rejected job's syntax")
+ raise Exception("Invalid job")
+ with open(job_definition, "r") as F:
+ job_data = F.read()
+ except Exception as e:
+ print("Cannot submit invalid job. Check %s's content" %
+ job_definition)
+ print(e)
+ return None, None
+
+ job_id = self.scheduler.submit_job(job_data)
+ job_url = self.server_job_prefix % job_id
+ return(job_id, job_url)
+
+ def resubmit_job(self, job_id):
+ """ Re-submit job with provided id. Returns resulting job id,
+ and server url for job"""
+
+ job_id = self.scheduler.resubmit_job(job_id)
+ job_url = self.server_job_prefix % job_id
+ return(job_id, job_url)
+
+ def block_wait_for_job(self, job_id, timeout, poll_freq=1):
+ """ Will block code execution and wait for the job to submit.
+ Returns job status on completion """
+
+ start_t = int(time.time())
+ while(True):
+ cur_t = int(time.time())
+ if cur_t - start_t >= timeout:
+ print("Breaking because of timeout")
+ break
+ # Check if the job is not running
+ cur_status = self.get_job_status(job_id)
+ # If in queue or running wait
+ if cur_status == "Running" or cur_status == "Submitted":
+ time.sleep(poll_freq)
+ else:
+ break
+ return self.get_job_status(job_id)
+
+ def test_credentials(self):
+ """ Attempt to querry the back-end and verify that the user provided
+ authentication is valid """
+
+ try:
+ self._rpc_cmd_raw("system.listMethods")
+ return True
+ except Exception as e:
+ print(e)
+ print("Credential validation failed")
+ return False
+
+
+if __name__ == "__main__":
+ pass