X-Git-Url: http://nitlanguage.org diff --git a/contrib/nitester/src/nitester.nit b/contrib/nitester/src/nitester.nit index 0818e74..fb51b4d 100644 --- a/contrib/nitester/src/nitester.nit +++ b/contrib/nitester/src/nitester.nit @@ -31,6 +31,9 @@ abstract class Processor # Controller rank is always 0 var controller_rank: Rank = 0.rank + # Rank on this processor + fun rank: Rank is abstract + # Where to store data for transfer between nodes # # Require: `buffer.length % 4 == 0` @@ -49,7 +52,7 @@ abstract class Processor # Tag of a new task packet of size `tasks_per_packet` var task_tag: Tag = 0.tag - # Tag to return a set of `Result` throught `buffer` + # Tag to return a set of `Result` thought `buffer` var result_tag: Tag = 1.tag # Tag to notify `Worker` when to quit @@ -67,7 +70,10 @@ abstract class Processor # Run the main logic of this node fun run is abstract - # Engines targetted by this execution + # Hash or name of the branch to test + var branch_hash: String is noinit + + # Engines targeted by this execution var engines: Array[String] is noinit # All known engines, used to detect errors in `engines` @@ -86,6 +92,10 @@ abstract class Processor fun read_cli_options do var opt_ctx = new OptionContext + var opt_hash = new OptionString( + "Branch to test", + "--hash", "-h") + opt_hash.mandatory = true var opt_engines = new OptionString( "Engines to test, separated with commas ({all_engines.join(", ")} or all)", "--engine", "-e") @@ -97,7 +107,7 @@ abstract class Processor "Clean up all nitester files (and do not run tests)", "--cleanup", "-C") - opt_ctx.add_option(opt_engines, opt_help, opt_verbose, opt_cleanup) + opt_ctx.add_option(opt_hash, opt_engines, opt_help, opt_verbose, opt_cleanup) opt_ctx.parse args # --help? @@ -121,7 +131,6 @@ abstract class Processor else full_path.file_delete end - stat.free end mpi.finalize exit 0 @@ -132,6 +141,9 @@ abstract class Processor if rest.is_empty then opt_ctx.usage_error "This tool needs at least one test_program.nit" test_programs = rest + # hash + branch_hash = opt_hash.value.as(not null) + # gather and check engines var engines_str = opt_engines.value var engines @@ -160,12 +172,29 @@ abstract class Processor # All tasks to be performed var tasks = new Array[Task] - # Gather and registar all tasks + # Gather and register all tasks fun create_tasks do - for prog in test_programs do for engine in engines do - tasks.add new Task(engine, prog) + # At this point we are in our local nit + var skip_path = "tests/turing.skip" + var skip + if skip_path.file_exists then + var skip_file = new FileReader.open(skip_path) + skip = skip_file.read_lines + skip_file.close + else + skip = new Array[String] end + + for engine in engines do for prog in test_programs do + # Is is blacklisted? + for s in skip do if not s.is_empty and prog.has(s) then + if verbose > 0 and rank == 0 then print "Skipping test '{prog}' because of '{s}' in turing.skip" + continue label + end + + tasks.add new Task(engine, prog) + end label end end @@ -173,6 +202,8 @@ end class Controller super Processor + redef fun rank do return controller_rank + # Id as `Int` of the next task to distribute var next_task_id = 0 @@ -270,7 +301,7 @@ class Controller mpi.recv_empty(status.source, status.tag, comm_world) at_work.remove(status.source) - if verbose > 1 then print "worker {status.source} is done ({at_work.length} still at work)" + if verbose > 0 then print "Worker {status.source} is done ({at_work.length} still at work)" else print "Unexpected tag {status.tag}" shutdown @@ -326,14 +357,11 @@ class Worker super Processor # The `Rank` of `self` - var rank: Rank + redef var rank: Rank # Compilation directory var comp_dir = "/dev/shm/nit_compile{rank}" is lazy - # Output file directory - var out_dir = "/dev/shm/nit_out{rank}" is lazy - # Directory to store the xml files produced for Jenkins var xml_dir = "~/jenkins_xml/" @@ -341,7 +369,10 @@ class Worker var tests_sh_out = "/dev/shm/nit_local_out{rank}" is lazy # Source Nit repository, must be already updated and `make` before execution - var nit_source_dir = "~/nit" + var local_nit = "/dev/shm/nit{rank}" is lazy + + # Remote Nit repository (actually the local source) + var remote_nit = "~/nit/" # Compiled `Regex` to detect the argument of an execution var re_arg: Regex = "arg [0-9]+".to_re @@ -364,6 +395,25 @@ class Worker fun setup do if verbose > 0 then sys.system "hostname" + + if local_nit.file_exists then local_nit.rmdir + + exec_and_check "git clone {remote_nit} {local_nit}" + local_nit.chdir + exec_and_check "git config remote.origin.fetch +refs/remotes/origin/pr/*:refs/remotes/origin/pr/*" + exec_and_check "git fetch origin --quiet" + exec_and_check "git checkout {branch_hash}" + exec_and_check "cp {remote_nit}/bin/* bin/" + exec_and_check "src/git-gen-version.sh" + end + + private fun exec_and_check(cmd: String) + do + if verbose > 0 then + print "+ {cmd}" + var res = sys.system(cmd) + assert res == 0 else print "Command '{cmd}' failed." + end end # Clean up the testing environment @@ -372,8 +422,8 @@ class Worker fun cleanup do if comp_dir.file_exists then comp_dir.rmdir - if out_dir.file_exists then out_dir.rmdir if tests_sh_out.file_exists then tests_sh_out.file_delete + if local_nit.file_exists then local_nit.file_delete end # Single C `int` to hold the next task id received from the `Controller` @@ -395,23 +445,24 @@ class Worker # Receive tasks to execute mpi.recv_into(task_buffer, 0, 1, status.source, status.tag, comm_world) var first_id = task_buffer[0] - for task_id in [first_id .. first_id + tasks_per_packet] do + for task_id in [first_id .. first_id + tasks_per_packet[ do # If id is over all known tasks, stop right here if task_id >= tasks.length then break var task = tasks[task_id] + "tests".chdir + # Command line to execute test - var cmd = "XMLDIR={xml_dir} ERRLIST={out_dir}/errlist TMPDIR={out_dir} " + + var cmd = "XMLDIR={xml_dir} " + "CCACHE_DIR={ccache_dir} CCACHE_TEMPDIR={ccache_dir} CCACHE_BASEDIR={comp_dir} " + - "./tests.sh --compdir {comp_dir} --outdir {out_dir} " + - " --node --engine {task.engine} {task.test_program} > {tests_sh_out}" + "./tests.sh --node --engine {task.engine} {task.test_program} > {tests_sh_out}" # Execute test sys.system cmd # Test results were written to file, read them - var fstream = new IFStream.open(tests_sh_out) + var fstream = new FileReader.open(tests_sh_out) var content = fstream.read_all fstream.close @@ -466,6 +517,8 @@ class Worker end end + if verbose > 1 then print "Done testing: {task}" + self.results_count = c end @@ -495,7 +548,7 @@ class Worker fun send_results do if results_count > 0 then - if verbose > 1 then print "sending {results_count} results" + if verbose > 2 then print "Sending {results_count} results" mpi.send_from(buffer, 0, results_count*4, controller_rank, result_tag, comm_world) results_count = 0 end