get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/109311/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 109311,
    "url": "http://patches.dpdk.org/api/patches/109311/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-13-juraj.linkes@pantheon.tech/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220406151903.2916254-13-juraj.linkes@pantheon.tech>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220406151903.2916254-13-juraj.linkes@pantheon.tech",
    "date": "2022-04-06T15:18:52",
    "name": "[RFC,v1,12/23] dts: merge DTS framework/virt_scene.py to DPDK",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "ee18a87a6146bc9a1ff83365219ae27639d0d05f",
    "submitter": {
        "id": 1626,
        "url": "http://patches.dpdk.org/api/people/1626/?format=api",
        "name": "Juraj Linkeš",
        "email": "juraj.linkes@pantheon.tech"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-13-juraj.linkes@pantheon.tech/mbox/",
    "series": [
        {
            "id": 22381,
            "url": "http://patches.dpdk.org/api/series/22381/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22381",
            "date": "2022-04-06T15:18:40",
            "name": "merge DTS test resource files to DPDK",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/22381/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/109311/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/109311/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 5A943A0509;\n\tWed,  6 Apr 2022 17:20:42 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5413842948;\n\tWed,  6 Apr 2022 17:19:23 +0200 (CEST)",
            "from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20])\n by mails.dpdk.org (Postfix) with ESMTP id 1655B42931\n for <dev@dpdk.org>; Wed,  6 Apr 2022 17:19:21 +0200 (CEST)",
            "from localhost (localhost [127.0.0.1])\n by lb.pantheon.sk (Postfix) with ESMTP id 5DDEC184FEE;\n Wed,  6 Apr 2022 17:19:20 +0200 (CEST)",
            "from lb.pantheon.sk ([127.0.0.1])\n by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id B8fxyxRvqGxm; Wed,  6 Apr 2022 17:19:18 +0200 (CEST)",
            "from entguard.lab.pantheon.local (unknown [46.229.239.141])\n by lb.pantheon.sk (Postfix) with ESMTP id D9B41184FF6;\n Wed,  6 Apr 2022 17:19:10 +0200 (CEST)"
        ],
        "X-Virus-Scanned": "amavisd-new at siecit.sk",
        "From": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "To": "thomas@monjalon.net, david.marchand@redhat.com,\n Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com",
        "Cc": "dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "Subject": "[RFC PATCH v1 12/23] dts: merge DTS framework/virt_scene.py to DPDK",
        "Date": "Wed,  6 Apr 2022 15:18:52 +0000",
        "Message-Id": "<20220406151903.2916254-13-juraj.linkes@pantheon.tech>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>",
        "References": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "---\n dts/framework/virt_scene.py | 560 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 560 insertions(+)\n create mode 100644 dts/framework/virt_scene.py",
    "diff": "diff --git a/dts/framework/virt_scene.py b/dts/framework/virt_scene.py\nnew file mode 100644\nindex 0000000000..63760192c3\n--- /dev/null\n+++ b/dts/framework/virt_scene.py\n@@ -0,0 +1,560 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+#   * Redistributions of source code must retain the above copyright\n+#     notice, this list of conditions and the following disclaimer.\n+#   * Redistributions in binary form must reproduce the above copyright\n+#     notice, this list of conditions and the following disclaimer in\n+#     the documentation and/or other materials provided with the\n+#     distribution.\n+#   * Neither the name of Intel Corporation nor the names of its\n+#     contributors may be used to endorse or promote products derived\n+#     from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+import time\n+\n+import framework.utils as utils\n+\n+from .config import VIRTCONF, VirtConf\n+from .exception import *\n+from .pmd_output import PmdOutput\n+from .qemu_kvm import QEMUKvm\n+from .settings import CONFIG_ROOT_PATH, get_netdev\n+from .utils import create_mask\n+\n+# scenario module for handling scenario\n+# 1. load configurations\n+# config saved in $DTS_CFG_FOLDER/scenarios/name.cfg\n+# load configurations will saved in vm list\n+# 2. handle special config\n+#   pf_idx=0,vf_num=2,driver=default;\n+#   PF0 igb_uio, create 2VFs by default driver\n+# 3. create scenario\n+#   allocate hardware resource for this vm\n+#   cpu, memory, pf devices, vf devices\n+#   configuration vm\n+#   run pre_vm commands\n+#   create vm\n+#   run post_vm commands\n+\n+\n+class VirtScene(object):\n+    def __init__(self, dut, tester, scene_name):\n+        self.name = scene_name\n+        self.host_dut = dut\n+        self.tester_dut = tester\n+        self.vm_dut = None\n+        self.pre_cmds = []\n+        self.post_cmds = []\n+\n+        self.vm_dut_enable = False\n+        self.auto_portmap = True\n+        self.vm_type = \"kvm\"\n+        self.def_target = \"x86_64-native-linuxapp-gcc\"\n+        self.host_bound = False\n+\n+        # for vm dut init_log\n+        self.host_dut.test_classname = \"dts\"\n+\n+    def load_config(self):\n+        try:\n+            self.vm_confs = {}\n+            conf = VirtConf(CONFIG_ROOT_PATH + \"/scene/\" + self.name + \".cfg\")\n+            self.sections = conf.virt_conf.get_sections()\n+            for vm in self.sections:\n+                conf.load_virt_config(vm)\n+                vm_conf = conf.get_virt_config()\n+                self.vm_confs[vm] = vm_conf\n+        except:\n+            raise VirtConfigParseException\n+\n+    def prepare_vm(self):\n+        host_cfg = None\n+        for conf in list(self.vm_confs.keys()):\n+            if conf == \"scene\":\n+                for cfg in self.vm_confs[\"scene\"]:\n+                    if \"suite\" in list(cfg.keys()):\n+                        self.prepare_suite(cfg[\"suite\"])\n+                    if \"host\" in list(cfg.keys()):\n+                        self.host_bound = True\n+                        host_cfg = cfg[\"host\"][0]\n+                self.vm_confs.pop(\"scene\")\n+            else:\n+                vm_name = conf\n+                vm_conf = self.vm_confs[vm_name]\n+                self.prepare_cpu(vm_name, vm_conf)\n+                self.prepare_devices(vm_conf)\n+                self.prepare_vmdevice(vm_conf)\n+\n+        # dpdk should start after vf devices created\n+        if host_cfg:\n+            self.prepare_host(**host_cfg)\n+\n+    def cleanup_vm(self):\n+        # reload config for has been changed when handle config\n+        self.load_config()\n+        for conf in list(self.vm_confs.keys()):\n+            if conf != \"scene\":\n+                vm_name = conf\n+                vm_conf = self.vm_confs[vm_name]\n+                self.cleanup_devices(vm_conf)\n+\n+    def prepare_suite(self, conf):\n+        for param in conf:\n+            if \"dut\" in list(param.keys()):\n+                if param[\"dut\"] == \"vm_dut\":\n+                    self.vm_dut_enable = True\n+            if \"type\" in list(param.keys()):\n+                if param[\"type\"] == \"xen\":\n+                    self.vm_type = \"xen\"\n+                # not implement yet\n+                if param[\"type\"] == \"vmware\":\n+                    self.vm_type = \"vmware\"\n+                # not implement yet\n+                if param[\"type\"] == \"container\":\n+                    self.vm_type = \"container\"\n+            if \"portmap\" in list(param.keys()):\n+                if param[\"portmap\"] == \"cfg\":\n+                    self.auto_portmap = False\n+\n+    def prepare_host(self, **opts):\n+        if \"dpdk\" not in list(opts.keys()):\n+            print(utils.RED(\"Scenario host parameter request dpdk option!!!\"))\n+            raise VirtConfigParamException(\"host\")\n+\n+        if \"cores\" not in list(opts.keys()):\n+            print(utils.RED(\"Scenario host parameter request cores option!!!\"))\n+            raise VirtConfigParamException(\"host\")\n+\n+        if \"target\" in list(opts.keys()):\n+            target = opts[\"target\"]\n+        else:\n+            target = self.def_target\n+\n+        self.host_dut.set_target(target, bind_dev=True)\n+\n+        if opts[\"dpdk\"] == \"testpmd\":\n+            self.pmdout = PmdOutput(self.host_dut)\n+            cores = opts[\"cores\"].split()\n+            out = self.pmdout.start_testpmd(cores)\n+            if \"Error\" in out:\n+                raise VirtHostPrepareException()\n+\n+    def prepare_cpu(self, vm_name, conf):\n+        cpu_param = {}\n+        for params in conf:\n+            if \"cpu\" in list(params.keys()):\n+                cpu_conf = params[\"cpu\"][0]\n+                break\n+\n+        if \"skipcores\" in list(cpu_conf.keys()):\n+            cpus = cpu_conf[\"skipcores\"].split()\n+            # remove invalid configured core\n+            for cpu in cpus:\n+                if int(cpu) not in self.host_dut.virt_pool.cores:\n+                    cpus.remove(cpu)\n+            # create core mask for reserved cores\n+            core_mask = create_mask(cpus)\n+            # reserve those skipped cores\n+            self.host_dut.virt_pool.reserve_cpu(core_mask)\n+\n+        if \"numa\" in list(cpu_conf.keys()):\n+            if cpu_conf[\"numa\"] == \"auto\":\n+                numa = self.host_dut.ports_info[0][\"port\"].socket\n+            else:\n+                numa = int(cpu_conf[\"numa\"])\n+        else:\n+            numa = 0\n+\n+        if \"number\" in list(cpu_conf.keys()):\n+            num = int(cpu_conf[\"number\"])\n+        else:\n+            num = 2\n+\n+        if \"model\" in list(cpu_conf.keys()):\n+            model = cpu_conf[\"model\"]\n+        else:\n+            model = \"host\"\n+\n+        cpu_topo = \"\"\n+        if \"cpu_topo\" in list(cpu_conf.keys()):\n+            cpu_topo = cpu_conf[\"cpu_topo\"]\n+\n+        pin_cores = []\n+        if \"cpu_pin\" in list(cpu_conf.keys()):\n+            pin_cores = cpu_conf[\"cpu_pin\"].split()\n+\n+        if len(pin_cores):\n+            cores = self.host_dut.virt_pool.alloc_cpu(vm=vm_name, corelist=pin_cores)\n+        else:\n+            cores = self.host_dut.virt_pool.alloc_cpu(\n+                vm=vm_name, number=num, socket=numa\n+            )\n+        core_cfg = \"\"\n+        for core in cores:\n+            core_cfg += \"%s \" % core\n+        core_cfg = core_cfg[:-1]\n+\n+        cpu_param[\"number\"] = num\n+        cpu_param[\"model\"] = model\n+        cpu_param[\"cpupin\"] = core_cfg\n+        cpu_param[\"cputopo\"] = cpu_topo\n+\n+        # replace with allocated cpus\n+        params[\"cpu\"] = [cpu_param]\n+\n+    def prepare_devices(self, conf):\n+        for params in conf:\n+            if \"dev_gen\" in list(params.keys()):\n+                index = conf.index(params)\n+                for param in params[\"dev_gen\"]:\n+                    self.handle_dev_gen(**param)\n+                # remove handled 'dev_gen' configuration\n+                conf.remove(conf[index])\n+\n+    def cleanup_devices(self, conf):\n+        for params in conf:\n+            if \"dev_gen\" in list(params.keys()):\n+                for param in params[\"dev_gen\"]:\n+                    self.handle_dev_destroy(**param)\n+\n+    def prepare_vmdevice(self, conf):\n+        for params in conf:\n+            if \"device\" in list(params.keys()):\n+                for param in params[\"device\"]:\n+                    if \"vf_idx\" in list(param.keys()):\n+                        new_param = self.prepare_vf_conf(param)\n+                        index = params[\"device\"].index(param)\n+                        params[\"device\"][index] = new_param\n+                    elif \"pf_idx\" in list(param.keys()):\n+                        new_param = self.prepare_pf_conf(param)\n+                        index = params[\"device\"].index(param)\n+                        params[\"device\"][index] = new_param\n+\n+                for param in params[\"device\"]:\n+                    netdev = get_netdev(self.host_dut, param[\"opt_host\"])\n+                    if netdev is not None:\n+                        netdev.bind_driver(\"pci-stub\")\n+\n+    def prepare_pf_conf(self, param):\n+        pf_param = {}\n+        # strip pf pci id\n+        pf = int(param[\"pf_idx\"])\n+        if pf >= len(self.host_dut.ports_info):\n+            raise VirtDeviceCreateException\n+        pf_pci = self.host_dut.ports_info[pf][\"pci\"]\n+        pf_param[\"driver\"] = \"pci-assign\"\n+        pf_param[\"opt_host\"] = pf_pci\n+        if param[\"guestpci\"] != \"auto\":\n+            pf_param[\"opt_addr\"] = param[\"guestpci\"]\n+\n+        return pf_param\n+\n+    def prepare_vf_conf(self, param):\n+        vf_param = {}\n+        # strip vf pci id\n+        if \"pf_dev\" in list(param.keys()):\n+            pf = int(param[\"pf_dev\"])\n+            pf_net = self.host_dut.ports_info[pf][\"port\"]\n+            vfs = self.host_dut.ports_info[pf][\"vfs_port\"]\n+            vf_idx = int(param[\"vf_idx\"])\n+            if vf_idx >= len(vfs):\n+                raise VirtDeviceCreateException\n+            vf_pci = vfs[vf_idx].pci\n+            vf_param[\"driver\"] = \"pci-assign\"\n+            vf_param[\"opt_host\"] = vf_pci\n+            if param[\"guestpci\"] != \"auto\":\n+                vf_param[\"opt_addr\"] = param[\"guestpci\"]\n+            if \"mac\" in list(param.keys()):\n+                pf_net.set_vf_mac_addr(vf_idx, param[\"mac\"])\n+        else:\n+            print(utils.RED(\"Invalid vf device config, request pf_dev\"))\n+\n+        return vf_param\n+\n+    def reset_pf_cmds(self, port):\n+        command = {}\n+        command[\"type\"] = \"host\"\n+        if not self.host_bound:\n+            intf = self.host_dut.ports_info[port][\"intf\"]\n+            command[\"command\"] = \"ifconfig %s up\" % intf\n+            self.reg_postvm_cmds(command)\n+\n+    def handle_dev_gen(self, **opts):\n+        if \"pf_idx\" in list(opts.keys()):\n+            port = int(opts[\"pf_idx\"])\n+            if \"vf_num\" in list(opts.keys()):\n+                vf_num = int(opts[\"vf_num\"])\n+            else:\n+                print(utils.RED(\"No vf_num for port %d, assum one VF\" % port))\n+                vf_num = 1\n+            if \"driver\" in list(opts.keys()):\n+                driver = opts[\"driver\"]\n+\n+            try:\n+                print(utils.GREEN(\"create vf %d %d %s\" % (port, vf_num, driver)))\n+                self.host_dut.generate_sriov_vfs_by_port(port, vf_num, driver)\n+                self.reset_pf_cmds(port)\n+            except:\n+                print(utils.RED(\"Failed to create vf as requested!!!\"))\n+                raise VirtDeviceCreateException\n+\n+    def handle_dev_destroy(self, **opts):\n+        if \"pf_idx\" in list(opts.keys()):\n+            port = int(opts[\"pf_idx\"])\n+\n+            try:\n+                print(utils.GREEN(\"destroy vfs on port %d\" % port))\n+                self.host_dut.destroy_sriov_vfs_by_port(port)\n+            except:\n+                print(utils.RED(\"Failed to destroy vf as requested!!!\"))\n+\n+    def reg_prevm_cmds(self, command):\n+        \"\"\"\n+        command: {'type':'host/tester/vm',\n+                    define which crb command progress\n+                  'command':'XXX',\n+                    command send to crb\n+                  'expect':'XXX',\n+                    expected output for command\n+                  'timeout': 60,\n+                  'verify': True or False\n+                    check whether command successfully\n+                 }\n+        \"\"\"\n+        self.pre_cmds.append(command)\n+\n+    def run_pre_cmds(self):\n+        for cmd in self.pre_cmds:\n+            if cmd[\"type\"] == \"vm\":\n+                print(utils.RED(\"Can't run vm command when vm not ready\"))\n+            elif cmd[\"type\"] == \"host\":\n+                crb = self.host_dut\n+            elif cmd[\"type\"] == \"tester\":\n+                crb = self.tester_dut\n+            else:\n+                crb = self.host_dut\n+\n+            if \"expect\" not in list(cmd.keys()):\n+                expect = \"# \"\n+            else:\n+                expect = cmd[\"expect\"]\n+\n+            if \"verify\" not in list(cmd.keys()):\n+                verify = False\n+            else:\n+                verify = cmd[\"verify\"]\n+\n+            if \"timeout\" not in list(cmd.keys()):\n+                timeout = 5\n+            else:\n+                timeout = cmd[\"timeout\"]\n+\n+            ret = crb.send_expect(\n+                cmd[\"command\"], expect, timeout=timeout, verify=verify\n+            )\n+\n+            if type(ret) is int and ret != 0:\n+                print(utils.RED(\"Failed to run command %s\" % cmd[\"command\"]))\n+                raise VirtVmOperationException\n+\n+    def reg_postvm_cmds(self, command):\n+        \"\"\"\n+        command: {'type':'host/tester/vm',\n+                    define which crb command progress\n+                  'command':'XXX',\n+                    command send to crb\n+                  'expect':'XXX',\n+                    expected output for command\n+                  'verify':'yes or no'\n+                    check whether command successfully\n+        \"\"\"\n+        self.post_cmds.append(command)\n+        pass\n+\n+    def run_post_cmds(self):\n+        for cmd in self.post_cmds:\n+            if cmd[\"type\"] == \"vm\":\n+                crb = self.vm_dut\n+            elif cmd[\"type\"] == \"host\":\n+                crb = self.host_dut\n+            elif cmd[\"type\"] == \"tester\":\n+                crb = self.tester_dut\n+            else:\n+                crb = self.host_dut\n+\n+            if \"expect\" not in list(cmd.keys()):\n+                expect = \"# \"\n+            else:\n+                expect = cmd[\"expect\"]\n+\n+            if \"verify\" not in list(cmd.keys()):\n+                verify = False\n+            else:\n+                verify = cmd[\"verify\"]\n+\n+            if \"timeout\" not in list(cmd.keys()):\n+                timeout = 5\n+            else:\n+                timeout = cmd[\"timeout\"]\n+\n+            ret = crb.send_expect(\n+                cmd[\"command\"], expect, timeout=timeout, verify=verify\n+            )\n+\n+            if type(ret) is int and ret != 0:\n+                print(utils.RED(\"Failed to run command %s\" % cmd[\"command\"]))\n+                raise VirtVmOperationException\n+\n+    def merge_params(self, vm, params):\n+        for param in params:\n+            index = vm.find_option_index(list(param.keys())[0])\n+            if index is not None:\n+                vm.params[index] = param\n+            else:\n+                vm.params.append(param)\n+        index = vm.find_option_index(\"name\")\n+        # update vm name\n+        vm.params[index][\"name\"][0][\"name\"] = vm.vm_name\n+\n+    def get_cputopo(self, params):\n+        for param in params:\n+            if \"cpu\" in list(param.keys()):\n+                cpu_topo = param[\"cpu\"][0][\"cputopo\"]\n+                return cpu_topo\n+\n+    def start_vms(self):\n+        self.vms = []\n+        if self.vm_type == \"kvm\":\n+            for vm_name in list(self.vm_confs.keys()):\n+                # tricky here, QEMUKvm based on suite and vm name\n+                # suite is virt_global, vm_name just the type\n+                vm = QEMUKvm(self.host_dut, self.vm_type.upper(), \"virt_global\")\n+                vm.load_config()\n+                vm.vm_name = vm_name\n+                vm.set_vm_default()\n+                # merge default config and scene config\n+                scene_params = self.vm_confs[vm_name]\n+                # reload merged configurations\n+                self.merge_params(vm, scene_params)\n+                # get cpu topo\n+                topo = self.get_cputopo(scene_params)\n+                try:\n+                    vm_dut = vm.start(\n+                        load_config=False, set_target=False, cpu_topo=topo\n+                    )\n+                    if vm_dut is None:\n+                        raise Exception(\"Set up VM ENV failed!\")\n+\n+                    vm_info = {}\n+                    vm_info[vm_name] = vm\n+                    vm_info[vm_name + \"_session\"] = vm_dut\n+                    self.vms.append(vm_info)\n+\n+                except Exception as e:\n+                    print(utils.RED(\"Failure for %s\" % str(e)))\n+\n+    def get_vm_duts(self):\n+        duts = []\n+        for vm_info in self.vms:\n+            for vm_obj in list(vm_info.keys()):\n+                if \"session\" in vm_obj:\n+                    duts.append(vm_info[vm_obj])\n+\n+        return duts\n+\n+    def create_scene(self):\n+        self.prepare_vm()\n+        self.run_pre_cmds()\n+        self.start_vms()\n+        self.run_post_cmds()\n+        pass\n+\n+    def set_target(self, target):\n+        for vm_info in self.vms:\n+            for vm_obj in list(vm_info.keys()):\n+                if \"session\" in vm_obj:\n+                    vm_info[vm_obj].set_target(target)\n+\n+    def destroy_scene(self):\n+        for vm_info in self.vms:\n+            for vm_obj in list(vm_info.keys()):\n+                if \"session\" in vm_obj:\n+                    vm_info[vm_obj].kill_all()\n+                    vm_info[vm_obj].close()\n+                    vm_info[vm_obj].logger.logger_exit()\n+            for vm_obj in list(vm_info.keys()):\n+                if \"session\" not in vm_obj:\n+                    vm_info[vm_obj].stop()\n+                    vm_info[vm_obj] = None\n+        self.cleanup_vm()\n+\n+\n+if __name__ == \"__main__\":\n+\n+    class QEMUKvmTmp:\n+        def __init__(self, dut, vm_name, suite_name):\n+            print(vm_name)\n+            print(suite_name)\n+\n+        def start(self):\n+            print(self.__dict__)\n+            return True\n+\n+    QEMUKvm = QEMUKvmTmp\n+\n+    class simple_dev(object):\n+        def __init__(self, pci):\n+            self.pci = pci\n+            self.socket = 1\n+\n+    emu_dev1 = simple_dev(\"00:00.1\")\n+    emu_dev2 = simple_dev(\"00:00.2\")\n+    emu_dev3 = simple_dev(\"00:00.3\")\n+    emu_dev4 = simple_dev(\"00:00.4\")\n+\n+    class simple_dut(object):\n+        def __init__(self):\n+            self.ports_info = [\n+                {\"vfs_port\": [emu_dev1, emu_dev2]},\n+                {\"vfs_port\": [emu_dev3, emu_dev4]},\n+            ]\n+            self.virt_pool = simple_resource()\n+\n+        def send_expect(\n+            self, cmds, expected, timeout=5, alt_session=False, verify=False\n+        ):\n+            print(cmds + \"---\" + expected)\n+\n+    class simple_resource(object):\n+        def __init__(self):\n+            pass\n+\n+        def reserve_cpu(self, coremask):\n+            print(\"reserve \" + coremask)\n+\n+        def alloc_cpu(self, vm=\"\", number=-1, socket=-1, corelist=None):\n+            print(\"alloc %s num %d on socket %d\" % (vm, number, socket))\n+\n+    dut = simple_dut()\n+    scene = VirtScene(dut, None, \"vf_passthrough\")\n+    scene.load_config()\n+    scene.create_scene()\n+    scene.destroy_scene()\n",
    "prefixes": [
        "RFC",
        "v1",
        "12/23"
    ]
}