Tests: generate_partitions_json.py

Implemented script to generate a json file that is to be used by
'hftest.py':
- To fetch the partitions' image;
- To fetch manifest file and append to spmc manifest, to expand the
'hypervisor' node with the respective partition's info.

Change-Id: I31965864af4e9d13dff781804fd9fa10bf67d654
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/build/image/generate_partitions_json.py b/build/image/generate_partitions_json.py
new file mode 100644
index 0000000..5a36141
--- /dev/null
+++ b/build/image/generate_partitions_json.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Copyright 2020 The Hafnium Authors.
+#
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/BSD-3-Clause.
+
+import argparse
+import sys
+import os
+import json
+
+"""
+This script aims at generating a json file that contains the artifacts of
+partitions that will execute alongside in the same test setup.
+A partition can be:
+ - Virtual Machine (VM) - to execute in EL1;
+ - Secure Partition (SP) - to execute in S-EL1.
+
+A setup can have multiple VMs and multiple SPs executing alongside.
+The json file shall list the VMs and SPs, such as:
+{
+    "SPs" : [ <SP information>, ... , <SPx Information>],
+    "VMs" : [ <VM information>, ... , <VMx Information>]
+}
+
+Where the information of each partition shall obey the following format:
+{
+     "img" : <path to partition package>.img,
+     "dts" : <path to manifest>.dts
+}
+
+In the arguments of this script provide the path to partition's artifacts
+separated by the character defined as 'ARG_SPLITTER'. Example:
+--sp <path to img>,<path to dts>
+--vm <path to img>,<path to dts>
+"""
+
+ARG_SPLITTER = ','
+ARG_FORMAT = f"<img>{ARG_SPLITTER}<dts>"
+
+def split_partition_arg(sp_arg : str):
+    ret = sp_arg.split(ARG_SPLITTER)
+    if len(ret) != 2:
+        raise Exception(f"Argument should follow format {ARG_FORMAT}")
+    return ret
+
+def partition_info(img, dts):
+    return {"img": img, "dts": dts}
+
+def list_of_partitions(partitions : list):
+    return [partition_info(*split_partition_arg(p)) for p in partitions]
+
+def Main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--sp", action="append")
+    parser.add_argument("--vm", action="append")
+    parser.add_argument("--out", action="store", required=True)
+    args = parser.parse_args()
+
+    #Arguments sanity check:
+    if args.vm is None and args.sp is None:
+        raise Exception("Specify at least one VM (--vm) or one SP (--sp)")
+
+    partitions = dict()
+    if args.sp is not None:
+        partitions["SPs"] = list_of_partitions(args.sp)
+    if args.vm is not None:
+        partitions["VMs"] = list_of_partitions(args.vm)
+
+    json.dump(partitions, open(args.out, "w+"))
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(Main())
diff --git a/build/image/image.gni b/build/image/image.gni
index 40da76d..50ca799 100644
--- a/build/image/image.gni
+++ b/build/image/image.gni
@@ -391,3 +391,68 @@
     ]
   }
 }
+
+# Generate a JSON file containing the path to the necessary artifacts to run
+# an FVP driver, and adequately populate its arguments.
+template("partitions_json") {
+  base_out_dir = "${target_out_dir}"
+  action(target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "testonly",
+                             "sps",
+                             "vms",
+                           ])
+
+    script = "//build/image/generate_partitions_json.py"
+
+    json_file = "${base_out_dir}/" + invoker.json_file
+
+    args = []
+    deps = []
+
+    foreach(sp, sps) {
+      deps += [
+        sp[2],
+        sp[3],
+      ]
+
+      package_dir = get_label_info(sp[2], "name")
+      img = rebase_path(
+              get_label_info(package_dir + "/" + sp[0], "target_out_dir"))
+
+      dts = rebase_path(sp[1])
+
+      args += [
+        "--sp",
+        "${img},${dts}",
+      ]
+    }
+
+    foreach(vm, vms) {
+      deps += [
+        vm[2],
+        vm[3],
+      ]
+
+      package_dir = get_label_info(vm[2], "name")
+      img = rebase_path(
+              get_label_info(package_dir + "/" + vm[0], "target_out_dir"))
+
+      dts = rebase_path(vm[1])
+      args += [
+        "--vm",
+        "${img},${dts}",
+      ]
+    }
+
+    args += [
+      "--out",
+      rebase_path(json_file),
+    ]
+
+    outputs = [
+      json_file,
+    ]
+  }
+}