You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.6 KiB
Ruby

# frozen_string_literal: true
# SPDX-License-Identifier: MIT OR Apache-2.0
#
# Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com>
require_relative '../../common/serial/minipush'
require_relative '../../common/tests/boot_test'
require 'pty'
# Match for the last print that 'demo_payload_rpiX.img' produces.
EXPECTED_PRINT = 'Echoing input now'
# Extend BootTest so that it listens on the output of a MiniPush instance, which is itself connected
# to a QEMU instance instead of a real HW.
class ChainbootTest < BootTest
MINIPUSH = '../common/serial/minipush.rb'
MINIPUSH_POWER_TARGET_REQUEST = 'Please power the target now'
def initialize(qemu_cmd, payload_path)
super(qemu_cmd, EXPECTED_PRINT)
@test_name = 'Boot test using Minipush'
@payload_path = payload_path
end
private
# override
def post_process_and_add_output(output)
temp = output.join.split("\r\n")
# Should a line have solo carriage returns, remove any overridden parts of the string.
temp.map! { |x| x.gsub(/.*\r/, '') }
@test_output += temp
end
def wait_for_minipush_power_request(mp_out)
output = []
Timeout.timeout(MAX_WAIT_SECS) do
loop do
output << mp_out.gets
break if output.last.include?(MINIPUSH_POWER_TARGET_REQUEST)
end
end
rescue Timeout::Error
@test_error = 'Timed out waiting for power request'
rescue StandardError => e
@test_error = e.message
ensure
post_process_and_add_output(output)
end
# override
def setup
pty_main, pty_secondary = PTY.open
mp_out, _mp_in = PTY.spawn("ruby #{MINIPUSH} #{pty_secondary.path} #{@payload_path}")
# Wait until MiniPush asks for powering the target.
wait_for_minipush_power_request(mp_out)
# Now is the time to start QEMU with the chainloader binary. QEMU's virtual tty is connected
# to the MiniPush instance spawned above, so that the two processes talk to each other.
Process.spawn(@qemu_cmd, in: pty_main, out: pty_main)
# The remainder of the test is done by the parent class' run_concrete_test, which listens on
# @qemu_serial. Hence, point it to MiniPush's output.
@qemu_serial = mp_out
end
end
##--------------------------------------------------------------------------------------------------
## Execution starts here
##--------------------------------------------------------------------------------------------------
payload_path = ARGV.pop
qemu_cmd = ARGV.join(' ')
ChainbootTest.new(qemu_cmd, payload_path).run