Skip to content

Commit

Permalink
Add keywords and tools for power measurement
Browse files Browse the repository at this point in the history
Signed-off-by: Samuli Leivo <[email protected]>
  • Loading branch information
leivos-unikie committed Dec 4, 2024
1 parent 0e9150e commit de2b0a7
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Robot-Framework/config/variables.robot
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Set Variables
Set Global Variable ${ADMIN_VM} admin-vm
Set Global Variable @{VMS} ${GUI_VM} ${CHROME_VM} ${GALA_VM} ${ZATHURA_VM} ${COMMS_VM} ${BUSINESS_VM} ${ADMIN_VM}

Set Global Variable ${RPI_IP_ADDRESS} ${config['addresses']['measurement_agent']['device_ip_address']}

IF $BUILD_ID != '${EMPTY}'
${config}= Read Config ../config/${BUILD_ID}.json
Set Global Variable ${JOB} ${config['Job']}
Expand Down
48 changes: 48 additions & 0 deletions Robot-Framework/lib/parse_power_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2022-2024 Technology Innovation Institute (TII)
# SPDX-License-Identifier: Apache-2.0

import pandas as pd
import logging
import matplotlib.pyplot as plt


def extract_time_interval(csv_file, start_time, end_time):
columns = ['time', 'power']
data = pd.read_csv(csv_file, names=columns)
interval = data.query("{} < time < {}".format(start_time, end_time))
interval.to_csv('power_interval.csv', index=False)
return

def generate_graph(csv_file, test_name):
data = pd.read_csv(csv_file)
start_time = data['time'].values[0]
end_time = data['time'].values[data.index.max()]
plt.figure(figsize=(20, 10))
plt.set_loglevel('WARNING')

# Show only hh-mm-ss part of the time at x-axis ticks
data['time'] = data['time'].str[11:19]

plt.ticklabel_format(axis='y', style='plain')
plt.plot(data['time'], data['power'], marker='o', linestyle='-', color='b')
plt.yticks(fontsize=14)

# Show full timestamps of the beginning and the end of the plotted time interval
plt.suptitle(f'Device power consumption {start_time} - {end_time}', fontsize=18, fontweight='bold')

plt.title(f'During "{test_name}"', loc='center', fontweight="bold", fontsize=16)
plt.ylabel('Power (mW)', fontsize=16)
plt.grid(True)
plt.xticks(data['time'], rotation=45, fontsize=14)

# Set maximum for tick number
plt.locator_params(axis='x', nbins=40)

plt.savefig(f'../test-suites/power_test.png')
return

def mean_power(csv_file):
columns = ['time', 'power']
data = pd.read_csv(csv_file, names=columns)
mean_value = data['power'].mean()
return mean_value
83 changes: 83 additions & 0 deletions Robot-Framework/resources/power_meas_keywords.resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# SPDX-FileCopyrightText: 2022-2024 Technology Innovation Institute (TII)
# SPDX-License-Identifier: Apache-2.0

*** Settings ***
Resource ../config/variables.robot
Library ../lib/parse_power_data.py
Library SSHLibrary
Library DateTime

*** Variables ***
${ssh_measurement} ${EMPTY}
${start_timestamp} ${EMPTY}


*** Keywords ***

Start power measurement
[Documentation] Connect to the measurement agent and run script to start collecting measurement results
[Arguments] ${id}=power_data ${timeout}=200
Connect to measurement agent
# Multiple logging processes not allowed (for now)
Stop recording power
Start recording power ${id} ${timeout}

Connect to measurement agent
[Documentation] Set up SSH connection to the measurement agent
[Arguments] ${IP}=${RPI_IP_ADDRESS} ${PORT}=22 ${target_output}=ghaf@raspberrypi
Log To Console Connecting to measurement agent
${connection}= Open Connection ${IP} port=${PORT} prompt=\$ timeout=15
${output}= Login username=${LOGIN_PI} password=${PASSWORD_PI}
Should Contain ${output} ${target_output}
Set Global Variable ${ssh_measurement} ${connection}
RETURN ${ssh_measurement}

Start recording power
[Arguments] ${file_name} ${timeout}
Log To Console Starting to record power measurements
Run Keyword And Ignore Error Execute Command nohup python /home/ghaf/ghaf/ghaf-power-measurement/measure_power.py ${file_name}.csv ${timeout} > output.log 2>&1 & timeout=3

Stop recording power
Log To Console Stopping power recording
Run Keyword And Ignore Error Execute Command pkill python timeout=3

Get power record
[Arguments] ${file_name}=power_data.csv
Connect to measurement agent
SSHLibrary.Get File /home/ghaf/ghaf/power_data/${file_name} ../../../power_measurements/

Save power measurement interval
[Documentation] Extract measurement data within given time interval
[Arguments] ${file_name} ${start_time} ${end_time}
Log To Console Extract power data from given time interval
${time_interval} DateTime.Subtract Date From Date ${end_time} ${start_time} exclude_millis=True
IF ${time_interval} < 0
Log To Console Invalid timestamp critera for extracting power data
RETURN
END
Extract time interval ../../../power_measurements/${file_name} ${start_time} ${end_time}

Generate power plot
[Documentation] Extract power data from start_timestamp to current time.
... Plot power vs time and save to png file.
[Arguments] ${id} ${test_name}
${end_timestamp} Get current timestamp
Switch Connection ${ssh_measurement}
Get power record ${id}.csv
Save power measurement interval ${id}.csv '${start_timestamp}' '${end_timestamp}'
Generate graph power_interval.csv ${test_name}
Log <img src="power_test.png" alt="Power plot" width="1200"> HTML

Set start timestamp
${current_time} DateTime.Get Current Date exclude_millis=yes
Set Global Variable ${start_timestamp} ${current_time}
Log To Console ${start_timestamp}

Get current timestamp
${current_time} DateTime.Get Current Date exclude_millis=yes
RETURN ${current_time}

Log average power
[Arguments] ${file_name}
${mean_P} Mean power ${file_name}
# TODO: With the statistics tools of performance testing also average power values could be plotted and monitored
3 changes: 2 additions & 1 deletion Robot-Framework/test-suites/gui-tests/__init__.robot
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Resource ../../resources/ssh_keywords.resource
Resource ../../resources/serial_keywords.resource
Resource ../../resources/gui_keywords.resource
Resource ../../resources/common_keywords.resource
Resource ../../resources/power_meas_keywords.resource
Library ../../lib/gui_testing.py
Suite Setup Common Setup
Suite Teardown Common Teardown
Expand All @@ -21,7 +22,7 @@ Common Setup
IF ${port_22_is_available} == False
FAIL Failed because port 22 of device was not available, tests can not be run.
END
Connect
Connect to ghaf host
IF "Lenovo" in "${DEVICE}"
Verify service status range=15 [email protected] expected_status=active expected_state=running
Connect to netvm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Resource ../../resources/device_control.resource
Resource ../../resources/serial_keywords.resource
Resource ../../config/variables.robot
Resource ../../resources/performance_keywords.resource
Resource ../../resources/power_meas_keywords.resource
Library ../../lib/output_parser.py
Library ../../lib/parse_perfbench.py
Library ../../lib/PerformanceDataProcessing.py ${DEVICE} ${BUILD_ID} ${JOB}
Expand Down Expand Up @@ -351,7 +352,7 @@ Perf-Bench test
Common Setup
Set Variables ${DEVICE}
Run Keyword If "${DEVICE_IP_ADDRESS}" == "NONE" Get ethernet IP address
Connect
Connect to ghaf host

LenovoX1 Setup
[Documentation] Reboot LenovoX1
Expand Down
2 changes: 1 addition & 1 deletion flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit de2b0a7

Please sign in to comment.