Compare commits
6 Commits
29c5beeb7b
...
40afa507a7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40afa507a7 | ||
|
|
18d97d7272 | ||
|
|
c7ed176903 | ||
|
|
911c033eb8 | ||
|
|
a102e2e564 | ||
|
|
3605885994 |
@@ -2,17 +2,20 @@
|
||||
_board_name=$1
|
||||
_mount_dir=$2
|
||||
|
||||
echo "INFO: Stop Servod"
|
||||
stop-servod
|
||||
|
||||
if [ -z "$_board_name" ]; then
|
||||
echo "please enter board namd and mount dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$_mount_dir" ]; then
|
||||
echo "start servod without share folder mounted"
|
||||
echo "please enter mount dir, I usually using the dir /home/${USER}/chrome/ToT/src/scripts"
|
||||
echo "start-servod --channel=release --mount=${_mount_dir}:/tmp/firmware_to_flash -n flashing_servod --board=${_board_name} -p 9999"
|
||||
echo "INFO: start servod without share folder mounted"
|
||||
echo "INFO: please enter mount dir, I usually using the dir /home/${USER}/chrome/ToT/src/scripts"
|
||||
echo "INFO: start-servod --channel=release --mount=${_mount_dir}:/tmp/firmware_to_flash -n flashing_servod --board=${_board_name} -p 9999"
|
||||
start-servod --channel=release --board=${_board_name} -p 9999
|
||||
else
|
||||
echo "start-servod --channel=release --mount=${_mount_dir}:/tmp/firmware_to_flash -n flashing_servod --board=${_board_name} -p 9999"
|
||||
echo "INFO: start-servod --channel=release --mount=${_mount_dir}:/tmp/firmware_to_flash -n flashing_servod --board=${_board_name} -p 9999"
|
||||
start-servod --channel=release --mount=${_mount_dir}:/tmp/firmware_to_flash -n flashing_servod --board=${_board_name} -p 9999
|
||||
fi
|
||||
|
||||
217
stress_test.py
Executable file
217
stress_test.py
Executable file
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import argparse
|
||||
import time
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
def log(message):
|
||||
"""Helper function to log messages with timestamp."""
|
||||
print(f"{datetime.now().strftime('%H:%M:%S')} - {message}")
|
||||
|
||||
|
||||
def run_ssh_command(ip, command, password="test0000", timeout=300, retries=3):
|
||||
"""Execute an SSH command using sshpass with retries and timeout."""
|
||||
ssh_cmd = f'sshpass -p {password} ssh -o StrictHostKeyChecking=no root@{ip} "{command}"'
|
||||
for attempt in range(1, retries + 1):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
ssh_cmd,
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
timeout=timeout
|
||||
)
|
||||
return result.stdout.strip(), result.stderr.strip()
|
||||
except subprocess.TimeoutExpired:
|
||||
log(f"SSH command timed out after {timeout} seconds (attempt {attempt}/{retries}): {command}")
|
||||
if attempt == retries:
|
||||
return None, "Timeout expired"
|
||||
except subprocess.CalledProcessError as e:
|
||||
log(f"SSH command error (attempt {attempt}/{retries}): {e}, stderr: {e.stderr}")
|
||||
if attempt == retries:
|
||||
return None, e.stderr
|
||||
time.sleep(5) # Wait before retrying
|
||||
return None, "Failed after retries"
|
||||
|
||||
def manage_battery_level(ip, check_interval=10):
|
||||
"""Monitor battery level and control charging based on thresholds using ectool chargestate."""
|
||||
log(f"\nManaging battery level for {ip}...")
|
||||
|
||||
while True:
|
||||
# Get battery percentage from ectool chargestate show
|
||||
stdout, stderr = run_ssh_command(ip, "ectool chargestate show | grep 'batt_state_of_charge' | awk '{print $3}'")
|
||||
if stdout and stdout.strip().isdigit():
|
||||
battery_level = int(stdout.strip())
|
||||
log(f"Current battery level: {battery_level}%")
|
||||
|
||||
# Check if battery > 90%
|
||||
if battery_level > 90:
|
||||
log("Battery > 90%, initiating discharge mode...")
|
||||
stdout, stderr = run_ssh_command(ip, "ectool chargecontrol discharge")
|
||||
if stderr:
|
||||
log(f"Failed to set discharge mode: {stderr}")
|
||||
else:
|
||||
log("Discharge mode set successfully")
|
||||
|
||||
# Check if battery <= 30%
|
||||
elif battery_level <= 30:
|
||||
log("Battery <= 30%, switching to normal mode...")
|
||||
stdout, stderr = run_ssh_command(ip, "ectool chargecontrol normal")
|
||||
if stderr:
|
||||
log(f"Failed to set normal mode: {stderr}")
|
||||
else:
|
||||
log("Normal mode set successfully")
|
||||
return # Exit after returning to normal mode
|
||||
|
||||
else:
|
||||
log(f"Battery level {battery_level}% is within acceptable range")
|
||||
|
||||
else:
|
||||
log(f"Failed to retrieve battery level: {stderr}")
|
||||
return # Exit on failure to get battery status
|
||||
|
||||
# Wait before next check
|
||||
time.sleep(check_interval)
|
||||
|
||||
|
||||
def get_system_info(ip):
|
||||
"""Retrieve system information using crossystem and cat /etc/lsb-release."""
|
||||
log(f"\nCollecting system information for {ip}...")
|
||||
|
||||
# Run crossystem
|
||||
log("\n--- crossystem output ---")
|
||||
stdout, stderr = run_ssh_command(ip, "crossystem")
|
||||
if stdout:
|
||||
log(stdout)
|
||||
else:
|
||||
log(f"Failed to retrieve crossystem info: {stderr}")
|
||||
|
||||
# Run cat /etc/lsb-release
|
||||
log("\n--- /etc/lsb-release output ---")
|
||||
stdout, stderr = run_ssh_command(ip, "cat /etc/lsb-release")
|
||||
if stdout:
|
||||
log(stdout)
|
||||
else:
|
||||
log(f"Failed to retrieve /etc/lsb-release: {stderr}")
|
||||
log("\n")
|
||||
|
||||
|
||||
def get_last_eventlog_line(ip):
|
||||
"""Retrieve the last line of /var/log/eventlog.txt."""
|
||||
command = "tail -n 1 /var/log/eventlog.txt"
|
||||
stdout, stderr = run_ssh_command(ip, command)
|
||||
return stdout if stdout else None
|
||||
|
||||
def run_firmware_update(ip, timeout=300):
|
||||
"""Run the firmware update command and check for success."""
|
||||
command = "/usr/local/chromeos-firmwareupdate_joxer_r132 -m factory"
|
||||
log(f"Firmware update command: {command}")
|
||||
stdout, stderr = run_ssh_command(ip, command, timeout=timeout)
|
||||
# log stdout and stderr
|
||||
# log(f"\n--- stdout ---\n{stdout if stdout else 'No stdout'}")
|
||||
# log(f"\n--- stderr ---\n{stderr if stderr else 'No stderr'}")
|
||||
|
||||
if stdout is None:
|
||||
log(f"Firmware update failed: No output received (timeout or error).")
|
||||
return False
|
||||
if "Firmware updater exits successfully" not in stdout:
|
||||
log(f"Firmware update failed: Success message not found. Output: {stdout}, Error: {stderr}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def reboot_device(ip):
|
||||
"""Send reboot command to the device and verify it's back online using ping."""
|
||||
command = "reboot"
|
||||
run_ssh_command(ip, command)
|
||||
log(f"Reboot command sent to {ip}. Waiting for device to restart...")
|
||||
|
||||
max_attempts = 3
|
||||
wait_time = 60 # Total wait time in seconds
|
||||
ping_interval = 5 # Seconds between ping attempts
|
||||
time.sleep(wait_time)
|
||||
|
||||
for attempt in range(1, max_attempts + 1):
|
||||
log(f"Ping attempt {attempt}/{max_attempts}...")
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < wait_time:
|
||||
try:
|
||||
# Attempt to ping the device
|
||||
subprocess.run(
|
||||
f"ping -c 1 {ip}",
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
log(f"Device {ip} is back online.")
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
time.sleep(ping_interval) # Wait before next ping
|
||||
log(f"Ping attempt {attempt} failed.")
|
||||
|
||||
log(f"Device {ip} did not respond to ping after {max_attempts} attempts.")
|
||||
return False
|
||||
|
||||
def main():
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Stress test script for firmware update")
|
||||
parser.add_argument("--remote", required=True, help="IP address of the DUT")
|
||||
parser.add_argument("--loops", type=int, default=30, help="Number of test loops")
|
||||
args = parser.parse_args()
|
||||
|
||||
ip = args.remote
|
||||
loops = args.loops
|
||||
failures = 0
|
||||
get_system_info(ip)
|
||||
|
||||
for i in range(1, loops + 1):
|
||||
log(f"\nStarting loop {i}/{loops}...")
|
||||
|
||||
manage_battery_level(ip)
|
||||
|
||||
# Step 1: Get initial last line of eventlog
|
||||
initial_log = get_last_eventlog_line(ip)
|
||||
if not initial_log:
|
||||
log("Failed to retrieve initial event log. Aborting loop.")
|
||||
failures += 1
|
||||
return
|
||||
log(f"Initial event log line: {initial_log}")
|
||||
|
||||
# Step 2: Run firmware update
|
||||
log("Running firmware update...")
|
||||
if not run_firmware_update(ip):
|
||||
log("Firmware update failed. Aborting loop.")
|
||||
failures += 1
|
||||
return False
|
||||
|
||||
# Step 4: Check if event log changed
|
||||
log("Checking event log before reboot...")
|
||||
time.sleep(10)
|
||||
|
||||
final_log = get_last_eventlog_line(ip)
|
||||
if not final_log:
|
||||
log("Failed to retrieve final event log. Aborting loop.")
|
||||
failures += 1
|
||||
return False
|
||||
log(f"Final event log line: {final_log}")
|
||||
|
||||
if final_log == initial_log:
|
||||
log("Event log did not change after firmware update!")
|
||||
failures += 1
|
||||
else:
|
||||
log(f"Event log updated. New line: {final_log}")
|
||||
return False
|
||||
|
||||
# Step 3: Reboot device
|
||||
if True != reboot_device(ip):
|
||||
return False
|
||||
|
||||
# Summary
|
||||
log(f"\nTest completed. Total loops: {loops}, Failures: {failures}")
|
||||
if failures > 0:
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
92
test.log
Normal file
92
test.log
Normal file
@@ -0,0 +1,92 @@
|
||||
|
||||
Collecting system information for 192.168.50.173...
|
||||
|
||||
--- crossystem output ---
|
||||
arch = x86 # [RO/str] Platform architecture
|
||||
backup_nvram_request = 1 # [RW/int] Backup the nvram somewhere at the next boot. Cleared on success.
|
||||
battery_cutoff_request = 0 # [RW/int] Cut off battery and shutdown on next boot
|
||||
block_devmode = 0 # [RW/int] Block all use of developer mode
|
||||
board_id = 2 # [RO/int] Board hardware revision number
|
||||
clear_tpm_owner_done = 1 # [RW/int] Clear TPM owner done
|
||||
clear_tpm_owner_request = 0 # [RW/int] Clear TPM owner on next boot
|
||||
cros_debug = 1 # [RO/int] OS should allow debug features
|
||||
dbg_reset = 0 # [RW/int] Debug reset mode request
|
||||
debug_build = 1 # [RO/int] OS image built for debug features
|
||||
dev_boot_altfw = 0 # [RW/int] Enable developer mode alternate bootloader
|
||||
dev_boot_signed_only = 0 # [RW/int] Enable developer mode boot only from official kernels
|
||||
dev_boot_usb = 0 # [RW/int] Enable developer mode boot from external disk (USB/SD)
|
||||
dev_default_boot = disk # [RW/str] Default boot from disk, altfw or usb
|
||||
dev_enable_udc = 0 # [RW/int] Enable USB Device Controller
|
||||
devsw_boot = 1 # [RO/int] Developer switch position at boot
|
||||
devsw_cur = 1 # [RO/int] Developer switch current position
|
||||
diagnostic_request = 0 # [RW/int] Request diagnostic rom run on next boot
|
||||
disable_dev_request = 0 # [RW/int] Disable virtual dev-mode on next boot
|
||||
ecfw_act = RW # [RO/str] Active EC firmware
|
||||
post_ec_sync_delay = 0 # [RW/int] Short delay after EC software sync (persistent, writable, eve only)
|
||||
fw_prev_result = unknown # [RO/str] Firmware result of previous boot
|
||||
fw_prev_tried = A # [RO/str] Firmware tried on previous boot (A or B)
|
||||
fw_result = unknown # [RW/str] Firmware result this boot
|
||||
fw_tried = A # [RO/str] Firmware tried this boot (A or B)
|
||||
fw_try_count = 0 # [RW/int] Number of times to try fw_try_next
|
||||
fw_try_next = A # [RW/str] Firmware to try next (A or B)
|
||||
fw_vboot2 = 1 # [RO/int] 1 if firmware was selected by vboot2 or 0 otherwise
|
||||
fwb_tries = 0 # [RW/int] Try firmware B count
|
||||
fwid = Google_Joxer.15217.608.0 # [RO/str] Active firmware ID
|
||||
fwupdate_tries = 0 # [RW/int] Times to try OS firmware update (inside kern_nv)
|
||||
hwid = JOXER TEST 8200 # [RO/str] Hardware ID
|
||||
inside_vm = 0 # [RO/int] Running in a VM?
|
||||
kern_nv = 0x0000 # [RO/int] Non-volatile field for kernel use
|
||||
kernel_max_rollforward = 0xfffffffe # [RW/int] Max kernel version to store into TPM
|
||||
kernkey_vfy = hash # [RO/str] Type of verification done on kernel keyblock
|
||||
loc_idx = 0 # [RW/int] Localization index for firmware screens
|
||||
mainfw_act = A # [RO/str] Active main firmware
|
||||
mainfw_type = developer # [RO/str] Active main firmware type
|
||||
minios_priority = A # [RW/str] miniOS image to try first (A or B)
|
||||
nvram_cleared = 0 # [RW/int] Have NV settings been lost? Write 0 to clear
|
||||
display_request = 0 # [RW/int] Should we initialize the display at boot?
|
||||
phase_enforcement = (error) # [RO/int] Board should have full security settings applied
|
||||
recovery_reason = 0 # [RO/int] Recovery mode reason for current boot
|
||||
recovery_request = 0 # [RW/int] Recovery mode request
|
||||
recovery_subcode = 0 # [RW/int] Recovery reason subcode
|
||||
recoverysw_boot = 0 # [RO/int] Recovery switch position at boot
|
||||
recoverysw_cur = (error) # [RO/int] Recovery switch current position
|
||||
recoverysw_ec_boot = 0 # [RO/int] Recovery switch position at EC boot
|
||||
ro_fwid = Google_Joxer.15217.439.0 # [RO/str] Read-only firmware ID
|
||||
tpm_attack = 0 # [RW/int] TPM was interrupted since this flag was cleared
|
||||
tpm_fwver = 0x00010001 # [RO/int] Firmware version stored in TPM
|
||||
tpm_kernver = 0x00010001 # [RO/int] Kernel version stored in TPM
|
||||
tpm_rebooted = 0 # [RO/int] TPM requesting repeated reboot
|
||||
tried_fwb = 0 # [RO/int] Tried firmware B before A this boot
|
||||
try_ro_sync = 0 # [RO/int] try read only software sync
|
||||
vdat_flags = 0x00008810 # [RO/int] Flags from VbSharedData
|
||||
wipeout_request = 0 # [RW/int] Firmware requested factory reset (wipeout)
|
||||
wpsw_cur = 0 # [RO/int] Firmware write protect hardware switch current position
|
||||
|
||||
--- /etc/lsb-release output ---
|
||||
CHROMEOS_RELEASE_APPID={A5F9E181-D0BE-4D6D-B67D-125069233535}
|
||||
CHROMEOS_BOARD_APPID={A5F9E181-D0BE-4D6D-B67D-125069233535}
|
||||
CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
|
||||
DEVICETYPE=REFERENCE
|
||||
CHROMEOS_RELEASE_NAME=Chrome OS
|
||||
CHROMEOS_AUSERVER=https://tools.google.com/service/update2
|
||||
CHROMEOS_DEVSERVER=
|
||||
CHROMEOS_RELEASE_BUILDER_PATH=factory-nissa-15199.B-nissa/R109-15199.624.0
|
||||
CHROMEOS_RELEASE_KEYSET=devkeys
|
||||
CHROMEOS_RELEASE_TRACK=testimage-channel
|
||||
CHROMEOS_RELEASE_BUILD_TYPE=Official Build
|
||||
CHROMEOS_RELEASE_DESCRIPTION=15199.624.0 (Official Build) dev-channel nissa test
|
||||
CHROMEOS_RELEASE_BOARD=nissa
|
||||
CHROMEOS_RELEASE_BRANCH_NUMBER=624
|
||||
CHROMEOS_RELEASE_BUILD_NUMBER=15199
|
||||
CHROMEOS_RELEASE_CHROME_MILESTONE=109
|
||||
CHROMEOS_RELEASE_PATCH_NUMBER=0
|
||||
CHROMEOS_RELEASE_VERSION=15199.624.0
|
||||
GOOGLE_RELEASE=15199.624.0
|
||||
CHROMEOS_RELEASE_UNIBUILD=1
|
||||
|
||||
|
||||
|
||||
Starting loop 1/100...
|
||||
Initial event log line: 326 | 2025-06-11 00:31:45 | Firmware vboot info | boot_mode=Developer | fw_tried=A | fw_try_count=0 | fw_prev_tried=A | fw_prev_result=Unknown
|
||||
Running firmware update...
|
||||
Firmware update command: /usr/local/chromeos-firmwareupdate_joxer_r132 -m factory
|
||||
@@ -1,47 +1,11 @@
|
||||
tast.firmware.SoftwareSync.dev
|
||||
tast.firmware.DeepSleep
|
||||
tast.firmware.BootMode.rec_to_dev
|
||||
tast.firmware.BootMode.rec_to_dev_gbb
|
||||
tast.firmware.CorruptBothFWSigABAndEC.dev
|
||||
tast.firmware.CorruptBothFWSigABAndEC.normal
|
||||
tast.firmware.CorruptBothFWSigABAndEC.dev
|
||||
tast.firmware.ECADC
|
||||
tast.firmware.ECBattery
|
||||
tast.firmware.ECCbi
|
||||
tast.firmware.ECChargingState.discharge
|
||||
tast.firmware.ECChargingState.full_charge
|
||||
tast.firmware.ECKeyboard.usb_keyboard
|
||||
tast.firmware.ECKeyboard.convertible
|
||||
tast.firmware.ECLaptopMode
|
||||
tast.firmware.ECLidShutdown
|
||||
tast.firmware.ECLidSwitch.check_key_press
|
||||
tast.firmware.ECLidSwitch.open_lid_to_boot
|
||||
tast.firmware.ECLidSwitch.close_lid_to_shutd
|
||||
tast.firmware.ECLidSwitch.open_lid_to_unsusp
|
||||
tast.firmware.ECPowerButton
|
||||
tast.firmware.ECPowerG3.shutdown
|
||||
tast.firmware.ECPowerG3.power_button
|
||||
tast.firmware.ECPowerG3.power_state
|
||||
tast.firmware.ECPowerG3.power_state_usb_plug
|
||||
tast.firmware.ECPowerG3.power_state_snk
|
||||
tast.firmware.ECPowerG3.power_state_rec_off
|
||||
tast.firmware.ECPowerG3.power_button_from_ro
|
||||
tast.firmware.ECReboot
|
||||
tast.firmware.ECSharedMemory
|
||||
tast.firmware.ECSize
|
||||
tast.firmware.ECTabletMode
|
||||
tast.firmware.ECUSBPorts.usb_pins_on_lid_clo
|
||||
tast.firmware.ECUSBPorts.usb_pins_on_shutdow
|
||||
tast.firmware.ECVerifyVK
|
||||
tast.firmware.ECWakeSource.power_btn
|
||||
tast.firmware.ECWakeSource.keypress
|
||||
tast.firmware.ECWakeSource.lid
|
||||
tast.firmware.ECWakeSource.usb_keyboard
|
||||
tast.firmware.ECWatchdog
|
||||
tast.firmware.Eventlog.suspend_resume
|
||||
tast.firmware.Fmap.ec
|
||||
tast.firmware.FWCorruptRecoveryCache.normal
|
||||
tast.firmware.ScreenWakeTabletMode
|
||||
tast.firmware.SoftwareSync.normal
|
||||
tast.firmware.USBResumeFromSuspend
|
||||
tast.firmware.WriteProtect.ec
|
||||
tast.power.SuspendPerf.fw_qual
|
||||
tast.firmware.ECPowerG3.power_state
|
||||
tast.firmware.ServoGBBFlags
|
||||
tast.firmware.WriteProtect.ec
|
||||
tast.firmware.WriteProtect.ec_dev
|
||||
tast.firmware.FwScreenPressPower.invalid_screen
|
||||
tast.firmware.FwmpDevDisableBoot
|
||||
tast.firmware.VerityCorruptRootfs.dev
|
||||
tast.firmware.WriteProtect.ap_dev
|
||||
tast.firmware.WriteProtectCrossystem.dev
|
||||
Reference in New Issue
Block a user