From 94e4f3a9bf18b6fdc272dd2a2a95cfb4780f4255 Mon Sep 17 00:00:00 2001 From: Torsten Date: Thu, 26 Mar 2020 20:28:59 +0200 Subject: [PATCH] better framework for running arm test 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 --- test/mains/helper.rb | 75 +++++++++++++++++++++++++++++++++++++++ test/mains/test_assign.rb | 31 ++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 test/mains/test_assign.rb diff --git a/test/mains/helper.rb b/test/mains/helper.rb index bb161258..23136d36 100644 --- a/test/mains/helper.rb +++ b/test/mains/helper.rb @@ -1,4 +1,79 @@ 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 diff --git a/test/mains/test_assign.rb b/test/mains/test_assign.rb new file mode 100644 index 00000000..32408742 --- /dev/null +++ b/test/mains/test_assign.rb @@ -0,0 +1,31 @@ +require_relative "helper" + +module Mains + class AssignTester < MiniTest::Test + include MainsHelper + + def test_local + @input = as_main 'a = 15 ; return a' + assert_result 15 , "" + end + + def test_plus + @preload = "Integer.plus" + @input = as_main("a = 5 + 5 ; return a") + assert_result 10 , "" + end + + def test_plus2 + @preload = "Integer.plus" + @input = as_main("a = 5 ;a = 5 + a ; return a") + assert_result 10 , "" + end + + def test_plus3 + @preload = "Integer.plus" + @input = as_main("a = 5 ;a = 5 + a ;a = a + 5; return a") + assert_result 15 , "" + end + + end +end