get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 109310,
    "url": "http://patches.dpdk.org/api/patches/109310/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-12-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-12-juraj.linkes@pantheon.tech>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220406151903.2916254-12-juraj.linkes@pantheon.tech",
    "date": "2022-04-06T15:18:51",
    "name": "[RFC,v1,11/23] dts: merge DTS framework/virt_resource.py to DPDK",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "6b2637c24e53dc6fb58e50c0ab0cc73d8860f034",
    "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-12-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/109310/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/109310/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 4250DA0509;\n\tWed,  6 Apr 2022 17:20:34 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 292DE4293F;\n\tWed,  6 Apr 2022 17:19:22 +0200 (CEST)",
            "from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20])\n by mails.dpdk.org (Postfix) with ESMTP id 3BBEF42925\n for <dev@dpdk.org>; Wed,  6 Apr 2022 17:19:20 +0200 (CEST)",
            "from localhost (localhost [127.0.0.1])\n by lb.pantheon.sk (Postfix) with ESMTP id 88FB9184FF1;\n Wed,  6 Apr 2022 17:19:19 +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 y36L9Dw2XfTL; 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 6288B184FFD;\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 11/23] dts: merge DTS framework/virt_resource.py to\n DPDK",
        "Date": "Wed,  6 Apr 2022 15:18:51 +0000",
        "Message-Id": "<20220406151903.2916254-12-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_resource.py | 584 +++++++++++++++++++++++++++++++++\n 1 file changed, 584 insertions(+)\n create mode 100644 dts/framework/virt_resource.py",
    "diff": "diff --git a/dts/framework/virt_resource.py b/dts/framework/virt_resource.py\nnew file mode 100644\nindex 0000000000..36b6fe9c71\n--- /dev/null\n+++ b/dts/framework/virt_resource.py\n@@ -0,0 +1,584 @@\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+from random import randint\n+\n+from .utils import RED, get_obj_funcs, parallel_lock\n+\n+INIT_FREE_PORT = 6000\n+INIT_SERIAL_PORT = 7000\n+INIT_MIGRATE_PORT = 8000\n+INIT_DISPLAY_PORT = 0\n+\n+QuickScan = True\n+\n+\n+class VirtResource(object):\n+\n+    \"\"\"\n+    Class handle dut resource, like cpu, memory, net devices\n+    \"\"\"\n+\n+    def __init__(self, dut):\n+        self.dut = dut\n+\n+        self.cores = [int(core[\"thread\"]) for core in dut.cores]\n+        # initialized unused cores\n+        self.unused_cores = self.cores[:]\n+        # initialized used cores\n+        self.used_cores = [-1] * len(self.unused_cores)\n+\n+        self.ports_info = dut.ports_info\n+        # initialized unused ports\n+        self.ports = [port[\"pci\"] for port in dut.ports_info]\n+        self.unused_ports = self.ports[:]\n+        # initialized used ports\n+        self.used_ports = [\"unused\"] * len(self.unused_ports)\n+\n+        # initialized vf ports\n+        self.vfs_info = []\n+        self.vfs = []\n+        self.unused_vfs = []\n+        self.used_vfs = []\n+\n+        # save allocated cores and related vm\n+        self.allocated_info = {}\n+\n+    def __port_isused(self, pci):\n+        return pci in self.used_ports\n+\n+    def __port_used(self, pci):\n+        index = self.ports.index(pci)\n+        self.used_ports[index] = pci\n+        self.unused_ports[index] = \"used\"\n+\n+    def __port_unused(self, pci):\n+        index = self.ports.index(pci)\n+        self.unused_ports[index] = pci\n+        self.used_ports[index] = \"unused\"\n+\n+    def __port_on_socket(self, pci, socket):\n+        for port in self.ports_info:\n+            if port[\"pci\"] == pci:\n+                if socket == -1:\n+                    return True\n+\n+                if port[\"numa\"] == socket:\n+                    return True\n+                else:\n+                    return False\n+\n+        return False\n+\n+    def __vf_used(self, pci):\n+        index = self.vfs.index(pci)\n+        self.used_vfs[index] = pci\n+        self.unused_vfs[index] = \"used\"\n+\n+    def __vf_unused(self, pci):\n+        index = self.vfs.index(pci)\n+        self.used_vfs[index] = \"unused\"\n+        self.unused_vfs[index] = pci\n+\n+    def __core_used(self, core):\n+        core = int(core)\n+        index = self.cores.index(core)\n+        self.used_cores[index] = core\n+        self.unused_cores[index] = -1\n+\n+    def __core_unused(self, core):\n+        core = int(core)\n+        index = self.cores.index(core)\n+        self.unused_cores[index] = core\n+        self.used_cores[index] = -1\n+\n+    def __core_on_socket(self, core, socket):\n+        for dut_core in self.dut.cores:\n+            if int(dut_core[\"thread\"]) == core:\n+                if socket == -1:\n+                    return True\n+\n+                if int(dut_core[\"socket\"]) == socket:\n+                    return True\n+                else:\n+                    return False\n+\n+        return False\n+\n+    def __core_isused(self, core):\n+        index = self.cores.index(core)\n+        if self.used_cores[index] != -1:\n+            return True\n+        else:\n+            return False\n+\n+    def reserve_cpu(self, coremask=\"\"):\n+        \"\"\"\n+        Reserve dpdk used cpus by mask\n+        \"\"\"\n+        val = int(coremask, base=16)\n+        cpus = []\n+        index = 0\n+        while val != 0:\n+            if val & 0x1:\n+                cpus.append(index)\n+\n+            val = val >> 1\n+            index += 1\n+\n+        for cpu in cpus:\n+            self.__core_used(cpu)\n+\n+    @parallel_lock()\n+    def alloc_cpu(self, vm=\"\", number=-1, socket=-1, corelist=None):\n+        \"\"\"\n+        There're two options for request cpu resource for vm.\n+        If number is not -1, just allocate cpu from not used cores.\n+        If list is not None, will allocate cpu after checked.\n+        \"\"\"\n+        cores = []\n+\n+        if vm == \"\":\n+            print(\"Alloc cpu request virtual machine name!!!\")\n+            return cores\n+\n+        # if vm has been allocated cores, just return them\n+        if self.__vm_has_resource(vm, \"cores\"):\n+            return self.allocated_info[vm][\"cores\"]\n+\n+        if number != -1:\n+            for core in self.unused_cores:\n+                if core != -1 and number != 0:\n+                    if self.__core_on_socket(core, socket) is True:\n+                        self.__core_used(core)\n+                        cores.append(str(core))\n+                        number = number - 1\n+            if number != 0:\n+                print(\"Can't allocated requested cpu!!!\")\n+\n+        if corelist is not None:\n+            for core in corelist:\n+                if self.__core_isused(int(core)) is True:\n+                    print(\"Core %s has been used!!!\" % core)\n+                else:\n+                    if self.__core_on_socket(int(core), socket) is True:\n+                        self.__core_used(int(core))\n+                        cores.append(core)\n+\n+        if vm not in self.allocated_info:\n+            self.allocated_info[vm] = {}\n+\n+        self.allocated_info[vm][\"cores\"] = cores\n+        return cores\n+\n+    def __vm_has_resource(self, vm, resource=\"\"):\n+        if vm == \"\":\n+            self.dut.logger.info(\"VM name can't be NULL!!!\")\n+            raise Exception(\"VM name can't be NULL!!!\")\n+        if vm not in self.allocated_info:\n+            self.dut.logger.info(\"There is no resource allocated to VM [%s].\" % vm)\n+            return False\n+        if resource == \"\":\n+            return True\n+        if resource not in self.allocated_info[vm]:\n+            self.dut.logger.info(\n+                \"There is no resource [%s] allocated to VM [%s] \" % (resource, vm)\n+            )\n+            return False\n+        return True\n+\n+    @parallel_lock()\n+    def free_cpu(self, vm):\n+        if self.__vm_has_resource(vm, \"cores\"):\n+            for core in self.allocated_info[vm][\"cores\"]:\n+                self.__core_unused(core)\n+            self.allocated_info[vm].pop(\"cores\")\n+\n+    @parallel_lock()\n+    def alloc_pf(self, vm=\"\", number=-1, socket=-1, pflist=[]):\n+        \"\"\"\n+        There're two options for request pf devices for vm.\n+        If number is not -1, just allocate pf device from not used pfs.\n+        If list is not None, will allocate pf devices after checked.\n+        \"\"\"\n+        ports = []\n+\n+        if number != -1:\n+            for pci in self.unused_ports:\n+                if pci != \"unused\" and number != 0:\n+                    if self.__port_on_socket(pci, socket) is True:\n+                        self.__port_used(pci)\n+                        ports.append(pci)\n+                        number = number - 1\n+            if number != 0:\n+                print(\"Can't allocated requested PF devices!!!\")\n+\n+        if pflist is not None:\n+            for pci in pflist:\n+                if self.__port_isused(pci) is True:\n+                    print(\"Port %s has been used!!!\" % pci)\n+                else:\n+                    if self.__port_on_socket(pci, socket) is True:\n+                        self.__port_used(pci)\n+                        ports.append(pci)\n+\n+        if vm not in self.allocated_info:\n+            self.allocated_info[vm] = {}\n+\n+        self.allocated_info[vm][\"ports\"] = ports\n+        return ports\n+\n+    @parallel_lock()\n+    def free_pf(self, vm):\n+        if self.__vm_has_resource(vm, \"ports\"):\n+            for pci in self.allocated_info[vm][\"ports\"]:\n+                self.__port_unused(pci)\n+            self.allocated_info[vm].pop(\"ports\")\n+\n+    @parallel_lock()\n+    def alloc_vf_from_pf(self, vm=\"\", pf_pci=\"\", number=-1, vflist=[]):\n+        \"\"\"\n+        There're two options for request vf devices of pf device.\n+        If number is not -1, just allocate vf device from not used vfs.\n+        If list is not None, will allocate vf devices after checked.\n+        \"\"\"\n+        vfs = []\n+        if vm == \"\":\n+            print(\"Alloc VF request vitual machine name!!!\")\n+            return vfs\n+\n+        if pf_pci == \"\":\n+            print(\"Alloc VF request PF pci address!!!\")\n+            return vfs\n+\n+        for vf_info in self.vfs_info:\n+            if vf_info[\"pf_pci\"] == pf_pci:\n+                if vf_info[\"pci\"] in vflist:\n+                    vfs.append(vf_info[\"pci\"])\n+                    continue\n+\n+                if number > 0:\n+                    vfs.append(vf_info[\"pci\"])\n+                    number = number - 1\n+\n+        for vf in vfs:\n+            self.__vf_used(vf)\n+\n+        if vm not in self.allocated_info:\n+            self.allocated_info[vm] = {}\n+\n+        self.allocated_info[vm][\"vfs\"] = vfs\n+        return vfs\n+\n+    @parallel_lock()\n+    def free_vf(self, vm):\n+        if self.__vm_has_resource(vm, \"vfs\"):\n+            for pci in self.allocated_info[vm][\"vfs\"]:\n+                self.__vf_unused(pci)\n+            self.allocated_info[vm].pop(\"vfs\")\n+\n+    @parallel_lock()\n+    def add_vf_on_pf(self, pf_pci=\"\", vflist=[]):\n+        \"\"\"\n+        Add vf devices generated by specified pf devices.\n+        \"\"\"\n+        # add vfs into vf info list\n+        vfs = []\n+        for vf in vflist:\n+            if vf not in self.vfs:\n+                self.vfs_info.append({\"pci\": vf, \"pf_pci\": pf_pci})\n+                vfs.append(vf)\n+        used_vfs = [\"unused\"] * len(vflist)\n+        self.unused_vfs += vfs\n+        self.used_vfs += used_vfs\n+        self.vfs += vfs\n+\n+    @parallel_lock()\n+    def del_vf_on_pf(self, pf_pci=\"\", vflist=[]):\n+        \"\"\"\n+        Remove vf devices generated by specified pf devices.\n+        \"\"\"\n+        vfs = []\n+        for vf in vflist:\n+            for vfs_info in self.vfs_info:\n+                if vfs_info[\"pci\"] == vf:\n+                    vfs.append(vf)\n+\n+        for vf in vfs:\n+            try:\n+                index = self.vfs.index(vf)\n+            except:\n+                continue\n+            del self.vfs_info[index]\n+            del self.unused_vfs[index]\n+            del self.used_vfs[index]\n+            del self.vfs[index]\n+\n+    @parallel_lock()\n+    def _check_port_allocated(self, port):\n+        \"\"\"\n+        Check whether port has been pre-allocated\n+        \"\"\"\n+        for vm_info in list(self.allocated_info.values()):\n+            if \"hostport\" in vm_info and port == vm_info[\"hostport\"]:\n+                return True\n+            if \"serialport\" in vm_info and port == vm_info[\"serialport\"]:\n+                return True\n+            if \"migrateport\" in vm_info and port == vm_info[\"migrateport\"]:\n+                return True\n+            if \"displayport\" in vm_info and port == (vm_info[\"displayport\"] + 5900):\n+                return True\n+        return False\n+\n+    @parallel_lock()\n+    def alloc_port(self, vm=\"\", port_type=\"connect\"):\n+        \"\"\"\n+        Allocate unused host port for vm\n+        \"\"\"\n+        global INIT_FREE_PORT\n+        global INIT_SERIAL_PORT\n+        global INIT_MIGRATE_PORT\n+        global INIT_DISPLAY_PORT\n+\n+        if vm == \"\":\n+            print(\"Alloc host port request vitual machine name!!!\")\n+            return None\n+\n+        if port_type == \"connect\":\n+            port = INIT_FREE_PORT\n+        elif port_type == \"serial\":\n+            port = INIT_SERIAL_PORT\n+        elif port_type == \"migrate\":\n+            port = INIT_MIGRATE_PORT\n+        elif port_type == \"display\":\n+            port = INIT_DISPLAY_PORT + 5900\n+\n+        while True:\n+            if (\n+                self.dut.check_port_occupied(port) is False\n+                and self._check_port_allocated(port) is False\n+            ):\n+                break\n+            else:\n+                port += 1\n+                continue\n+\n+        if vm not in self.allocated_info:\n+            self.allocated_info[vm] = {}\n+\n+        if port_type == \"connect\":\n+            self.allocated_info[vm][\"hostport\"] = port\n+        elif port_type == \"serial\":\n+            self.allocated_info[vm][\"serialport\"] = port\n+        elif port_type == \"migrate\":\n+            self.allocated_info[vm][\"migrateport\"] = port\n+        elif port_type == \"display\":\n+            port -= 5900\n+            self.allocated_info[vm][\"displayport\"] = port\n+\n+        # do not scan port from the beginning\n+        if QuickScan:\n+            if port_type == \"connect\":\n+                INIT_FREE_PORT = port\n+            elif port_type == \"serial\":\n+                INIT_SERIAL_PORT = port\n+            elif port_type == \"migrate\":\n+                INIT_MIGRATE_PORT = port\n+            elif port_type == \"display\":\n+                INIT_DISPLAY_PORT = port\n+\n+        return port\n+\n+    @parallel_lock()\n+    def free_port(self, vm):\n+        if self.__vm_has_resource(vm, \"hostport\"):\n+            self.allocated_info[vm].pop(\"hostport\")\n+        if self.__vm_has_resource(vm, \"serialport\"):\n+            self.allocated_info[vm].pop(\"serialport\")\n+        if self.__vm_has_resource(vm, \"migrateport\"):\n+            self.allocated_info[vm].pop(\"migrateport\")\n+        if self.__vm_has_resource(vm, \"displayport\"):\n+            self.allocated_info[vm].pop(\"displayport\")\n+\n+    @parallel_lock()\n+    def free_all_resource(self, vm):\n+        \"\"\"\n+        Free all resource VM has been allocated.\n+        \"\"\"\n+        self.free_port(vm)\n+        self.free_vf(vm)\n+        self.free_pf(vm)\n+        self.free_cpu(vm)\n+\n+        if self.__vm_has_resource(vm):\n+            self.allocated_info.pop(vm)\n+\n+    def get_cpu_on_vm(self, vm=\"\"):\n+        \"\"\"\n+        Return core list on specified VM.\n+        \"\"\"\n+        if vm in self.allocated_info:\n+            if \"cores\" in self.allocated_info[vm]:\n+                return self.allocated_info[vm][\"cores\"]\n+\n+    def get_vfs_on_vm(self, vm=\"\"):\n+        \"\"\"\n+        Return vf device list on specified VM.\n+        \"\"\"\n+        if vm in self.allocated_info:\n+            if \"vfs\" in self.allocated_info[vm]:\n+                return self.allocated_info[vm][\"vfs\"]\n+\n+    def get_pfs_on_vm(self, vm=\"\"):\n+        \"\"\"\n+        Return pf device list on specified VM.\n+        \"\"\"\n+        if vm in self.allocated_info:\n+            if \"ports\" in self.allocated_info[vm]:\n+                return self.allocated_info[vm][\"ports\"]\n+\n+\n+class simple_dut(object):\n+    def __init__(self):\n+        self.ports_info = []\n+        self.cores = []\n+\n+    def check_port_occupied(self, port):\n+        return False\n+\n+\n+if __name__ == \"__main__\":\n+    dut = simple_dut()\n+    dut.cores = [\n+        {\"thread\": \"1\", \"socket\": \"0\"},\n+        {\"thread\": \"2\", \"socket\": \"0\"},\n+        {\"thread\": \"3\", \"socket\": \"0\"},\n+        {\"thread\": \"4\", \"socket\": \"0\"},\n+        {\"thread\": \"5\", \"socket\": \"0\"},\n+        {\"thread\": \"6\", \"socket\": \"0\"},\n+        {\"thread\": \"7\", \"socket\": \"1\"},\n+        {\"thread\": \"8\", \"socket\": \"1\"},\n+        {\"thread\": \"9\", \"socket\": \"1\"},\n+        {\"thread\": \"10\", \"socket\": \"1\"},\n+        {\"thread\": \"11\", \"socket\": \"1\"},\n+        {\"thread\": \"12\", \"socket\": \"1\"},\n+    ]\n+\n+    dut.ports_info = [\n+        {\n+            \"intf\": \"p786p1\",\n+            \"source\": \"cfg\",\n+            \"mac\": \"90:e2:ba:69:e5:e4\",\n+            \"pci\": \"08:00.0\",\n+            \"numa\": 0,\n+            \"ipv6\": \"fe80::92e2:baff:fe69:e5e4\",\n+            \"peer\": \"IXIA:6.5\",\n+            \"type\": \"8086:10fb\",\n+        },\n+        {\n+            \"intf\": \"p786p2\",\n+            \"source\": \"cfg\",\n+            \"mac\": \"90:e2:ba:69:e5:e5\",\n+            \"pci\": \"08:00.1\",\n+            \"numa\": 0,\n+            \"ipv6\": \"fe80::92e2:baff:fe69:e5e5\",\n+            \"peer\": \"IXIA:6.6\",\n+            \"type\": \"8086:10fb\",\n+        },\n+        {\n+            \"intf\": \"p787p1\",\n+            \"source\": \"cfg\",\n+            \"mac\": \"90:e2:ba:69:e5:e6\",\n+            \"pci\": \"84:00.0\",\n+            \"numa\": 1,\n+            \"ipv6\": \"fe80::92e2:baff:fe69:e5e6\",\n+            \"peer\": \"IXIA:6.7\",\n+            \"type\": \"8086:10fb\",\n+        },\n+        {\n+            \"intf\": \"p787p2\",\n+            \"source\": \"cfg\",\n+            \"mac\": \"90:e2:ba:69:e5:e7\",\n+            \"pci\": \"84:00.1\",\n+            \"numa\": 1,\n+            \"ipv6\": \"fe80::92e2:baff:fe69:e5e7\",\n+            \"peer\": \"IXIA:6.8\",\n+            \"type\": \"8086:10fb\",\n+        },\n+    ]\n+\n+    virt_pool = VirtResource(dut)\n+    print(\"Alloc two PF devices on socket 1 from VM\")\n+    print(virt_pool.alloc_pf(vm=\"test1\", number=2, socket=1))\n+\n+    virt_pool.add_vf_on_pf(\n+        pf_pci=\"08:00.0\", vflist=[\"08:10.0\", \"08:10.2\", \"08:10.4\", \"08:10.6\"]\n+    )\n+    virt_pool.add_vf_on_pf(\n+        pf_pci=\"08:00.1\", vflist=[\"08:10.1\", \"08:10.3\", \"08:10.5\", \"08:10.7\"]\n+    )\n+    print(\"Add VF devices to resource pool\")\n+    print(virt_pool.vfs_info)\n+\n+    print(\"Alloc VF device from resource pool\")\n+    print(virt_pool.alloc_vf_from_pf(vm=\"test1\", pf_pci=\"08:00.0\", number=2))\n+    print(virt_pool.used_vfs)\n+    print(\"Alloc VF device from resource pool\")\n+    print(\n+        virt_pool.alloc_vf_from_pf(\n+            vm=\"test2\", pf_pci=\"08:00.1\", vflist=[\"08:10.3\", \"08:10.5\"]\n+        )\n+    )\n+    print(virt_pool.used_vfs)\n+\n+    print(\"Del VF devices from resource pool\")\n+    virt_pool.del_vf_on_pf(pf_pci=\"08:00.0\", vflist=[\"08:10.4\", \"08:10.2\"])\n+    print(virt_pool.vfs_info)\n+\n+    virt_pool.reserve_cpu(\"e\")\n+    print(\"Reserve three cores from resource pool\")\n+    print(virt_pool.unused_cores)\n+    print(\"Alloc two cores on socket1 for VM-test1\")\n+    print(virt_pool.alloc_cpu(vm=\"test1\", number=2, socket=1))\n+    print(\"Alloc two cores in list for VM-test2\")\n+    print(virt_pool.alloc_cpu(vm=\"test2\", corelist=[\"4\", \"5\"]))\n+    print(\"Alloc two cores for VM-test3\")\n+    print(virt_pool.alloc_cpu(vm=\"test3\", number=2))\n+    print(\"Alloc port for VM-test1\")\n+    print(virt_pool.alloc_port(vm=\"test1\"))\n+    print(\"Alloc information after allocated\")\n+    print(virt_pool.allocated_info)\n+\n+    print(\"Get cores on VM-test1\")\n+    print(virt_pool.get_cpu_on_vm(\"test1\"))\n+    print(\"Get pfs on VM-test1\")\n+    print(virt_pool.get_pfs_on_vm(\"test1\"))\n+    print(\"Get vfs on VM-test2\")\n+    print(virt_pool.get_vfs_on_vm(\"test2\"))\n",
    "prefixes": [
        "RFC",
        "v1",
        "11/23"
    ]
}