Initial commit: First two meeasurements of sample 8, runs (almost) all stress and eth tests and measures power and ripple.

This commit is contained in:
Pbopbo
2025-11-11 15:10:39 +01:00
commit ca3057157b
76 changed files with 960658 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.venv/

157
measure.py Normal file
View File

@@ -0,0 +1,157 @@
#!/usr/bin/env python3
import pyvisa
import yaml
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
import os
import argparse # For handling command-line arguments
def detach_kernel_tmc(vid, pid):
"""Detach kernel driver for USBTMC devices."""
import usb.core, usb.util
dev = usb.core.find(idVendor=vid, idProduct=pid)
if not dev:
return
try:
for cfg in dev:
for intf in cfg:
if intf.bInterfaceClass == 0xFE: # USBTMC
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
dev.detach_kernel_driver(intf.bInterfaceNumber)
try:
dev.set_configuration()
except Exception:
pass
except Exception:
pass
def load_settings(file_path):
"""Load settings from a YAML file."""
with open(file_path, 'r') as file:
return yaml.safe_load(file)
def configure_oscilloscope(osc, settings):
"""Configure the oscilloscope with the given settings."""
osc.write(f":TIMebase:SCALe {settings['timebase_scale']}")
for channel, config in settings['channels'].items():
osc.write(f":CHANnel{channel}:OFFSet {config['offset']}")
osc.write(f":CHANnel{channel}:SCALe {config['scale']}")
osc.write(":SINGle") # Set to single trigger mode
def fetch_waveform(osc, channel, timebase_scale):
"""Fetch waveform data from a specific channel."""
osc.write(f":WAVeform:SOURce CHANnel{channel}")
osc.write(":WAVeform:FORMat ASCii")
data = osc.query(":WAVeform:DATA?")
if data.startswith('#'):
header_length = int(data[1]) # The second character indicates the header length
data = data[2 + header_length:] # Skip the header
voltage = np.array([float(x) for x in data.split(',')])
time = np.linspace(0, timebase_scale * 10, len(voltage)) # 10 divisions
return time, voltage
def save_waveform_plot(time, voltage, channel, output_dir):
"""Save waveform as a JPG image."""
plt.figure()
plt.plot(time, voltage)
plt.title(f"Channel {channel} Waveform")
plt.xlabel("Time (s)")
plt.ylabel("Voltage (V)")
plt.grid()
file_path = f"{output_dir}/channel{channel}_waveform.jpg"
plt.savefig(file_path)
plt.close()
print(f"Waveform saved as {file_path}")
def save_raw_timeseries(time, voltage, channel, output_dir):
"""Save raw time series data as a CSV file."""
file_path = f"{output_dir}/channel{channel}_timeseries.csv"
data = np.column_stack((time, voltage))
np.savetxt(file_path, data, delimiter=",", header="Time (s),Voltage (V)", comments="")
print(f"Raw time series saved as {file_path}")
def calculate_ripple(data):
"""Calculate the ripple (peak-to-peak voltage)."""
return float(np.ptp(data)) # Convert to plain float
def calculate_average(data):
"""Calculate the average voltage."""
return float(np.mean(data)) # Convert to plain float
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(description="Automated oscilloscope measurement script.")
parser.add_argument("SampleNumber", type=int, help="The sample number for the test.")
parser.add_argument("Supply", type=str, choices=["PoE", "PoELong", "external"], help="The supply type (PoE, PoELong, or external).")
parser.add_argument("TestCase", type=str, choices=["baseline", "CPU", "EthPrim", "EthSec"], help="The test case (baseline, CPU, EthPrim, or EthSec).")
args = parser.parse_args()
# Detach kernel driver if necessary
VID, PID = 0x0957, 0x1798 # Keysight DSOX2014A
detach_kernel_tmc(VID, PID)
# Load settings
settings_file = "settings.yaml"
settings = load_settings(settings_file)
# Ensure timebase_scale is a float
timebase_scale = float(settings['timebase_scale'])
# Create a timestamped subfolder for results
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_dir = os.path.join(settings.get('output_directory', '.'), f"measurement_results_{timestamp}")
os.makedirs(output_dir, exist_ok=True)
# Connect to the oscilloscope
rm = pyvisa.ResourceManager("@py") # Use pyvisa-py backend
resource_string = f"USB0::0x{VID:04x}::0x{PID:04x}::MY59124583::INSTR"
oscilloscope = rm.open_resource(resource_string)
print("Connected to:", oscilloscope.query("*IDN?"))
# Configure the oscilloscope
configure_oscilloscope(oscilloscope, settings)
# Trigger a measurement
oscilloscope.write(":DIGitize")
# Fetch and process data for each channel
results = {
"SampleNumber": args.SampleNumber,
"Supply": args.Supply,
"TestCase": args.TestCase,
"Channels": {}
}
for channel in settings['channels']:
time, voltage = fetch_waveform(oscilloscope, channel, timebase_scale)
save_waveform_plot(time, voltage, channel, output_dir)
save_raw_timeseries(time, voltage, channel, output_dir)
ripple = calculate_ripple(voltage)
average = calculate_average(voltage)
results["Channels"][channel] = {'ripple': ripple, 'average': average}
print(f"Channel {channel}: Ripple = {ripple:.3f} V, Average = {average:.3f} V")
# Save results to a YAML file
results_file = f"{output_dir}/results.yaml"
with open(results_file, 'w') as file:
yaml.dump(results, file)
print(f"Results saved to {results_file}")
# Close the connection
oscilloscope.close()
print("Measurement complete.")
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.145188140703517
ripple: 0.07235999999999976
3:
average: 3.2925820100502508
ripple: 0.04823999999999984
SampleNumber: 8
Supply: external
TestCase: baseline

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.1029829145728645
ripple: 0.06432000000000038
3:
average: 3.293092361809045
ripple: 0.044219999999999704
SampleNumber: 8
Supply: external
TestCase: CPU

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.094936482412059
ripple: 0.07235999999999976
3:
average: 3.2914342713567843
ripple: 0.044219999999999704
SampleNumber: 8
Supply: external
TestCase: EthPrim

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.061786742668567
ripple: 0.3859300000000001
3:
average: 3.2921956783919595
ripple: 0.06834000000000007
SampleNumber: 8
Supply: PoE
TestCase: baseline

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.005816642916072
ripple: 0.45828999999999986
3:
average: 3.291857286432161
ripple: 0.07637999999999989
SampleNumber: 8
Supply: PoE
TestCase: CPU

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.063485833395835
ripple: 0.3618100000000002
3:
average: 3.2923308542713565
ripple: 0.06030000000000024
SampleNumber: 8
Supply: PoE
TestCase: EthPrim

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.156141507537689
ripple: 0.05628000000000011
3:
average: 3.292163618090452
ripple: 0.04823999999999984
SampleNumber: 8
Supply: external
TestCase: baseline

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.088713165829145
ripple: 0.06431999999999949
3:
average: 3.291958492462311
ripple: 0.05628000000000011
SampleNumber: 8
Supply: external
TestCase: CPU

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.081068944723618
ripple: 0.06432000000000038
3:
average: 3.292249346733668
ripple: 0.06432000000000038
SampleNumber: 8
Supply: external
TestCase: EthPrim

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.0519079399484985
ripple: 0.32160999999999973
3:
average: 3.2914292462311554
ripple: 0.06030000000000024
SampleNumber: 8
Supply: PoE
TestCase: baseline

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.007290644516113
ripple: 0.3618100000000002
3:
average: 3.291560703517588
ripple: 0.08040000000000003
SampleNumber: 8
Supply: PoE
TestCase: CPU

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,10 @@
Channels:
2:
average: 5.057190754268857
ripple: 0.3215999999999992
3:
average: 3.2919710552763823
ripple: 0.06432000000000038
SampleNumber: 8
Supply: PoE
TestCase: EthPrim

View File

@@ -0,0 +1,19 @@
Connecting to host 10.11.0.91, port 5201
[ 5] local 10.11.0.70 port 53466 connected to 10.11.0.91 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.8 MBytes 98.8 Mbits/sec 0 105 KBytes
[ 5] 1.00-2.00 sec 11.2 MBytes 94.3 Mbits/sec 0 105 KBytes
[ 5] 2.00-3.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
[ 5] 4.00-5.00 sec 11.3 MBytes 94.9 Mbits/sec 0 113 KBytes
[ 5] 5.00-6.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
[ 5] 6.00-7.00 sec 11.0 MBytes 92.3 Mbits/sec 0 119 KBytes
[ 5] 7.00-8.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
[ 5] 8.00-9.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
[ 5] 9.00-10.00 sec 11.2 MBytes 94.4 Mbits/sec 0 119 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 113 MBytes 94.7 Mbits/sec 0 sender
[ 5] 0.00-10.04 sec 112 MBytes 93.8 Mbits/sec receiver
iperf Done.

View File

@@ -0,0 +1,19 @@
Connecting to host 10.11.0.91, port 5201
[ 5] local 10.11.0.70 port 42388 connected to 10.11.0.91 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.7 MBytes 98.4 Mbits/sec 0 116 KBytes
[ 5] 1.00-2.00 sec 11.2 MBytes 93.8 Mbits/sec 0 116 KBytes
[ 5] 2.00-3.00 sec 11.4 MBytes 95.9 Mbits/sec 0 116 KBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 116 KBytes
[ 5] 4.00-5.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
[ 5] 9.00-10.00 sec 11.4 MBytes 95.9 Mbits/sec 0 120 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 113 MBytes 94.7 Mbits/sec 0 sender
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
iperf Done.

View File

@@ -0,0 +1,24 @@
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 10.11.0.70, port 42376
[ 5] local 10.11.0.91 port 5201 connected to 10.11.0.70 port 42388
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 10.7 MBytes 89.5 Mbits/sec
[ 5] 1.00-2.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 3.00-4.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 4.00-5.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 5.00-6.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 6.00-7.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 7.00-8.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 8.00-9.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 9.00-10.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 10.00-10.05 sec 625 KBytes 94.0 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
iperf3: interrupt - the server has terminated
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

View File

@@ -0,0 +1 @@
stress: info: [1697] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd

View File

@@ -0,0 +1,2 @@
stress: info: [1150] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
stress: info: [1150] successful run completed in 49s

View File

@@ -0,0 +1,19 @@
Connecting to host 10.11.0.91, port 5201
[ 5] local 10.11.0.70 port 57980 connected to 10.11.0.91 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.7 MBytes 97.8 Mbits/sec 0 110 KBytes
[ 5] 1.00-2.00 sec 11.2 MBytes 94.3 Mbits/sec 0 116 KBytes
[ 5] 2.00-3.00 sec 11.2 MBytes 94.4 Mbits/sec 0 116 KBytes
[ 5] 3.00-4.00 sec 11.4 MBytes 95.4 Mbits/sec 0 126 KBytes
[ 5] 4.00-5.00 sec 11.3 MBytes 94.9 Mbits/sec 0 126 KBytes
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
[ 5] 9.00-10.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 113 MBytes 94.6 Mbits/sec 0 sender
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
iperf Done.

View File

@@ -0,0 +1,19 @@
Connecting to host 10.11.0.91, port 5201
[ 5] local 10.11.0.70 port 44400 connected to 10.11.0.91 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.8 MBytes 98.9 Mbits/sec 0 113 KBytes
[ 5] 1.00-2.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
[ 5] 2.00-3.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
[ 5] 4.00-5.00 sec 11.4 MBytes 95.9 Mbits/sec 0 113 KBytes
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
[ 5] 9.00-10.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 113 MBytes 94.5 Mbits/sec 0 sender
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
iperf Done.

View File

@@ -0,0 +1,24 @@
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 10.11.0.70, port 44398
[ 5] local 10.11.0.91 port 5201 connected to 10.11.0.70 port 44400
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 10.7 MBytes 90.1 Mbits/sec
[ 5] 1.00-2.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 3.00-4.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 4.00-5.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 5.00-6.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 6.00-7.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 7.00-8.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 8.00-9.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 9.00-10.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 10.00-10.05 sec 574 KBytes 93.8 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
iperf3: interrupt - the server has terminated
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

View File

@@ -0,0 +1 @@
Now with caps between poe + - and gnd

View File

@@ -0,0 +1 @@
stress: info: [1278] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd

View File

@@ -0,0 +1,2 @@
stress: info: [1196] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
stress: info: [1196] successful run completed in 65s

188
run_tests.py Normal file
View File

@@ -0,0 +1,188 @@
#!/usr/bin/env python3
import subprocess
import time
import paramiko
import os
from datetime import datetime
def ssh_execute_command(host, username, command):
"""Execute a command on a remote host via SSH and capture its output."""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username)
stdin, stdout, stderr = ssh.exec_command(command)
output = stdout.read().decode()
error = stderr.read().decode()
ssh.close()
if error:
raise RuntimeError(f"Error executing command '{command}': {error}")
return output
def ssh_execute_command_no_wait(host, username, command):
"""Execute a command on a remote host via SSH without waiting for completion."""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username)
ssh.exec_command(command)
ssh.close()
def fetch_file_from_dut(host, username, remote_path, local_path):
"""Fetch a file from the DUT to the local machine."""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username)
sftp = ssh.open_sftp()
sftp.get(remote_path, local_path)
sftp.close()
ssh.close()
def run_measurement(sample_number, supply, test_case, output_dir):
"""Run the measure.py script."""
subprocess.run(
["python3", "measure.py", str(sample_number), supply, test_case],
check=True
)
def run_iperf3_server(output_dir):
"""Run iperf3 in server mode on the host and save its log."""
print("Starting iperf3 server on the host...")
log_file = os.path.join(output_dir, "iperf3_server.log")
server_process = subprocess.Popen(
["iperf3", "-s"],
stdout=open(log_file, "w"),
stderr=subprocess.STDOUT
)
time.sleep(2) # Allow the server to start
return server_process
def stop_iperf3_server(server_process):
"""Stop the iperf3 server."""
print("Stopping iperf3 server on the host...")
server_process.terminate()
server_process.wait()
def start_background_command_and_measure(host, username, command, remote_log_file, local_log_file, sample_number, supply, test_case, output_dir):
"""
Start a background command on the DUT, perform the measurement while it's running,
and fetch the log file after the command finishes.
"""
# Start the command in the background and redirect output to a log file on the DUT
nohup_command = f"nohup {command} > {remote_log_file} 2>&1 &"
ssh_execute_command_no_wait(host, username, nohup_command)
print(f"Command '{command}' started on DUT. Log will be saved to {remote_log_file}")
# Wait briefly to ensure the command is running
time.sleep(5)
# Perform the measurement while the command is running
run_measurement(sample_number, supply, test_case, output_dir)
# Wait for the command to finish (optional: adjust this based on the command duration)
time.sleep(5)
# Fetch the log file from the DUT
fetch_file_from_dut(host, username, remote_log_file, local_log_file)
print(f"Log file fetched from DUT: {local_log_file}")
def main():
sample_number = 8
dut_ip = "10.11.0.45" # Replace with the actual DUT IP
host_ip = "10.11.0.91" # Replace with the actual host IP
username = "caster"
# Create a timestamped folder for logs and results
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_dir = os.path.join("results", f"test_{timestamp}")
os.makedirs(output_dir, exist_ok=True)
print("Measuring baseline...")
run_measurement(sample_number, "external", "baseline", output_dir)
print("Running stress test...")
# Run the stress test in the background and measure while it's running
remote_stress_log = "/tmp/stress.log"
local_stress_log = os.path.join(output_dir, "stress.log")
start_background_command_and_measure(
dut_ip,
username,
"stress -c 2 --io 2 --vm 2 --timeout 30",
remote_stress_log,
local_stress_log,
sample_number,
"external",
"CPU",
output_dir
)
print("Running iperf3 test...")
iperf3_server = run_iperf3_server(output_dir) # Start iperf3 server on the host
try:
remote_iperf3_client_log = "/tmp/iperf3_client.log"
local_iperf3_client_log = os.path.join(output_dir, "iperf3_client.log")
start_background_command_and_measure(
dut_ip,
username,
f"iperf3 -c {host_ip}",
remote_iperf3_client_log,
local_iperf3_client_log,
sample_number,
"external",
"EthPrim",
output_dir
)
finally:
stop_iperf3_server(iperf3_server) # Ensure the server is stopped
input("Switch power to PoE and press Enter to continue...")
print("Measuring baseline with PoE...")
run_measurement(sample_number, "PoE", "baseline", output_dir)
print("Running stress test with PoE...")
# Run the stress test in the background and measure while it's running
remote_stress_log_poe = "/tmp/stress_poe.log"
local_stress_log_poe = os.path.join(output_dir, "stress_poe.log")
start_background_command_and_measure(
dut_ip,
username,
"stress -c 2 --io 2 --vm 2 --timeout 15",
remote_stress_log_poe,
local_stress_log_poe,
sample_number,
"PoE",
"CPU",
output_dir
)
print("Running iperf3 test with PoE...")
iperf3_server = run_iperf3_server(output_dir) # Start iperf3 server on the host
try:
remote_iperf3_client_log_poe = "/tmp/iperf3_client_poe.log"
local_iperf3_client_log_poe = os.path.join(output_dir, "iperf3_client_poe.log")
start_background_command_and_measure(
dut_ip,
username,
f"iperf3 -c {host_ip}",
remote_iperf3_client_log_poe,
local_iperf3_client_log_poe,
sample_number,
"PoE",
"EthPrim",
output_dir
)
finally:
stop_iperf3_server(iperf3_server) # Ensure the server is stopped
print("All tests completed.")
if __name__ == "__main__":
main()

9
settings.yaml Normal file
View File

@@ -0,0 +1,9 @@
timebase_scale: 2e-6
channels:
2:
offset: 5.0
scale: 0.2
3:
offset: 3.3
scale: 0.1
output_directory: "./output"

52
test.py Normal file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# connect_dsx2014a_pyvisa.py
import pyvisa
import usb.core, usb.util
VID, PID = 0x0957, 0x1798 # Keysight DSOX2014A
SERIAL = "MY59124583" # from your lsusb/PyUSB output
def detach_kernel_tmc(vid, pid):
dev = usb.core.find(idVendor=vid, idProduct=pid)
if not dev:
return
try:
for cfg in dev:
for intf in cfg:
if intf.bInterfaceClass == 0xFE: # USBTMC
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
dev.detach_kernel_driver(intf.bInterfaceNumber)
try:
dev.set_configuration()
except Exception:
pass
except Exception:
pass
def main():
# If the kernel usbtmc module is bound, libusb can't talk. Detach it:
detach_kernel_tmc(VID, PID)
rm = pyvisa.ResourceManager("@py") # pyvisa-py (libusb) backend
candidates = [
f"USB0::{VID}::{PID}::{SERIAL}::INSTR",
f"USB::{VID}::{PID}::{SERIAL}::INSTR",
f"USB0::0x{VID:04x}::0x{PID:04x}::{SERIAL}::INSTR",
f"USB::0x{VID:04x}::0x{PID:04x}::{SERIAL}::INSTR",
]
for addr in candidates:
try:
inst = rm.open_resource(addr)
inst.timeout = 5000
inst.read_termination = "\n"
inst.write_termination = "\n"
print("Connected:", addr, "->", inst.query("*IDN?").strip())
inst.close()
break
except Exception as e:
print(addr, "->", e)
rm.close()
if __name__ == "__main__":
main()