summaryrefslogtreecommitdiff
path: root/rakelib/tester.rake
diff options
context:
space:
mode:
Diffstat (limited to 'rakelib/tester.rake')
-rw-r--r--rakelib/tester.rake80
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