test suite reviews and discussions
 help / color / Atom feed
* [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan
@ 2020-01-16  1:56 yufengmx
  2020-01-16  1:56 ` [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file yufengmx
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: yufengmx @ 2020-01-16  1:56 UTC (permalink / raw)
  To: dts, lei.a.yao; +Cc: yufengmx

 upload automation script and test plan 

v2: 
 - remove pf passthrough. 

yufengmx (4):
  tests/power_bidirection_channel: vm config file
  tests/power_bidirection_channel: upload automation script
  test_plans/power_bidirection_channel: add test plan index
  test_plans/power_bidirection_channel: upload test plan

 conf/power_bidirection_channel.cfg            |  30 +
 test_plans/index.rst                          |   1 +
 .../power_bidirection_channel_test_plan.rst   | 173 +++++
 tests/TestSuite_power_bidirection_channel.py  | 590 ++++++++++++++++++
 4 files changed, 794 insertions(+)
 create mode 100644 conf/power_bidirection_channel.cfg
 create mode 100644 test_plans/power_bidirection_channel_test_plan.rst
 create mode 100644 tests/TestSuite_power_bidirection_channel.py

-- 
2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file
  2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
@ 2020-01-16  1:56 ` yufengmx
  2020-01-16  2:27   ` Yao, Lei A
  2020-01-16  1:56 ` [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script yufengmx
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: yufengmx @ 2020-01-16  1:56 UTC (permalink / raw)
  To: dts, lei.a.yao; +Cc: yufengmx


upload vm config file.

Signed-off-by: yufengmx <yufengx.mo@intel.com>
---
 conf/power_bidirection_channel.cfg | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 conf/power_bidirection_channel.cfg

diff --git a/conf/power_bidirection_channel.cfg b/conf/power_bidirection_channel.cfg
new file mode 100644
index 0000000..bb13bdf
--- /dev/null
+++ b/conf/power_bidirection_channel.cfg
@@ -0,0 +1,30 @@
+# libvirtd options:
+# [VM name] section value is the name for VM
+# cpu       # hard code type to host-passthrough
+#   number: number of vcpus
+#   cpupin: host cpu list
+# mem
+#   size: 4096
+# disk
+#   file: absolute path to disk image
+#   type: disk image format
+# login
+#   user: user name to login into VM
+#   password: passwork to login into VM
+# device
+#   pf_idx: pass-through device index of DUT ports
+#   guestpci: hardcode value of guest pci address
+# virtio_serial_channel
+#   path: virtio unix socket absolute path
+#   name: virtio serial name in VM
+
+# vm configuration for vm power management case
+[vm0]
+cpu =
+    number=8,cpupin=4 5 6 7 8 9 10 11;
+mem =
+    size=8196;
+disk =
+    file=/home/vms/fedora27.img,opt_format=qcow2;
+login =
+    user=root,password=tester;
-- 
2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script
  2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
  2020-01-16  1:56 ` [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file yufengmx
@ 2020-01-16  1:56 ` yufengmx
  2020-01-16  2:27   ` Yao, Lei A
  2020-01-16  1:56 ` [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index yufengmx
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: yufengmx @ 2020-01-16  1:56 UTC (permalink / raw)
  To: dts, lei.a.yao; +Cc: yufengmx


upload automation script.

Signed-off-by: yufengmx <yufengx.mo@intel.com>
---
 tests/TestSuite_power_bidirection_channel.py | 590 +++++++++++++++++++
 1 file changed, 590 insertions(+)
 create mode 100644 tests/TestSuite_power_bidirection_channel.py

diff --git a/tests/TestSuite_power_bidirection_channel.py b/tests/TestSuite_power_bidirection_channel.py
new file mode 100644
index 0000000..ed82fda
--- /dev/null
+++ b/tests/TestSuite_power_bidirection_channel.py
@@ -0,0 +1,590 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2020 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#   * Neither the name of Intel Corporation nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+DPDK Test suite.
+virtual power manager test suite.
+"""
+import os
+import time
+import traceback
+
+from utils import create_mask as dts_create_mask
+from qemu_libvirt import LibvirtKvm
+from exception import VerifyFailure
+from test_case import TestCase
+
+
+class TestPowerBidirectionChannel(TestCase):
+    # temporary file directory
+    output_path = '/tmp'
+
+    @property
+    def target_dir(self):
+        # get absolute directory of target source code
+        target_dir = '/root' + self.dut.base_dir[1:] \
+                     if self.dut.base_dir.startswith('~') else \
+                     self.dut.base_dir
+        return target_dir
+
+    def get_cores_mask(self, config='all'):
+        ports_socket = self.dut.get_numa_id(self.dut.get_ports()[0])
+        mask = dts_create_mask(
+            self.dut.get_core_list(config, socket=ports_socket))
+        return mask
+
+    def prepare_binary(self, name, host_crb=None):
+        _host_crb = host_crb if host_crb else self.dut
+        example_dir = "examples/" + name
+        out = _host_crb.build_dpdk_apps('./' + example_dir)
+        self.verify("Error" not in out, "Compilation error")
+        self.verify("No such" not in out, "Compilation error")
+        binary_dir = os.path.join(self.target_dir, example_dir, 'build')
+        cmd = ["ls -F {0} | grep '*'".format(binary_dir), '# ', 5]
+        exec_file = self.execute_cmds(cmd, name=_host_crb.session.name)
+        binary_file = os.path.join(binary_dir, exec_file[:-1])
+        return binary_file
+
+    def add_console(self, session):
+        self.ext_con[session.name] = [
+            session.send_expect,
+            session.session.get_output_all]
+
+    def get_console(self, name):
+        default_con_table = {
+            self.dut.session.name: [
+                self.dut.send_expect,
+                self.dut.get_session_output],
+            self.dut.alt_session.name: [
+                self.dut.alt_session.send_expect,
+                self.dut.alt_session.session.get_output_all]}
+        if name not in default_con_table:
+            return self.ext_con.get(name) or [None, None]
+        else:
+            return default_con_table.get(name)
+
+    def execute_cmds(self, cmds, name='dut'):
+        console, msg_pipe = self.get_console(name)
+        if len(cmds) == 0:
+            return
+        if isinstance(cmds, (str, unicode)):
+            cmds = [cmds, '# ', 5]
+        if not isinstance(cmds[0], list):
+            cmds = [cmds]
+        outputs = [] if len(cmds) > 1 else ''
+        for item in cmds:
+            expected_items = item[1]
+            if expected_items and isinstance(expected_items, (list, tuple)):
+                check_output = True
+                expected_str = expected_items[0] or '# '
+            else:
+                check_output = False
+                expected_str = expected_items or '# '
+
+            try:
+                if len(item) == 3:
+                    timeout = int(item[2])
+                    output = console(item[0], expected_str, timeout)
+                    output = msg_pipe() if not output else output
+                else:
+                    output = console(item[0], expected_str)
+                    output = msg_pipe() if not output else output
+            except Exception as e:
+                msg = "execute '{0}' timeout".format(item[0])
+                raise Exception(msg)
+            time.sleep(1)
+            if len(cmds) > 1:
+                outputs.append(output)
+            else:
+                outputs = output
+
+        return outputs
+
+    def d_con(self, cmds):
+        return self.execute_cmds(cmds, name=self.dut.session.name)
+
+    def d_a_con(self, cmds):
+        return self.execute_cmds(cmds, name=self.dut.alt_session.name)
+
+    def vm_con(self, cmds):
+        return self.execute_cmds(cmds, name=self.vm_dut.session.name)
+
+    def vm_g_con(self, cmds):
+        return self.execute_cmds(cmds, name=self.guest_con_name)
+
+    def get_sys_power_driver(self):
+        drv_file = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver"
+        output = self.d_a_con('cat ' + drv_file)
+        if not output:
+            msg = 'unknown power driver'
+            self.verify(False, msg)
+        drv_name = output.splitlines()[0].strip()
+        return drv_name
+
+    @property
+    def is_support_pbf(self):
+        # check if cpu support bpf feature
+        cpu_attr = r'/sys/devices/system/cpu/cpu0/cpufreq/base_frequency'
+        cmd = "ls {0}".format(cpu_attr)
+        self.d_a_con(cmd)
+        cmd = "echo $?"
+        output = self.d_a_con(cmd)
+        ret = True if output == "0" else False
+        return ret
+
+    def get_all_cpu_attrs(self):
+        '''
+        get all cpus' base_frequency value, if not support pbf, set all to 0
+        '''
+        if not self.is_support_pbf:
+            cpu_topos = self.dut.get_all_cores()
+            _base_freqs_info = {}
+            for index, _ in enumerate(cpu_topos):
+                _base_freqs_info[index] = 0
+            return _base_freqs_info
+        # if cpu support high priority core
+        key_values = ['base_frequency',
+                      'cpuinfo_max_freq',
+                      'cpuinfo_min_freq']
+        freq = r'/sys/devices/system/cpu/cpu{0}/cpufreq/{1}'.format
+        # use dut alt session to get dut platform cpu base frequency attribute
+        cpu_topos = self.dut.get_all_cores()
+        cpu_info = {}
+        for cpu_topo in cpu_topos:
+            cpu_id = int(cpu_topo['thread'])
+            cpu_info[cpu_id] = {}
+            cpu_info[cpu_id]['socket'] = cpu_topo['socket']
+            cpu_info[cpu_id]['core'] = cpu_topo['core']
+
+        for key_value in key_values:
+            cmds = []
+            for cpu_id in sorted(cpu_info.keys()):
+                cmds.append('cat {0}'.format(freq(cpu_id, key_value)))
+            output = self.d_a_con(';'.join(cmds))
+            freqs = [int(item) for item in output.splitlines()]
+            for index, cpu_id in enumerate(sorted(cpu_info.keys())):
+                cpu_info[cpu_id][key_value] = freqs[index]
+
+        # get high priority core and normal core
+        base_freqs_info = {}
+        for core_index, value in cpu_info.iteritems():
+            base_frequency = value.get('base_frequency')
+            base_freqs_info.setdefault(base_frequency, []).append(core_index)
+        base_freqs = base_freqs_info.keys()
+        # cpu should have high priority core and normal core
+        # high priority core frequency is higher than normal core frequency
+        if len(base_freqs) <= 1 or \
+           not all([len(value) for value in base_freqs_info.values()]):
+            msg = 'current cpu has no high priority core'
+            raise Exception(msg)
+
+        high_pri_freq = max(self.base_freqs_info.keys())
+        high_pri_cores = base_freqs_info[high_pri_freq]
+        _base_freqs_info = {}
+        for index, _ in enumerate(cpu_topos):
+            _base_freqs_info[index] = 1 if index in high_pri_cores else 0
+
+        return _base_freqs_info
+
+    def init_vms_params(self):
+        self.vm = self.vcpu_map = self.vcpu_lst = self.vm_dut = \
+            self.guest_session = self.is_guest_on = self.is_vm_on = None
+        # vm config
+        self.vm_name = 'vm0'
+        self.vm_max_ch = 8
+        self.vm_log_dir = '/tmp/powermonitor'
+        self.create_powermonitor_folder()
+
+    def create_powermonitor_folder(self):
+        # create temporary folder for power monitor
+        cmd = 'mkdir -p {0}; chmod 777 {0}'.format(self.vm_log_dir)
+        self.d_a_con(cmd)
+
+    def start_vm(self):
+        # set vm initialize parameters
+        self.init_vms_params()
+        # start vm
+        self.vm = LibvirtKvm(self.dut, self.vm_name, self.suite_name)
+        # pass pf to virtual machine
+        pci_addr = self.dut.get_port_pci(self.dut_ports[0])
+        # add channel
+        ch_name = 'virtio.serial.port.poweragent.{0}'
+        vm_path = os.path.join(self.vm_log_dir, '{0}.{1}')
+        for cnt in range(self.vm_max_ch):
+            channel = {
+                'path': vm_path.format(self.vm_name, cnt),
+                'name': ch_name.format(cnt)}
+            self.vm.add_vm_virtio_serial_channel(**channel)
+        # boot up vm
+        self.vm_dut = self.vm.start()
+        self.is_vm_on = True
+        self.verify(self.vm_dut, "create vm_dut fail !")
+        self.add_console(self.vm_dut.session)
+        # get virtual machine cpu cores
+        _vcpu_map = self.vm.get_vm_cpu()
+        self.vcpu_map = [int(item) for item in _vcpu_map]
+        self.vcpu_lst = [int(item['core']) for item in self.vm_dut.cores]
+
+    def close_vm(self):
+        # close vm
+        if self.is_vm_on:
+            if self.guest_session:
+                self.vm_dut.close_session(self.guest_session)
+                self.guest_session = None
+            self.vm.stop()
+            self.is_vm_on = False
+            self.vm = None
+            self.dut.virt_exit()
+            cmd_fmt = 'virsh {0} {1} > /dev/null 2>&1'.format
+            cmds = [
+                [cmd_fmt('shutdown', self.vm_name), '# '],
+                [cmd_fmt('undefine', self.vm_name), '# '], ]
+            self.d_a_con(cmds)
+
+    def init_vm_power_mgr(self):
+        self.vm_power_mgr = self.prepare_binary('vm_power_manager')
+
+    def start_vm_power_mgr(self):
+        eal_option = (
+            ' '
+            '-c {core_mask} '
+            '-n {mem_channel} '
+            '--no-pci ').format(**{
+                'core_mask': self.get_cores_mask("1S/3C/1T"),
+                'mem_channel': self.dut.get_memory_channels(), })
+        prompt = 'vmpower>'
+        option = eal_option
+        cmd = [' '.join([self.vm_power_mgr, option]), prompt, 30]
+        self.d_con(cmd)
+        self.is_mgr_on = True
+
+    def set_vm_power_mgr(self):
+        vm_name = self.vm_name
+        cmds = [
+            "add_vm %s" % vm_name,
+            "add_channels %s all" % vm_name,
+            'set_channel_status %s all enabled' % vm_name,
+            "show_vm %s" % vm_name]
+        prompt = 'vmpower>'
+        self.d_con([[cmd, prompt] for cmd in cmds])
+
+    def close_vm_power_mgr(self):
+        if not self.is_mgr_on:
+            return
+        self.d_con(['quit', '# ', 15])
+        self.is_mgr_on = False
+
+    def host_set_query_enable(self):
+        return self.d_con(
+            ['set_query {} enable'.format(self.vm_name), 'vmpower>', 15])
+
+    def host_set_query_disable(self):
+        return self.d_con(
+            ['set_query {} disable'.format(self.vm_name), 'vmpower>', 15])
+
+    def init_guest_mgr(self):
+        name = 'vm_power_manager/guest_cli'
+        self.guest_cli = self.prepare_binary(name, host_crb=self.vm_dut)
+        self.guest_con_name = \
+            '_'.join([self.vm_dut.NAME, name.replace('/', '-')])
+        self.guest_session = self.vm_dut.create_session(self.guest_con_name)
+        self.add_console(self.guest_session)
+
+    def start_guest_mgr(self):
+        prompt = r"vmpower\(guest\)>"
+        option = (
+            ' '
+            '-c {core_mask} '
+            '-n {memory_channel} '
+            '-m {memory_size} '
+            '--no-pci '
+            '--file-prefix={file_prefix} '
+            '-- '
+            '--vm-name={vm_name} '
+            '--vcpu-list={vpus} ').format(**{
+                'core_mask': '0xff',
+                'memory_channel': self.vm_dut.get_memory_channels(),
+                'memory_size': 1024,
+                'file_prefix': 'vmpower1',
+                'vm_name': self.vm_name,
+                'vpus': ','.join([str(core) for core in self.vcpu_lst]),
+            })
+        guest_cmd = self.guest_cli + option
+        self.vm_g_con([guest_cmd, prompt, 120])
+        self.is_guest_on = True
+
+    def close_guest_mgr(self):
+        if not self.is_guest_on:
+            return
+        self.vm_g_con("quit")
+        self.is_guest_on = False
+
+    def guest_set_cpu_freq_down(self, core_index):
+        return self.vm_g_con(['set_cpu_freq {} down'.format(core_index),
+                              r"vmpower\(guest\)>", 20])
+
+    def guest_query_cpu_caps(self, core='all'):
+        return self.vm_g_con(
+            ['query_cpu_caps {}'.format(core), r"vmpower\(guest\)>", 20])
+
+    def guest_query_cpu_freq(self, core='all'):
+        return self.vm_g_con(
+            ['query_cpu_freq {}'.format(core), r"vmpower\(guest\)>", 20])
+
+    def run_test_pre(self):
+        # boot up binary processes
+        self.start_vm_power_mgr()
+        # set binary process command
+        self.set_vm_power_mgr()
+        # boot up binary processes
+        self.start_guest_mgr()
+
+    def run_test_post(self):
+        # close all binary processes
+        self.close_guest_mgr()
+        self.close_vm_power_mgr()
+
+    def check_cpupower_tool(self):
+        cmd = "whereis cpupower > /dev/null 2>&1; echo $?"
+        output = self.d_a_con(cmd)
+        status = True if output and output.strip() == "0" else False
+        msg = 'cpupower tool have not installed on DUT'
+        self.verify(status, msg)
+
+    def check_policy_command_acked_output(self):
+        output = self.guest_set_cpu_freq_down(self.vcpu_lst[-1])
+        expected = 'ACK received for message sent to host'
+        msg = "expected message '{}' not in output".format(expected)
+        status = expected in output
+        [self.logger.info(output) if not status else None]
+        self.verify(status, msg)
+        output = self.guest_set_cpu_freq_down(self.vcpu_lst[-1] + 1)
+        expected = 'Error sending message: Unknown error -1'
+        msg = "expected message '{}' not in output".format(expected)
+        status = expected in output
+        [self.logger.info(output) if not status else None]
+        self.verify(status, msg)
+
+    def check_query_cpu_freqs_command(self):
+        # Query the CPU frequency for all CPU cores from VM side
+        self.host_set_query_enable()
+
+        def get_cpu_attribute(cores):
+            freq_path_fmt = ("cat /sys/devices/system/cpu/cpu{0}"
+                             "/cpufreq/cpuinfo_cur_freq").format
+            cmd = ";".join([freq_path_fmt(core) for core in cores])
+            output = self.d_a_con(cmd)
+            freqs = [int(item) for item in output.splitlines()]
+            return freqs
+
+        def check(core, freq, output):
+            expected = "Frequency of [{0}] vcore is {1}.".format(core, freq)
+            msg = "expected message '{}' not in output".format(expected)
+            self.verify(expected in output, msg)
+        # check one core
+        check_core = self.vcpu_lst[-1]
+        freqs = get_cpu_attribute([self.vcpu_map[-1]])
+        output = self.guest_query_cpu_freq(check_core)
+        check(check_core, freqs[0], output)
+        # check all cores
+        freqs = get_cpu_attribute(self.vcpu_map)
+        output = self.guest_query_cpu_freq()
+        [check(check_core, freqs[index], output)
+         for index, check_core in enumerate(self.vcpu_lst)]
+        # disable query permission from VM, check the host CPU frequency
+        # won't be returned
+        self.host_set_query_disable()
+        output = self.guest_query_cpu_freq()
+        expected = "Error during frequency list reception."
+        msg = "expected message '{}' not in output".format(expected)
+        self.verify(expected in output, msg)
+
+    def check_cpu_capability_on_vm(self):
+        self.host_set_query_enable()
+        # check the high priority core is recognized correctly.
+        turbo_status = 1
+
+        def check(index, output):
+            vcore = self.vcpu_lst[index]
+            pcore = self.vcpu_map[index]
+            pri = self.base_freqs_info[pcore]
+            expected = (
+                "Capabilities of [{0}] vcore are: "
+                "turbo possibility: {1}, "
+                "is priority core: {2}.").format(vcore, turbo_status, pri)
+            msg = "expected message '{}' not in output".format(expected)
+            self.verify(expected in output, msg)
+
+        output = self.guest_query_cpu_caps()
+        [check(index, output)
+         for index, _ in enumerate(self.vcpu_lst)]
+        # check no CPU info will be return.
+        output = self.guest_query_cpu_caps(self.vcpu_lst[-1] + 1)
+        expected = 'Invalid parameter provided'
+        msg = "expected message '{}' not in output".format(expected)
+        self.verify(expected in output, msg)
+        # check the host CPU capability won't be returned.
+        self.host_set_query_disable()
+        output = self.guest_query_cpu_caps()
+        expected = "Error during capabilities reception"
+        msg = "expected message '{}' not in output".format(expected)
+        self.verify(expected in output, msg)
+
+    def verify_policy_command_acked_action(self):
+        except_content = None
+        msg = "begin test policy command acked action ..."
+        self.logger.info(msg)
+        try:
+            self.run_test_pre()
+            self.check_policy_command_acked_output()
+        except Exception as e:
+            self.logger.error(traceback.format_exc())
+            except_content = e
+        finally:
+            self.run_test_post()
+
+        # check verify result
+        if except_content:
+            raise VerifyFailure(except_content)
+        msg = "test policy command acked action successful !!!"
+        self.logger.info(msg)
+
+    def verify_query_cpu_freqs_from_vm(self):
+        except_content = None
+        msg = "begin test query cpu freqs from vm ..."
+        self.logger.info(msg)
+        try:
+            self.run_test_pre()
+            self.check_query_cpu_freqs_command()
+        except Exception as e:
+            self.logger.error(traceback.format_exc())
+            except_content = e
+        finally:
+            self.run_test_post()
+
+        # check verify result
+        if except_content:
+            raise VerifyFailure(except_content)
+        msg = "test query cpu freqs from vm successful !!!"
+        self.logger.info(msg)
+
+    def verify_query_cpu_capability(self):
+        except_content = None
+        msg = "begin test query cpu capability ..."
+        self.logger.info(msg)
+        try:
+            self.run_test_pre()
+            self.check_cpu_capability_on_vm()
+        except Exception as e:
+            self.logger.error(traceback.format_exc())
+            except_content = e
+        finally:
+            self.run_test_post()
+
+        # check verify result
+        if except_content:
+            raise VerifyFailure(except_content)
+        msg = "test query cpu capability successful !!!"
+        self.logger.info(msg)
+
+    def verify_power_driver(self):
+        expected_drv = 'acpi-cpufreq'
+        power_drv = self.get_sys_power_driver()
+        msg = "{0} should work with {1} driver on DUT".format(
+            self.suite_name, expected_drv)
+        self.verify(power_drv == expected_drv, msg)
+
+    def preset_test_environment(self):
+        self.is_mgr_on = None
+        self.ext_con = {}
+        # modprobe msr module to let the application can get the CPU HW info
+        self.d_a_con('modprobe msr')
+        self.d_a_con('cpupower frequency-set -g userspace')
+        self.dut.init_core_list_uncached_linux()
+        # check if cpu support bpf feature
+        self.base_freqs_info = self.get_all_cpu_attrs()
+        # boot up vm
+        self.start_vm()
+        # init binary
+        self.init_vm_power_mgr()
+        self.init_guest_mgr()
+
+    #
+    # Test cases.
+    #
+
+    def set_up_all(self):
+        """
+        Run at the start of each test suite.
+        """
+        self.dut_ports = self.dut.get_ports(self.nic)
+        self.verify(len(self.dut_ports) >= 1, "Not enough ports")
+        self.check_cpupower_tool()
+        self.verify_power_driver()
+        # prepare testing environment
+        self.preset_test_environment()
+
+    def tear_down_all(self):
+        """
+        Run after each test suite.
+        """
+        self.close_vm()
+
+    def set_up(self):
+        """
+        Run before each test case.
+        """
+        pass
+
+    def tear_down(self):
+        """
+        Run after each test case.
+        """
+        self.vm_dut.kill_all()
+        self.dut.kill_all()
+
+    def test_policy_command_acked_action(self):
+        """
+        Check VM can send power policy command to host and get acked
+        """
+        self.verify_policy_command_acked_action()
+
+    def test_query_cpu_freqs_from_vm(self):
+        """
+        Query Host CPU frequency list from VM
+        """
+        self.verify_query_cpu_freqs_from_vm()
+
+    def test_query_cpu_capability(self):
+        """
+        Query CPU capability from VM
+        """
+        self.verify_query_cpu_capability()
-- 
2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index
  2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
  2020-01-16  1:56 ` [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file yufengmx
  2020-01-16  1:56 ` [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script yufengmx
@ 2020-01-16  1:56 ` yufengmx
  2020-01-16  2:28   ` Yao, Lei A
  2020-01-16  1:56 ` [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan yufengmx
  2020-01-16  6:18 ` [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and " Tu, Lijuan
  4 siblings, 1 reply; 10+ messages in thread
From: yufengmx @ 2020-01-16  1:56 UTC (permalink / raw)
  To: dts, lei.a.yao; +Cc: yufengmx


add test plan index.

Signed-off-by: yufengmx <yufengx.mo@intel.com>
---
 test_plans/index.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test_plans/index.rst b/test_plans/index.rst
index c439870..de4ead7 100644
--- a/test_plans/index.rst
+++ b/test_plans/index.rst
@@ -164,6 +164,7 @@ The following are the test plans for the DPDK DTS automated test system.
     vhost_user_live_migration_test_plan
     vm_power_manager_test_plan
     vm_pw_mgmt_policy_test_plan
+    power_bidirection_channel_test_plan
     power_empty_poll_test_plan
     power_pbf_test_plan
     power_pstate_test_plan
-- 
2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan
  2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
                   ` (2 preceding siblings ...)
  2020-01-16  1:56 ` [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index yufengmx
@ 2020-01-16  1:56 ` yufengmx
  2020-01-16  2:28   ` Yao, Lei A
  2020-01-16  6:18 ` [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and " Tu, Lijuan
  4 siblings, 1 reply; 10+ messages in thread
From: yufengmx @ 2020-01-16  1:56 UTC (permalink / raw)
  To: dts, lei.a.yao; +Cc: yufengmx


upload test plan.

Signed-off-by: yufengmx <yufengx.mo@intel.com>
---
 .../power_bidirection_channel_test_plan.rst   | 173 ++++++++++++++++++
 1 file changed, 173 insertions(+)
 create mode 100644 test_plans/power_bidirection_channel_test_plan.rst

diff --git a/test_plans/power_bidirection_channel_test_plan.rst b/test_plans/power_bidirection_channel_test_plan.rst
new file mode 100644
index 0000000..e26a603
--- /dev/null
+++ b/test_plans/power_bidirection_channel_test_plan.rst
@@ -0,0 +1,173 @@
+.. Copyright (c) <2010-2020>, Intel Corporation
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+   - Neither the name of Intel Corporation nor the names of its
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+   OF THE POSSIBILITY OF SUCH DAMAGE.
+
+===================================
+power bidirection channel test plan
+===================================
+
+preparation work
+================
+1. Turn on speedstep option in BIOS.
+2. Turn on CPU C3 and C6.
+3. Turn on turbo in BIOS.
+4. Disable intel_pstate in Linux kernel command ``intel_pstate=disable``.
+5. modprobe msr module to let the application can get the CPU HW info.
+6. Let user space can control the CPU frequency::
+
+    cpupower frequency-set -g userspace
+
+7. set a folder::
+
+    mkdir /tmp/powermonitor
+    chmod 777 /tmp/powermonitor
+
+
+Test Case 1 : Check VM can send power policy command to host and get acked
+==========================================================================
+Step 1. Launch VM using libvirt::
+
+    virsh start [VM name]
+
+Step 2. Launch VM power manager example on the host to monitor the channel from VM::
+
+    ./examples/vm_power_manager/build/vm_power_mgr -l 12-14 -n 4 --no-pci
+    vmpower> add_vm [vm name]
+    vmpower> add_channels [vm name] all
+    vmpower> set_channel_status [vm name] all enabled
+    vmpower> show_vm [vm name]
+
+    If VM name is ubuntu, the command as following:
+    vmpower> add_vm ubuntu
+    vmpower> add_channels ubuntu all
+    vmpower> set_channel_status ubuntu all enabled
+    vmpower> show_vm ubuntu
+
+Step 3. In the VM, launch guest_vm_power_mgr to set and send the power manager policy to the host power example::
+
+   ./examples/vm_power_manager/guest_cli/build/guest_vm_power_mgr -c 0xff -n 4 -m 1024 --no-pci --file-prefix=vm_power -- --vm-name=ubuntu --vcpu-list=0-7
+
+    Send command to the core 7 on host APP:
+    vmpower(guest)> set_cpu_freq 7 down
+
+    Check following info will be returned for the ACK activity, as following:
+    ACK received for message sent to host.
+
+    If command can't be executed, NACK will be returned, as following:
+    NACK received for message sent to host.
+
+Step 4. Set frequency on core which is out of the VM's core scope::
+
+    For example, the vcpu range is 0-7, we set command to vcpu number 9 as following:
+    vmpower(guest)> set_cpu_freq 9 down
+    GUEST_CHANNEL: Channel is not connected
+    Error sending message: Unknown error -1
+
+
+Test Case 2 : Query Host CPU frequency list from VM
+===================================================
+Step 1. Launch VM using libvirt::
+
+    virsh start [VM name]
+
+Step 2. Launch VM power manager example on the host to monitor the channel from VM::
+
+    ./examples/vm_power_manager/build/vm_power_mgr -l 12-14 -n 4 --no-pci
+    vmpower> add_vm [vm name]
+    vmpower> add_channels [vm name] all
+    vmpower> set_channel_status [vm name] all enabled
+    vmpower> show_vm [vm name]
+    vmpower> set_query <vm_name> <enable|disable>
+
+Step 3. Enable the query permission for target VM from host vm_power_mgr example::
+
+    Command format: set_query <vm_name> <enable|disable>
+    if vm name is ubuntu,command as following:
+    vmpower> set_query ubuntu enable
+
+Step 4. Query the CPU frequency for all CPU cores from VM side::
+
+   ./examples/vm_power_manager/guest_cli/build/guest_vm_power_mgr -c 0xff -n 4 -m 1024 --no-pci --file-prefix=vm_power -- --vm-name=ubuntu --vcpu-list=0-7
+    vmpower> query_cpu_freq <core_num> | all
+
+    Check vcpu 0~7 frequency info will be returned, for example:
+        Frequency of [0] vcore is 2300000.
+        Frequency of [1] vcore is 2200000.
+        Frequency of [2] vcore is 2800000.
+        Frequency of [3] vcore is 2300000.
+        Frequency of [4] vcore is 2300000.
+        Frequency of [5] vcore is 2300000.
+        Frequency of [6] vcore is 2300000.
+        Frequency of [7] vcore is 2300000.
+
+Step 5. Disable query permission from VM, check the host CPU frequency won't be returned::
+
+    at host side, disable query permission by vm_power_mgr example:
+    vmpower> set_query ubuntu disable
+
+    at VM side, query CPU frequency again, this action should not be executed successfully, log as following:
+    vmpower(guest)> query_cpu_freq all
+    GUEST_CLI: Error receiving message.
+    Error during frequency list reception.
+
+
+Test Case 3: Query CPU capability from VM
+=========================================
+Step1~3. The same as test case 2
+
+Step4: Query all the valid CPU core capability of host, check all cores' information is returned. Check the high priority core is recognized correctly::
+
+    For example, core 2 is returned as high priority core:
+    vmpower(guest)> query_cpu_caps all
+    Capabilities of [0] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [1] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [2] vcore are: turbo possibility: 1, is priority core: 1.
+    Capabilities of [3] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [4] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [5] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [6] vcore are: turbo possibility: 1, is priority core: 0.
+    Capabilities of [7] vcore are: turbo possibility: 1, is priority core: 0.
+
+Step 5: Query CPU capability for core out of scope, check no CPU info will be return::
+
+    For example, the valid vcpu range is 0~7, query cpu capability of core 9 should return error as following:
+    vmpower(guest)> query_cpu_caps 9
+    Invalid parameter provided.
+
+Step 6: Disable query permission from VM, check the host CPU capability won't be returned::
+
+    at host side, disable query permission by vm_power_mgr example:
+    vmpower> set_query ubuntu disable
+
+    at VM side, query CPU capability again, this action should not be executed successfully, log as following:
+    vmpower(guest)> query_cpu_caps all
+    GUEST_CLI: Error receiving message.
+    Error during capabilities reception.
\ No newline at end of file
-- 
2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file
  2020-01-16  1:56 ` [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file yufengmx
@ 2020-01-16  2:27   ` Yao, Lei A
  0 siblings, 0 replies; 10+ messages in thread
From: Yao, Lei A @ 2020-01-16  2:27 UTC (permalink / raw)
  To: Mo, YufengX, dts



> -----Original Message-----
> From: Mo, YufengX <yufengx.mo@intel.com>
> Sent: Thursday, January 16, 2020 9:56 AM
> To: dts@dpdk.org; Yao, Lei A <lei.a.yao@intel.com>
> Cc: Mo, YufengX <yufengx.mo@intel.com>
> Subject: [dts][PATCH V2 1/4] tests/power_bidirection_channel: vm config
> file
> 
> 
> upload vm config file.
> 
> Signed-off-by: yufengmx <yufengx.mo@intel.com>
Acked-by: Lei Yao <lei.a.yao@intel.com>
> ---
>  conf/power_bidirection_channel.cfg | 30
> ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 conf/power_bidirection_channel.cfg
> 
> diff --git a/conf/power_bidirection_channel.cfg
> b/conf/power_bidirection_channel.cfg
> new file mode 100644
> index 0000000..bb13bdf
> --- /dev/null
> +++ b/conf/power_bidirection_channel.cfg
> @@ -0,0 +1,30 @@
> +# libvirtd options:
> +# [VM name] section value is the name for VM
> +# cpu       # hard code type to host-passthrough
> +#   number: number of vcpus
> +#   cpupin: host cpu list
> +# mem
> +#   size: 4096
> +# disk
> +#   file: absolute path to disk image
> +#   type: disk image format
> +# login
> +#   user: user name to login into VM
> +#   password: passwork to login into VM
> +# device
> +#   pf_idx: pass-through device index of DUT ports
> +#   guestpci: hardcode value of guest pci address
> +# virtio_serial_channel
> +#   path: virtio unix socket absolute path
> +#   name: virtio serial name in VM
> +
> +# vm configuration for vm power management case [vm0] cpu =
> +    number=8,cpupin=4 5 6 7 8 9 10 11;
> +mem =
> +    size=8196;
> +disk =
> +    file=/home/vms/fedora27.img,opt_format=qcow2;
> +login =
> +    user=root,password=tester;
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script
  2020-01-16  1:56 ` [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script yufengmx
@ 2020-01-16  2:27   ` Yao, Lei A
  0 siblings, 0 replies; 10+ messages in thread
From: Yao, Lei A @ 2020-01-16  2:27 UTC (permalink / raw)
  To: Mo, YufengX, dts



> -----Original Message-----
> From: Mo, YufengX <yufengx.mo@intel.com>
> Sent: Thursday, January 16, 2020 9:56 AM
> To: dts@dpdk.org; Yao, Lei A <lei.a.yao@intel.com>
> Cc: Mo, YufengX <yufengx.mo@intel.com>
> Subject: [dts][PATCH V2 2/4] tests/power_bidirection_channel: upload
> automation script
> 
> 
> upload automation script.
> 
> Signed-off-by: yufengmx <yufengx.mo@intel.com>
Acked-by: Lei Yao <lei.a.yao@intel.com>
> ---
>  tests/TestSuite_power_bidirection_channel.py | 590
> +++++++++++++++++++
>  1 file changed, 590 insertions(+)
>  create mode 100644 tests/TestSuite_power_bidirection_channel.py
> 
> diff --git a/tests/TestSuite_power_bidirection_channel.py
> b/tests/TestSuite_power_bidirection_channel.py
> new file mode 100644
> index 0000000..ed82fda
> --- /dev/null
> +++ b/tests/TestSuite_power_bidirection_channel.py
> @@ -0,0 +1,590 @@
> +# BSD LICENSE
> +#
> +# Copyright(c) 2010-2020 Intel Corporation. All rights reserved.
> +# All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without #
> +modification, are permitted provided that the following conditions #
> +are met:
> +#
> +#   * Redistributions of source code must retain the above copyright
> +#     notice, this list of conditions and the following disclaimer.
> +#   * Redistributions in binary form must reproduce the above copyright
> +#     notice, this list of conditions and the following disclaimer in
> +#     the documentation and/or other materials provided with the
> +#     distribution.
> +#   * Neither the name of Intel Corporation nor the names of its
> +#     contributors may be used to endorse or promote products derived
> +#     from this software without specific prior written permission.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS #
> +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> #
> +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> FOR #
> +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT #
> +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL, #
> +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> NOT #
> +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> USE, #
> +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY #
> +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE #
> +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> +
> +"""
> +DPDK Test suite.
> +virtual power manager test suite.
> +"""
> +import os
> +import time
> +import traceback
> +
> +from utils import create_mask as dts_create_mask from qemu_libvirt
> +import LibvirtKvm from exception import VerifyFailure from test_case
> +import TestCase
> +
> +
> +class TestPowerBidirectionChannel(TestCase):
> +    # temporary file directory
> +    output_path = '/tmp'
> +
> +    @property
> +    def target_dir(self):
> +        # get absolute directory of target source code
> +        target_dir = '/root' + self.dut.base_dir[1:] \
> +                     if self.dut.base_dir.startswith('~') else \
> +                     self.dut.base_dir
> +        return target_dir
> +
> +    def get_cores_mask(self, config='all'):
> +        ports_socket = self.dut.get_numa_id(self.dut.get_ports()[0])
> +        mask = dts_create_mask(
> +            self.dut.get_core_list(config, socket=ports_socket))
> +        return mask
> +
> +    def prepare_binary(self, name, host_crb=None):
> +        _host_crb = host_crb if host_crb else self.dut
> +        example_dir = "examples/" + name
> +        out = _host_crb.build_dpdk_apps('./' + example_dir)
> +        self.verify("Error" not in out, "Compilation error")
> +        self.verify("No such" not in out, "Compilation error")
> +        binary_dir = os.path.join(self.target_dir, example_dir, 'build')
> +        cmd = ["ls -F {0} | grep '*'".format(binary_dir), '# ', 5]
> +        exec_file = self.execute_cmds(cmd, name=_host_crb.session.name)
> +        binary_file = os.path.join(binary_dir, exec_file[:-1])
> +        return binary_file
> +
> +    def add_console(self, session):
> +        self.ext_con[session.name] = [
> +            session.send_expect,
> +            session.session.get_output_all]
> +
> +    def get_console(self, name):
> +        default_con_table = {
> +            self.dut.session.name: [
> +                self.dut.send_expect,
> +                self.dut.get_session_output],
> +            self.dut.alt_session.name: [
> +                self.dut.alt_session.send_expect,
> +                self.dut.alt_session.session.get_output_all]}
> +        if name not in default_con_table:
> +            return self.ext_con.get(name) or [None, None]
> +        else:
> +            return default_con_table.get(name)
> +
> +    def execute_cmds(self, cmds, name='dut'):
> +        console, msg_pipe = self.get_console(name)
> +        if len(cmds) == 0:
> +            return
> +        if isinstance(cmds, (str, unicode)):
> +            cmds = [cmds, '# ', 5]
> +        if not isinstance(cmds[0], list):
> +            cmds = [cmds]
> +        outputs = [] if len(cmds) > 1 else ''
> +        for item in cmds:
> +            expected_items = item[1]
> +            if expected_items and isinstance(expected_items, (list, tuple)):
> +                check_output = True
> +                expected_str = expected_items[0] or '# '
> +            else:
> +                check_output = False
> +                expected_str = expected_items or '# '
> +
> +            try:
> +                if len(item) == 3:
> +                    timeout = int(item[2])
> +                    output = console(item[0], expected_str, timeout)
> +                    output = msg_pipe() if not output else output
> +                else:
> +                    output = console(item[0], expected_str)
> +                    output = msg_pipe() if not output else output
> +            except Exception as e:
> +                msg = "execute '{0}' timeout".format(item[0])
> +                raise Exception(msg)
> +            time.sleep(1)
> +            if len(cmds) > 1:
> +                outputs.append(output)
> +            else:
> +                outputs = output
> +
> +        return outputs
> +
> +    def d_con(self, cmds):
> +        return self.execute_cmds(cmds, name=self.dut.session.name)
> +
> +    def d_a_con(self, cmds):
> +        return self.execute_cmds(cmds, name=self.dut.alt_session.name)
> +
> +    def vm_con(self, cmds):
> +        return self.execute_cmds(cmds, name=self.vm_dut.session.name)
> +
> +    def vm_g_con(self, cmds):
> +        return self.execute_cmds(cmds, name=self.guest_con_name)
> +
> +    def get_sys_power_driver(self):
> +        drv_file = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver"
> +        output = self.d_a_con('cat ' + drv_file)
> +        if not output:
> +            msg = 'unknown power driver'
> +            self.verify(False, msg)
> +        drv_name = output.splitlines()[0].strip()
> +        return drv_name
> +
> +    @property
> +    def is_support_pbf(self):
> +        # check if cpu support bpf feature
> +        cpu_attr = r'/sys/devices/system/cpu/cpu0/cpufreq/base_frequency'
> +        cmd = "ls {0}".format(cpu_attr)
> +        self.d_a_con(cmd)
> +        cmd = "echo $?"
> +        output = self.d_a_con(cmd)
> +        ret = True if output == "0" else False
> +        return ret
> +
> +    def get_all_cpu_attrs(self):
> +        '''
> +        get all cpus' base_frequency value, if not support pbf, set all to 0
> +        '''
> +        if not self.is_support_pbf:
> +            cpu_topos = self.dut.get_all_cores()
> +            _base_freqs_info = {}
> +            for index, _ in enumerate(cpu_topos):
> +                _base_freqs_info[index] = 0
> +            return _base_freqs_info
> +        # if cpu support high priority core
> +        key_values = ['base_frequency',
> +                      'cpuinfo_max_freq',
> +                      'cpuinfo_min_freq']
> +        freq = r'/sys/devices/system/cpu/cpu{0}/cpufreq/{1}'.format
> +        # use dut alt session to get dut platform cpu base frequency attribute
> +        cpu_topos = self.dut.get_all_cores()
> +        cpu_info = {}
> +        for cpu_topo in cpu_topos:
> +            cpu_id = int(cpu_topo['thread'])
> +            cpu_info[cpu_id] = {}
> +            cpu_info[cpu_id]['socket'] = cpu_topo['socket']
> +            cpu_info[cpu_id]['core'] = cpu_topo['core']
> +
> +        for key_value in key_values:
> +            cmds = []
> +            for cpu_id in sorted(cpu_info.keys()):
> +                cmds.append('cat {0}'.format(freq(cpu_id, key_value)))
> +            output = self.d_a_con(';'.join(cmds))
> +            freqs = [int(item) for item in output.splitlines()]
> +            for index, cpu_id in enumerate(sorted(cpu_info.keys())):
> +                cpu_info[cpu_id][key_value] = freqs[index]
> +
> +        # get high priority core and normal core
> +        base_freqs_info = {}
> +        for core_index, value in cpu_info.iteritems():
> +            base_frequency = value.get('base_frequency')
> +            base_freqs_info.setdefault(base_frequency, []).append(core_index)
> +        base_freqs = base_freqs_info.keys()
> +        # cpu should have high priority core and normal core
> +        # high priority core frequency is higher than normal core frequency
> +        if len(base_freqs) <= 1 or \
> +           not all([len(value) for value in base_freqs_info.values()]):
> +            msg = 'current cpu has no high priority core'
> +            raise Exception(msg)
> +
> +        high_pri_freq = max(self.base_freqs_info.keys())
> +        high_pri_cores = base_freqs_info[high_pri_freq]
> +        _base_freqs_info = {}
> +        for index, _ in enumerate(cpu_topos):
> +            _base_freqs_info[index] = 1 if index in high_pri_cores else
> + 0
> +
> +        return _base_freqs_info
> +
> +    def init_vms_params(self):
> +        self.vm = self.vcpu_map = self.vcpu_lst = self.vm_dut = \
> +            self.guest_session = self.is_guest_on = self.is_vm_on = None
> +        # vm config
> +        self.vm_name = 'vm0'
> +        self.vm_max_ch = 8
> +        self.vm_log_dir = '/tmp/powermonitor'
> +        self.create_powermonitor_folder()
> +
> +    def create_powermonitor_folder(self):
> +        # create temporary folder for power monitor
> +        cmd = 'mkdir -p {0}; chmod 777 {0}'.format(self.vm_log_dir)
> +        self.d_a_con(cmd)
> +
> +    def start_vm(self):
> +        # set vm initialize parameters
> +        self.init_vms_params()
> +        # start vm
> +        self.vm = LibvirtKvm(self.dut, self.vm_name, self.suite_name)
> +        # pass pf to virtual machine
> +        pci_addr = self.dut.get_port_pci(self.dut_ports[0])
> +        # add channel
> +        ch_name = 'virtio.serial.port.poweragent.{0}'
> +        vm_path = os.path.join(self.vm_log_dir, '{0}.{1}')
> +        for cnt in range(self.vm_max_ch):
> +            channel = {
> +                'path': vm_path.format(self.vm_name, cnt),
> +                'name': ch_name.format(cnt)}
> +            self.vm.add_vm_virtio_serial_channel(**channel)
> +        # boot up vm
> +        self.vm_dut = self.vm.start()
> +        self.is_vm_on = True
> +        self.verify(self.vm_dut, "create vm_dut fail !")
> +        self.add_console(self.vm_dut.session)
> +        # get virtual machine cpu cores
> +        _vcpu_map = self.vm.get_vm_cpu()
> +        self.vcpu_map = [int(item) for item in _vcpu_map]
> +        self.vcpu_lst = [int(item['core']) for item in
> + self.vm_dut.cores]
> +
> +    def close_vm(self):
> +        # close vm
> +        if self.is_vm_on:
> +            if self.guest_session:
> +                self.vm_dut.close_session(self.guest_session)
> +                self.guest_session = None
> +            self.vm.stop()
> +            self.is_vm_on = False
> +            self.vm = None
> +            self.dut.virt_exit()
> +            cmd_fmt = 'virsh {0} {1} > /dev/null 2>&1'.format
> +            cmds = [
> +                [cmd_fmt('shutdown', self.vm_name), '# '],
> +                [cmd_fmt('undefine', self.vm_name), '# '], ]
> +            self.d_a_con(cmds)
> +
> +    def init_vm_power_mgr(self):
> +        self.vm_power_mgr = self.prepare_binary('vm_power_manager')
> +
> +    def start_vm_power_mgr(self):
> +        eal_option = (
> +            ' '
> +            '-c {core_mask} '
> +            '-n {mem_channel} '
> +            '--no-pci ').format(**{
> +                'core_mask': self.get_cores_mask("1S/3C/1T"),
> +                'mem_channel': self.dut.get_memory_channels(), })
> +        prompt = 'vmpower>'
> +        option = eal_option
> +        cmd = [' '.join([self.vm_power_mgr, option]), prompt, 30]
> +        self.d_con(cmd)
> +        self.is_mgr_on = True
> +
> +    def set_vm_power_mgr(self):
> +        vm_name = self.vm_name
> +        cmds = [
> +            "add_vm %s" % vm_name,
> +            "add_channels %s all" % vm_name,
> +            'set_channel_status %s all enabled' % vm_name,
> +            "show_vm %s" % vm_name]
> +        prompt = 'vmpower>'
> +        self.d_con([[cmd, prompt] for cmd in cmds])
> +
> +    def close_vm_power_mgr(self):
> +        if not self.is_mgr_on:
> +            return
> +        self.d_con(['quit', '# ', 15])
> +        self.is_mgr_on = False
> +
> +    def host_set_query_enable(self):
> +        return self.d_con(
> +            ['set_query {} enable'.format(self.vm_name), 'vmpower>',
> + 15])
> +
> +    def host_set_query_disable(self):
> +        return self.d_con(
> +            ['set_query {} disable'.format(self.vm_name), 'vmpower>',
> + 15])
> +
> +    def init_guest_mgr(self):
> +        name = 'vm_power_manager/guest_cli'
> +        self.guest_cli = self.prepare_binary(name, host_crb=self.vm_dut)
> +        self.guest_con_name = \
> +            '_'.join([self.vm_dut.NAME, name.replace('/', '-')])
> +        self.guest_session = self.vm_dut.create_session(self.guest_con_name)
> +        self.add_console(self.guest_session)
> +
> +    def start_guest_mgr(self):
> +        prompt = r"vmpower\(guest\)>"
> +        option = (
> +            ' '
> +            '-c {core_mask} '
> +            '-n {memory_channel} '
> +            '-m {memory_size} '
> +            '--no-pci '
> +            '--file-prefix={file_prefix} '
> +            '-- '
> +            '--vm-name={vm_name} '
> +            '--vcpu-list={vpus} ').format(**{
> +                'core_mask': '0xff',
> +                'memory_channel': self.vm_dut.get_memory_channels(),
> +                'memory_size': 1024,
> +                'file_prefix': 'vmpower1',
> +                'vm_name': self.vm_name,
> +                'vpus': ','.join([str(core) for core in self.vcpu_lst]),
> +            })
> +        guest_cmd = self.guest_cli + option
> +        self.vm_g_con([guest_cmd, prompt, 120])
> +        self.is_guest_on = True
> +
> +    def close_guest_mgr(self):
> +        if not self.is_guest_on:
> +            return
> +        self.vm_g_con("quit")
> +        self.is_guest_on = False
> +
> +    def guest_set_cpu_freq_down(self, core_index):
> +        return self.vm_g_con(['set_cpu_freq {} down'.format(core_index),
> +                              r"vmpower\(guest\)>", 20])
> +
> +    def guest_query_cpu_caps(self, core='all'):
> +        return self.vm_g_con(
> +            ['query_cpu_caps {}'.format(core), r"vmpower\(guest\)>",
> + 20])
> +
> +    def guest_query_cpu_freq(self, core='all'):
> +        return self.vm_g_con(
> +            ['query_cpu_freq {}'.format(core), r"vmpower\(guest\)>",
> + 20])
> +
> +    def run_test_pre(self):
> +        # boot up binary processes
> +        self.start_vm_power_mgr()
> +        # set binary process command
> +        self.set_vm_power_mgr()
> +        # boot up binary processes
> +        self.start_guest_mgr()
> +
> +    def run_test_post(self):
> +        # close all binary processes
> +        self.close_guest_mgr()
> +        self.close_vm_power_mgr()
> +
> +    def check_cpupower_tool(self):
> +        cmd = "whereis cpupower > /dev/null 2>&1; echo $?"
> +        output = self.d_a_con(cmd)
> +        status = True if output and output.strip() == "0" else False
> +        msg = 'cpupower tool have not installed on DUT'
> +        self.verify(status, msg)
> +
> +    def check_policy_command_acked_output(self):
> +        output = self.guest_set_cpu_freq_down(self.vcpu_lst[-1])
> +        expected = 'ACK received for message sent to host'
> +        msg = "expected message '{}' not in output".format(expected)
> +        status = expected in output
> +        [self.logger.info(output) if not status else None]
> +        self.verify(status, msg)
> +        output = self.guest_set_cpu_freq_down(self.vcpu_lst[-1] + 1)
> +        expected = 'Error sending message: Unknown error -1'
> +        msg = "expected message '{}' not in output".format(expected)
> +        status = expected in output
> +        [self.logger.info(output) if not status else None]
> +        self.verify(status, msg)
> +
> +    def check_query_cpu_freqs_command(self):
> +        # Query the CPU frequency for all CPU cores from VM side
> +        self.host_set_query_enable()
> +
> +        def get_cpu_attribute(cores):
> +            freq_path_fmt = ("cat /sys/devices/system/cpu/cpu{0}"
> +                             "/cpufreq/cpuinfo_cur_freq").format
> +            cmd = ";".join([freq_path_fmt(core) for core in cores])
> +            output = self.d_a_con(cmd)
> +            freqs = [int(item) for item in output.splitlines()]
> +            return freqs
> +
> +        def check(core, freq, output):
> +            expected = "Frequency of [{0}] vcore is {1}.".format(core, freq)
> +            msg = "expected message '{}' not in output".format(expected)
> +            self.verify(expected in output, msg)
> +        # check one core
> +        check_core = self.vcpu_lst[-1]
> +        freqs = get_cpu_attribute([self.vcpu_map[-1]])
> +        output = self.guest_query_cpu_freq(check_core)
> +        check(check_core, freqs[0], output)
> +        # check all cores
> +        freqs = get_cpu_attribute(self.vcpu_map)
> +        output = self.guest_query_cpu_freq()
> +        [check(check_core, freqs[index], output)
> +         for index, check_core in enumerate(self.vcpu_lst)]
> +        # disable query permission from VM, check the host CPU frequency
> +        # won't be returned
> +        self.host_set_query_disable()
> +        output = self.guest_query_cpu_freq()
> +        expected = "Error during frequency list reception."
> +        msg = "expected message '{}' not in output".format(expected)
> +        self.verify(expected in output, msg)
> +
> +    def check_cpu_capability_on_vm(self):
> +        self.host_set_query_enable()
> +        # check the high priority core is recognized correctly.
> +        turbo_status = 1
> +
> +        def check(index, output):
> +            vcore = self.vcpu_lst[index]
> +            pcore = self.vcpu_map[index]
> +            pri = self.base_freqs_info[pcore]
> +            expected = (
> +                "Capabilities of [{0}] vcore are: "
> +                "turbo possibility: {1}, "
> +                "is priority core: {2}.").format(vcore, turbo_status, pri)
> +            msg = "expected message '{}' not in output".format(expected)
> +            self.verify(expected in output, msg)
> +
> +        output = self.guest_query_cpu_caps()
> +        [check(index, output)
> +         for index, _ in enumerate(self.vcpu_lst)]
> +        # check no CPU info will be return.
> +        output = self.guest_query_cpu_caps(self.vcpu_lst[-1] + 1)
> +        expected = 'Invalid parameter provided'
> +        msg = "expected message '{}' not in output".format(expected)
> +        self.verify(expected in output, msg)
> +        # check the host CPU capability won't be returned.
> +        self.host_set_query_disable()
> +        output = self.guest_query_cpu_caps()
> +        expected = "Error during capabilities reception"
> +        msg = "expected message '{}' not in output".format(expected)
> +        self.verify(expected in output, msg)
> +
> +    def verify_policy_command_acked_action(self):
> +        except_content = None
> +        msg = "begin test policy command acked action ..."
> +        self.logger.info(msg)
> +        try:
> +            self.run_test_pre()
> +            self.check_policy_command_acked_output()
> +        except Exception as e:
> +            self.logger.error(traceback.format_exc())
> +            except_content = e
> +        finally:
> +            self.run_test_post()
> +
> +        # check verify result
> +        if except_content:
> +            raise VerifyFailure(except_content)
> +        msg = "test policy command acked action successful !!!"
> +        self.logger.info(msg)
> +
> +    def verify_query_cpu_freqs_from_vm(self):
> +        except_content = None
> +        msg = "begin test query cpu freqs from vm ..."
> +        self.logger.info(msg)
> +        try:
> +            self.run_test_pre()
> +            self.check_query_cpu_freqs_command()
> +        except Exception as e:
> +            self.logger.error(traceback.format_exc())
> +            except_content = e
> +        finally:
> +            self.run_test_post()
> +
> +        # check verify result
> +        if except_content:
> +            raise VerifyFailure(except_content)
> +        msg = "test query cpu freqs from vm successful !!!"
> +        self.logger.info(msg)
> +
> +    def verify_query_cpu_capability(self):
> +        except_content = None
> +        msg = "begin test query cpu capability ..."
> +        self.logger.info(msg)
> +        try:
> +            self.run_test_pre()
> +            self.check_cpu_capability_on_vm()
> +        except Exception as e:
> +            self.logger.error(traceback.format_exc())
> +            except_content = e
> +        finally:
> +            self.run_test_post()
> +
> +        # check verify result
> +        if except_content:
> +            raise VerifyFailure(except_content)
> +        msg = "test query cpu capability successful !!!"
> +        self.logger.info(msg)
> +
> +    def verify_power_driver(self):
> +        expected_drv = 'acpi-cpufreq'
> +        power_drv = self.get_sys_power_driver()
> +        msg = "{0} should work with {1} driver on DUT".format(
> +            self.suite_name, expected_drv)
> +        self.verify(power_drv == expected_drv, msg)
> +
> +    def preset_test_environment(self):
> +        self.is_mgr_on = None
> +        self.ext_con = {}
> +        # modprobe msr module to let the application can get the CPU HW info
> +        self.d_a_con('modprobe msr')
> +        self.d_a_con('cpupower frequency-set -g userspace')
> +        self.dut.init_core_list_uncached_linux()
> +        # check if cpu support bpf feature
> +        self.base_freqs_info = self.get_all_cpu_attrs()
> +        # boot up vm
> +        self.start_vm()
> +        # init binary
> +        self.init_vm_power_mgr()
> +        self.init_guest_mgr()
> +
> +    #
> +    # Test cases.
> +    #
> +
> +    def set_up_all(self):
> +        """
> +        Run at the start of each test suite.
> +        """
> +        self.dut_ports = self.dut.get_ports(self.nic)
> +        self.verify(len(self.dut_ports) >= 1, "Not enough ports")
> +        self.check_cpupower_tool()
> +        self.verify_power_driver()
> +        # prepare testing environment
> +        self.preset_test_environment()
> +
> +    def tear_down_all(self):
> +        """
> +        Run after each test suite.
> +        """
> +        self.close_vm()
> +
> +    def set_up(self):
> +        """
> +        Run before each test case.
> +        """
> +        pass
> +
> +    def tear_down(self):
> +        """
> +        Run after each test case.
> +        """
> +        self.vm_dut.kill_all()
> +        self.dut.kill_all()
> +
> +    def test_policy_command_acked_action(self):
> +        """
> +        Check VM can send power policy command to host and get acked
> +        """
> +        self.verify_policy_command_acked_action()
> +
> +    def test_query_cpu_freqs_from_vm(self):
> +        """
> +        Query Host CPU frequency list from VM
> +        """
> +        self.verify_query_cpu_freqs_from_vm()
> +
> +    def test_query_cpu_capability(self):
> +        """
> +        Query CPU capability from VM
> +        """
> +        self.verify_query_cpu_capability()
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index
  2020-01-16  1:56 ` [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index yufengmx
@ 2020-01-16  2:28   ` Yao, Lei A
  0 siblings, 0 replies; 10+ messages in thread
From: Yao, Lei A @ 2020-01-16  2:28 UTC (permalink / raw)
  To: Mo, YufengX, dts



> -----Original Message-----
> From: Mo, YufengX <yufengx.mo@intel.com>
> Sent: Thursday, January 16, 2020 9:56 AM
> To: dts@dpdk.org; Yao, Lei A <lei.a.yao@intel.com>
> Cc: Mo, YufengX <yufengx.mo@intel.com>
> Subject: [dts][PATCH V2 3/4] test_plans/power_bidirection_channel: add
> test plan index
> 
> 
> add test plan index.
> 
> Signed-off-by: yufengmx <yufengx.mo@intel.com>
Acked-by: Lei Yao <lei.a.yao@intel.com>
> ---
>  test_plans/index.rst | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/test_plans/index.rst b/test_plans/index.rst index
> c439870..de4ead7 100644
> --- a/test_plans/index.rst
> +++ b/test_plans/index.rst
> @@ -164,6 +164,7 @@ The following are the test plans for the DPDK DTS
> automated test system.
>      vhost_user_live_migration_test_plan
>      vm_power_manager_test_plan
>      vm_pw_mgmt_policy_test_plan
> +    power_bidirection_channel_test_plan
>      power_empty_poll_test_plan
>      power_pbf_test_plan
>      power_pstate_test_plan
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan
  2020-01-16  1:56 ` [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan yufengmx
@ 2020-01-16  2:28   ` Yao, Lei A
  0 siblings, 0 replies; 10+ messages in thread
From: Yao, Lei A @ 2020-01-16  2:28 UTC (permalink / raw)
  To: Mo, YufengX, dts



> -----Original Message-----
> From: Mo, YufengX <yufengx.mo@intel.com>
> Sent: Thursday, January 16, 2020 9:57 AM
> To: dts@dpdk.org; Yao, Lei A <lei.a.yao@intel.com>
> Cc: Mo, YufengX <yufengx.mo@intel.com>
> Subject: [dts][PATCH V2 4/4] test_plans/power_bidirection_channel: upload
> test plan
> 
> 
> upload test plan.
> 
> Signed-off-by: yufengmx <yufengx.mo@intel.com>
Acked-by: Lei Yao <lei.a.yao@intel.com>
> ---
>  .../power_bidirection_channel_test_plan.rst   | 173 ++++++++++++++++++
>  1 file changed, 173 insertions(+)
>  create mode 100644 test_plans/power_bidirection_channel_test_plan.rst
> 
> diff --git a/test_plans/power_bidirection_channel_test_plan.rst
> b/test_plans/power_bidirection_channel_test_plan.rst
> new file mode 100644
> index 0000000..e26a603
> --- /dev/null
> +++ b/test_plans/power_bidirection_channel_test_plan.rst
> @@ -0,0 +1,173 @@
> +.. Copyright (c) <2010-2020>, Intel Corporation
> +   All rights reserved.
> +
> +   Redistribution and use in source and binary forms, with or without
> +   modification, are permitted provided that the following conditions
> +   are met:
> +
> +   - Redistributions of source code must retain the above copyright
> +     notice, this list of conditions and the following disclaimer.
> +
> +   - Redistributions in binary form must reproduce the above copyright
> +     notice, this list of conditions and the following disclaimer in
> +     the documentation and/or other materials provided with the
> +     distribution.
> +
> +   - Neither the name of Intel Corporation nor the names of its
> +     contributors may be used to endorse or promote products derived
> +     from this software without specific prior written permission.
> +
> +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> +   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS
> +   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> +   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT,
> +   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> +   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
> GOODS OR
> +   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> +   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> CONTRACT,
> +   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> ADVISED
> +   OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +===================================
> +power bidirection channel test plan
> +===================================
> +
> +preparation work
> +================
> +1. Turn on speedstep option in BIOS.
> +2. Turn on CPU C3 and C6.
> +3. Turn on turbo in BIOS.
> +4. Disable intel_pstate in Linux kernel command ``intel_pstate=disable``.
> +5. modprobe msr module to let the application can get the CPU HW info.
> +6. Let user space can control the CPU frequency::
> +
> +    cpupower frequency-set -g userspace
> +
> +7. set a folder::
> +
> +    mkdir /tmp/powermonitor
> +    chmod 777 /tmp/powermonitor
> +
> +
> +Test Case 1 : Check VM can send power policy command to host and get
> +acked
> +=========================================================
> ==============
> +===
> +Step 1. Launch VM using libvirt::
> +
> +    virsh start [VM name]
> +
> +Step 2. Launch VM power manager example on the host to monitor the
> channel from VM::
> +
> +    ./examples/vm_power_manager/build/vm_power_mgr -l 12-14 -n 4 --
> no-pci
> +    vmpower> add_vm [vm name]
> +    vmpower> add_channels [vm name] all
> +    vmpower> set_channel_status [vm name] all enabled
> +    vmpower> show_vm [vm name]
> +
> +    If VM name is ubuntu, the command as following:
> +    vmpower> add_vm ubuntu
> +    vmpower> add_channels ubuntu all
> +    vmpower> set_channel_status ubuntu all enabled
> +    vmpower> show_vm ubuntu
> +
> +Step 3. In the VM, launch guest_vm_power_mgr to set and send the power
> manager policy to the host power example::
> +
> +   ./examples/vm_power_manager/guest_cli/build/guest_vm_power_mgr
> -c
> + 0xff -n 4 -m 1024 --no-pci --file-prefix=vm_power -- --vm-name=ubuntu
> + --vcpu-list=0-7
> +
> +    Send command to the core 7 on host APP:
> +    vmpower(guest)> set_cpu_freq 7 down
> +
> +    Check following info will be returned for the ACK activity, as following:
> +    ACK received for message sent to host.
> +
> +    If command can't be executed, NACK will be returned, as following:
> +    NACK received for message sent to host.
> +
> +Step 4. Set frequency on core which is out of the VM's core scope::
> +
> +    For example, the vcpu range is 0-7, we set command to vcpu number 9 as
> following:
> +    vmpower(guest)> set_cpu_freq 9 down
> +    GUEST_CHANNEL: Channel is not connected
> +    Error sending message: Unknown error -1
> +
> +
> +Test Case 2 : Query Host CPU frequency list from VM
> +===================================================
> +Step 1. Launch VM using libvirt::
> +
> +    virsh start [VM name]
> +
> +Step 2. Launch VM power manager example on the host to monitor the
> channel from VM::
> +
> +    ./examples/vm_power_manager/build/vm_power_mgr -l 12-14 -n 4 --
> no-pci
> +    vmpower> add_vm [vm name]
> +    vmpower> add_channels [vm name] all
> +    vmpower> set_channel_status [vm name] all enabled
> +    vmpower> show_vm [vm name]
> +    vmpower> set_query <vm_name> <enable|disable>
> +
> +Step 3. Enable the query permission for target VM from host
> vm_power_mgr example::
> +
> +    Command format: set_query <vm_name> <enable|disable>
> +    if vm name is ubuntu,command as following:
> +    vmpower> set_query ubuntu enable
> +
> +Step 4. Query the CPU frequency for all CPU cores from VM side::
> +
> +   ./examples/vm_power_manager/guest_cli/build/guest_vm_power_mgr
> -c 0xff -n 4 -m 1024 --no-pci --file-prefix=vm_power -- --vm-name=ubuntu --
> vcpu-list=0-7
> +    vmpower> query_cpu_freq <core_num> | all
> +
> +    Check vcpu 0~7 frequency info will be returned, for example:
> +        Frequency of [0] vcore is 2300000.
> +        Frequency of [1] vcore is 2200000.
> +        Frequency of [2] vcore is 2800000.
> +        Frequency of [3] vcore is 2300000.
> +        Frequency of [4] vcore is 2300000.
> +        Frequency of [5] vcore is 2300000.
> +        Frequency of [6] vcore is 2300000.
> +        Frequency of [7] vcore is 2300000.
> +
> +Step 5. Disable query permission from VM, check the host CPU frequency
> won't be returned::
> +
> +    at host side, disable query permission by vm_power_mgr example:
> +    vmpower> set_query ubuntu disable
> +
> +    at VM side, query CPU frequency again, this action should not be
> executed successfully, log as following:
> +    vmpower(guest)> query_cpu_freq all
> +    GUEST_CLI: Error receiving message.
> +    Error during frequency list reception.
> +
> +
> +Test Case 3: Query CPU capability from VM
> +=========================================
> +Step1~3. The same as test case 2
> +
> +Step4: Query all the valid CPU core capability of host, check all cores'
> information is returned. Check the high priority core is recognized correctly::
> +
> +    For example, core 2 is returned as high priority core:
> +    vmpower(guest)> query_cpu_caps all
> +    Capabilities of [0] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [1] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [2] vcore are: turbo possibility: 1, is priority core: 1.
> +    Capabilities of [3] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [4] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [5] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [6] vcore are: turbo possibility: 1, is priority core: 0.
> +    Capabilities of [7] vcore are: turbo possibility: 1, is priority core: 0.
> +
> +Step 5: Query CPU capability for core out of scope, check no CPU info will be
> return::
> +
> +    For example, the valid vcpu range is 0~7, query cpu capability of core 9
> should return error as following:
> +    vmpower(guest)> query_cpu_caps 9
> +    Invalid parameter provided.
> +
> +Step 6: Disable query permission from VM, check the host CPU capability
> won't be returned::
> +
> +    at host side, disable query permission by vm_power_mgr example:
> +    vmpower> set_query ubuntu disable
> +
> +    at VM side, query CPU capability again, this action should not be executed
> successfully, log as following:
> +    vmpower(guest)> query_cpu_caps all
> +    GUEST_CLI: Error receiving message.
> +    Error during capabilities reception.
> \ No newline at end of file
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan
  2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
                   ` (3 preceding siblings ...)
  2020-01-16  1:56 ` [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan yufengmx
@ 2020-01-16  6:18 ` " Tu, Lijuan
  4 siblings, 0 replies; 10+ messages in thread
From: Tu, Lijuan @ 2020-01-16  6:18 UTC (permalink / raw)
  To: Mo, YufengX, dts, Yao, Lei A; +Cc: Mo, YufengX

Applied the series.

> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of yufengmx
> Sent: Thursday, January 16, 2020 9:56 AM
> To: dts@dpdk.org; Yao, Lei A <lei.a.yao@intel.com>
> Cc: Mo, YufengX <yufengx.mo@intel.com>
> Subject: [dts] [PATCH V2 0/4] power_bidirection_channel: upload
> automation script and test plan
> 
>  upload automation script and test plan
> 
> v2:
>  - remove pf passthrough.
> 
> yufengmx (4):
>   tests/power_bidirection_channel: vm config file
>   tests/power_bidirection_channel: upload automation script
>   test_plans/power_bidirection_channel: add test plan index
>   test_plans/power_bidirection_channel: upload test plan
> 
>  conf/power_bidirection_channel.cfg            |  30 +
>  test_plans/index.rst                          |   1 +
>  .../power_bidirection_channel_test_plan.rst   | 173 +++++
>  tests/TestSuite_power_bidirection_channel.py  | 590 ++++++++++++++++++
>  4 files changed, 794 insertions(+)
>  create mode 100644 conf/power_bidirection_channel.cfg
>  create mode 100644 test_plans/power_bidirection_channel_test_plan.rst
>  create mode 100644 tests/TestSuite_power_bidirection_channel.py
> 
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, back to index

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-16  1:56 [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and test plan yufengmx
2020-01-16  1:56 ` [dts] [PATCH V2 1/4] tests/power_bidirection_channel: vm config file yufengmx
2020-01-16  2:27   ` Yao, Lei A
2020-01-16  1:56 ` [dts] [PATCH V2 2/4] tests/power_bidirection_channel: upload automation script yufengmx
2020-01-16  2:27   ` Yao, Lei A
2020-01-16  1:56 ` [dts] [PATCH V2 3/4] test_plans/power_bidirection_channel: add test plan index yufengmx
2020-01-16  2:28   ` Yao, Lei A
2020-01-16  1:56 ` [dts] [PATCH V2 4/4] test_plans/power_bidirection_channel: upload test plan yufengmx
2020-01-16  2:28   ` Yao, Lei A
2020-01-16  6:18 ` [dts] [PATCH V2 0/4] power_bidirection_channel: upload automation script and " Tu, Lijuan

test suite reviews and discussions

Archives are clonable:
	git clone --mirror http://inbox.dpdk.org/dts/0 dts/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dts dts/ http://inbox.dpdk.org/dts \
		dts@dpdk.org
	public-inbox-index dts


Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dts


AGPL code for this site: git clone https://public-inbox.org/ public-inbox