diff options
Diffstat (limited to 'rakelib/tester.rake')
| -rw-r--r-- | rakelib/tester.rake | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/rakelib/tester.rake b/rakelib/tester.rake new file mode 100644 index 0000000..ef05556 --- /dev/null +++ b/rakelib/tester.rake @@ -0,0 +1,80 @@ +require 'open3' +require 'rake/clean' +require_relative 'shared' + +CLEAN.include(TMP + 'riscv') + +LINKER = 'build/rootfs/riscv32-unknown-linux-gnu/bin/ld' + +namespace :test do + test_sources = FileList['tests/vm/*.elna'] + compiler = `cabal list-bin elna`.strip + object_directory = TMP + 'riscv/tests' + root_directory = TMP + 'riscv/root' + executable_directory = root_directory + 'tests' + expectation_directory = root_directory + 'expectations' + init = TMP + 'riscv/root/init' + + directory root_directory + directory object_directory + directory executable_directory + directory expectation_directory + + test_files = test_sources.flat_map do |test_source| + test_basename = File.basename(test_source, '.elna') + test_object = object_directory + test_basename.ext('.o') + + file test_object => [test_source, object_directory] do + sh compiler, '--output', test_object.to_path, test_source + end + test_executable = executable_directory + test_basename + + file test_executable => [test_object, executable_directory] do + sh LINKER, '-o', test_executable.to_path, test_object.to_path + end + expectation_name = test_basename.ext '.txt' + source_expectation = "tests/expectations/#{expectation_name}" + target_expectation = expectation_directory + expectation_name + + file target_expectation => [source_expectation, expectation_directory] do + cp source_expectation, target_expectation + end + + [test_executable, target_expectation] + end + + file init => [root_directory] do |task| + cp (TMP + 'tools/init'), task.name + end + test_files << init << executable_directory << expectation_directory + + file (TMP + 'riscv/root.cpio') => test_files do |task| + root_files = task.prerequisites + .map { |prerequisite| Pathname.new(prerequisite).relative_path_from(root_directory).to_path } + + File.open task.name, 'wb' do |cpio_file| + cpio_options = { + chdir: root_directory.to_path + } + cpio_stream = Open3.popen2 'cpio', '-o', '--format=newc', cpio_options do |stdin, stdout, wait_thread| + stdin.write root_files.join("\n") + stdin.close + stdout.each { |chunk| cpio_file.write chunk } + wait_thread.value + end + end + end + + task :vm => (TMP + 'riscv/root.cpio') do |task| + kernels = FileList.glob(TMP + 'tools/linux-*/arch/riscv/boot/Image') + + sh 'qemu-system-riscv32', + '-nographic', + '-M', 'virt', + '-bios', 'default', + '-kernel', kernels.first, + '-append', 'quiet panic=1', + '-initrd', task.prerequisites.first, + '-no-reboot' + end +end |
