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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
##############################################################################
# Copyright (c) 2019 Lenovo Group Limited Co.,Ltd and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
from __future__ import print_function
from __future__ import absolute_import
import logging
import requests
import json
from yardstick.benchmark.scenarios import base
LOG = logging.getLogger(__name__)
logging.captureWarnings(True)
class Energy(base.Scenario):
"""Get current energy consumption of target host
This scenario sends a REDFISH request to a host BMC
to request current energy consumption.
The response returns a number of Watts.
Usually this is an average of a rolling windows
taken from server internal sensor.
This is dependant of the server provider.
This scenario should be used with node context
As this scenario usually run background with other scenarios,
error of api query or data parse will not terminate task runner.
If any error occured, energy consumption will be set to -1.
Parameters
None
"""
__scenario_type__ = "Energy"
def __init__(self, scenario_cfg, context_cfg):
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
self.target = self.context_cfg['target']
self.setup_done = False
self.get_response = False
def _send_request(self, url):
LOG.info("Send request to %s", url)
pod_auth = (self.target["redfish_user"], self.target["redfish_pwd"])
response = requests.get(url, auth=pod_auth, verify=False)
return response
def setup(self):
url = "https://{}/redfish/v1/".format(self.target["redfish_ip"])
response = self._send_request(url)
if response.status_code != 200:
LOG.info("Don't get right response from %s", url)
self.get_response = False
else:
LOG.info("Get response from %s", url)
self.get_response = True
self.setup_done = True
def load_chassis_list(self):
chassis_list = []
# Get Chassis list
request_url = "https://" + self.target["redfish_ip"]
request_url += "/redfish/v1/Chassis/"
response = self._send_request(request_url)
if response.status_code != 200:
LOG.info("Do not get proper response from %s", request_url)
return chassis_list
try:
chassis_data = json.loads(response.text)
except(TypeError, ValueError) as e:
LOG.info("Invalid response data, %s", e)
return chassis_list
try:
for chassis in chassis_data['Members']:
chassis_list.append(chassis["@odata.id"])
except KeyError as e:
LOG.info("Error data format of chassis data or invalid key.")
return chassis_list
def get_power(self, chassis_uri):
"""Get PowerMetter values from Redfish API."""
if chassis_uri[-1:] != '/':
chassis_uri += '/'
request_url = "https://" + self.target['redfish_ip']
request_url += chassis_uri
request_url += "Power/"
response = self._send_request(request_url)
if response.status_code != 200:
LOG.info("Do not get proper response from %s", request_url)
power = -1
return power
try:
power_metrics = json.loads(response.text)
except(TypeError, ValueError) as e:
LOG.info("Invalid response data, %s", e)
power = -1
return power
try:
power = power_metrics["PowerControl"][0]["PowerConsumedWatts"]
except KeyError as e:
LOG.info("Error data format of power metrics or invalid key.")
power = -1
return power
def run(self, result):
"""execute the benchmark"""
if not self.setup_done:
self.setup()
chassis_list = self.load_chassis_list()
if not self.get_response or not chassis_list:
power = -1
data = {
"power": power,
}
result.update(data)
else:
power = 0
for chassis in chassis_list:
power += self.get_power(chassis)
data = {
"power": power,
}
result.update(data)
|