aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/network_services/helpers/cpu.py
blob: 8cdd829a0dd1289915bca4fd05d8b166f8559650 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# Copyright (c) 2016-2017 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import io


class CpuSysCores(object):

    def __init__(self, connection=""):
        self.core_map = {}
        self.connection = connection

    def _open_cpuinfo(self):
        cpuinfo = io.BytesIO()
        self.connection.get_file_obj("/proc/cpuinfo", cpuinfo)
        lines = cpuinfo.getvalue().decode('utf-8').splitlines()
        return lines

    def _get_core_details(self, lines):
        core_details = []
        core_lines = {}
        for line in lines:
            if line.strip():
                name, value = line.split(":", 1)
                core_lines[name.strip()] = value.strip()
            else:
                core_details.append(core_lines)
                core_lines = {}

        return core_details

    def get_core_socket(self):
        lines = self.connection.execute("lscpu")[1].split(u'\n')
        num_cores = self._get_core_details(lines)
        for num in num_cores:
            self.core_map["cores_per_socket"] = num["Core(s) per socket"]
            self.core_map["thread_per_core"] = num["Thread(s) per core"]

        lines = self._open_cpuinfo()
        core_details = self._get_core_details(lines)
        for core in core_details:
            for k, _ in core.items():
                if k == "physical id":
                    if core["physical id"] not in self.core_map:
                        self.core_map[core['physical id']] = []
                    self.core_map[core['physical id']].append(
                        core["processor"])

        return self.core_map

    def get_cpu_layout(self):
        _, stdout, _ = self.connection.execute("lscpu -p")
        cpuinfo = {}
        cpuinfo['cpuinfo'] = list()
        for line in stdout.split("\n"):
            if line and line[0] != "#":
                cpuinfo['cpuinfo'].append([CpuSysCores._str2int(x) for x in
                                           line.split(",")])
        return cpuinfo

    def validate_cpu_cfg(self, vnf_cfg=None):
        if vnf_cfg is None:
            vnf_cfg = {
                'lb_config': 'SW',
                'lb_count': 1,
                'worker_config': '1C/1T',
                'worker_threads': 1
            }
        if self.core_map["thread_per_core"] == 1 and \
                vnf_cfg["worker_config"] == "1C/2T":
            return -1

        if vnf_cfg['lb_config'] == 'SW':
            num_cpu = int(vnf_cfg["worker_threads"]) + 5
            if int(self.core_map["cores_per_socket"]) < num_cpu:
                return -1

        return 0

    @staticmethod
    def _str2int(string):
        try:
            return int(string)
        except ValueError:
            return 0