more explicit, rather than gobbling files, pass code in preload is available (so code does not have to be duplicated) interpret first, so bad mistakes get caught no ssh, just qemu-arm, configure through env
80 lines
2.9 KiB
Ruby
80 lines
2.9 KiB
Ruby
require_relative '../helper'
|
|
|
|
module Mains
|
|
module MainsHelper
|
|
include Preloader
|
|
include ScopeHelper
|
|
|
|
def setup
|
|
@qemu = ENV["qemu-arm"] || "qemu-arm"
|
|
@linker = ENV["arm-linux-gnu-ld"] || "arm-linux-gnu-ld" #on fedora
|
|
@arm = ENV["TEST_ARM"] or ENV["TEST_ALL"]
|
|
#@linker = "arm-linux-gnueabi-ld" # on ubuntu
|
|
# ENV["TEST_ARM"] = "DEBUG"
|
|
end
|
|
|
|
def assert_result( exit_code , stdout , name = nil)
|
|
name = caller_locations.first.label unless name
|
|
input = preload + @input
|
|
code , out = run_interpreter( input , name)
|
|
assert_equal exit_code , code , "interpreter code for #{name}"
|
|
assert_equal stdout , out , "interpreter stdout for #{name}"
|
|
return unless @arm
|
|
code , out = run_arm( input , name)
|
|
assert_equal exit_code , code , "arm code for #{name}"
|
|
assert_equal stdout , out , "arm stdout for #{name}"
|
|
end
|
|
|
|
# runnable_methods is called by minitest to determine which tests to run
|
|
def self.runnable_methods
|
|
all = Dir["test/mains/source/*_*.rb"]
|
|
tests =[]
|
|
return tests unless has_qemu
|
|
all.each do |file_name|
|
|
fullname = file_name.split("/").last.split(".").first
|
|
order , name , stdout , exit_code = fullname.split("_")
|
|
method_name = "test_#{order}_#{name}"
|
|
input = File.read(file_name)
|
|
tests << method_name
|
|
self.send(:define_method, method_name ) do
|
|
out , code = run_code(input , "#{order}_#{name}")
|
|
assert_equal stdout , out , "Wrong stdout #{name}"
|
|
assert_equal exit_code , code.to_s , "Wrong exit code #{name}"
|
|
end
|
|
end
|
|
tests
|
|
end
|
|
|
|
def run_arm(input , name )
|
|
puts "Compiling #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
linker = ::RubyX::RubyXCompiler.new({}).ruby_to_binary( input , :arm )
|
|
writer = Elf::ObjectWriter.new(linker)
|
|
writer.save "mains.o"
|
|
puts "Linking #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
`#{@linker} -N mains.o`
|
|
assert_equal 0 , $?.exitstatus , "Linking #{name} failed #{$?}"
|
|
puts "Running #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
stdout = `#{@qemu} ./a.out`
|
|
exit_code = $?.exitstatus
|
|
puts "Arm #{stdout} #{exit_code}" if ENV["TEST_ARM"] == "DEBUG"
|
|
return exit_code , stdout
|
|
end
|
|
|
|
def run_interpreter(input , name )
|
|
puts "Interpreting #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
compiler = RubyX::RubyXCompiler.new(RubyX.default_test_options)
|
|
linker = compiler.ruby_to_binary(input , :interpreter)
|
|
interpreter = Risc::Interpreter.new(linker)
|
|
interpreter.start_program
|
|
interpreter.tick while(interpreter.instruction)
|
|
saved_in = interpreter.std_reg(:saved_message)
|
|
assert_equal Parfait::Message , interpreter.get_register(saved_in).class
|
|
ret = interpreter.get_register(interpreter.std_reg(:syscall_1))
|
|
puts "Interpret #{interpreter.stdout} #{ret}" if ENV["TEST_ARM"] == "DEBUG"
|
|
return ret , interpreter.stdout
|
|
end
|
|
|
|
end
|
|
|
|
end
|