Running tests on binary through qemu (system, no ssh)

This commit is contained in:
Torsten Rüger 2019-08-18 12:39:23 +03:00
parent 3fa696b527
commit c9d77a29b2
3 changed files with 28 additions and 58 deletions

View File

@ -1,8 +1,8 @@
before_install: before_install:
- sudo apt-get install -y qemu - sudo apt-get install -y qemu
- sudo apt-get install -y binutils-arm-linux-gnueabi - sudo apt-get install -y binutils-arm-linux-gnueabi
- gem install bundler --version '2.0.1'
language: ruby language: ruby
before_install: gem install bundler --version '2.0.1'
script: script:
- qemu-arm -version - qemu-arm -version
- arm-linux-gnu-ld -v - arm-linux-gnu-ld -v

View File

@ -91,15 +91,14 @@ class RubyXC < Thor
def execute(file) def execute(file)
outfile = compile(file) outfile = compile(file)
system "arm-linux-gnueabihf-ld -N #{outfile}" system "arm-linux-gnueabi-ld -N #{outfile}"
puts "Linked ok, now running #{file}" puts "Linked ok, now running #{file}"
system "qemu-arm ./a.out" system "qemu-arm ./a.out ; echo $?"
end end
private private
def extract_options def extract_options
opt = { factory: options[:parfait] || 1024 } opt = { factory: options[:parfait] || 1024 }
puts opt
return {parfait: opt} return {parfait: opt}
end end

View File

@ -5,21 +5,13 @@ require 'net/scp'
module Mains module Mains
class TestArm < MiniTest::Test class TestArm < MiniTest::Test
DEBUG = true DEBUG = false
def self.user
ENV["ARM_USER"] || "pi"
end
def self.port
ENV["ARM_PORT"] || 2222
end
# runnable_methods is called by minitest to determine which tests to run # runnable_methods is called by minitest to determine which tests to run
def self.runnable_methods def self.runnable_methods
all = Dir["test/mains/source/*_*.rb"] all = Dir["test/mains/source/*_*.rb"]
tests =[] tests =[]
host = ENV["ARM_HOST"] return tests unless has_qemu
return tests unless host
ssh = Net::SSH.start(host, user , port: port )
all.each do |file_name| all.each do |file_name|
fullname = file_name.split("/").last.split(".").first fullname = file_name.split("/").last.split(".").first
name , stdout , exit_code = fullname.split("_") name , stdout , exit_code = fullname.split("_")
@ -27,8 +19,7 @@ module Mains
input = File.read(file_name) input = File.read(file_name)
tests << method_name tests << method_name
self.send(:define_method, method_name ) do self.send(:define_method, method_name ) do
compile( input , name , ssh.scp) out , code = run_code(input , name)
out , code = run_ssh(name , ssh)
assert_equal stdout , out , "Wrong stdout #{name}" assert_equal stdout , out , "Wrong stdout #{name}"
assert_equal exit_code , code.to_s , "Wrong exit code #{name}" assert_equal exit_code , code.to_s , "Wrong exit code #{name}"
end end
@ -36,53 +27,33 @@ module Mains
tests tests
end end
def compile(input , file , scp) def self.has_qemu
Risc.boot! `qemu-arm -version`
puts "Compiling test/#{file}.o" if DEBUG return false unless $?.exitstatus == 0
RubyX::RubyXCompiler.ruby_to_binary( input ) `arm-linux-gnu-ld -v`
writer = Elf::ObjectWriter.new(Risc.machine) return false unless $?.exitstatus == 0
writer.save "test/#{file}.o" true
object_file = "/tmp/#{file}.o"
puts "Copying test/#{file}.o to #{object_file}" if DEBUG
scp.upload! "test/#{file}.o", object_file
end end
def run_ssh( file , ssh) def run_code(input , name )
binary_file = "/tmp/#{file}" puts "Compiling #{name}.o" if DEBUG
object_file = binary_file + ".o"
puts "Linking #{object_file}" if DEBUG linker = ::RubyX::RubyXCompiler.new({}).ruby_to_binary( input , :arm )
stdout , exit_code = ssh_exec!(ssh , "ld -N -o #{binary_file} #{object_file}") writer = Elf::ObjectWriter.new(linker)
assert_equal 0 , exit_code , "Linking #{binary_file} failed"
puts "Running #{binary_file}" if DEBUG writer.save "mains.o"
stdout , exit_code = ssh_exec!(ssh , binary_file)
puts "Linking #{name}" if DEBUG
`arm-linux-gnu-ld -N mains.o`
assert_equal 0 , $?.exitstatus , "Linking #{name} failed #{$?}"
puts "Running #{name}" if DEBUG
stdout = `qemu-arm ./a.out`
exit_code = $?.exitstatus
puts "Result #{stdout} #{exit_code}" if DEBUG puts "Result #{stdout} #{exit_code}" if DEBUG
return stdout , exit_code return stdout , exit_code
end end
def ssh_exec!(ssh, command)
stdout_data = ""
exit_code = nil
ssh.open_channel do |channel|
channel.exec(command) do |ch, success|
unless success
raise "FAILED: couldn't execute command (ssh.channel.exec)"
end
channel.on_data do |c,data|
stdout_data+=data
end
channel.on_extended_data do |c,type,data|
raise "#{ssh} received stderr #{data}"
end
channel.on_request("exit-status") do |c,data|
exit_code = data.read_long
end
channel.on_request("exit-signal") do |c, data|
raise "#{ssh} received signal #{data.read_long}"
end
end
end
ssh.loop
[stdout_data, exit_code]
end
end end
end end