Index: src/tests/test.py
===================================================================
--- src/tests/test.py	(revision 4e2b97109c2f3a8707de4cdb9e9d0a4fb27b63f1)
+++ src/tests/test.py	(revision ced2e989551f6b3f34df1525410586d86ab208d0)
@@ -2,4 +2,6 @@
 from __future__ import print_function
 
+from functools import partial
+from multiprocessing import Pool
 from os import listdir, environ
 from os.path import isfile, join, splitext
@@ -102,5 +104,5 @@
 #               running test functions
 ################################################################################
-def run_test_instance(test, generate, dry_run):
+def run_single_test(test, generate, dry_run):
 
 	# find the output file based on the test name and options flag
@@ -163,4 +165,32 @@
 	return retcode, error
 
+def run_test_instance(t, generate, dry_run) :
+	# print formated name
+	name_txt = "%20s  " % t.name
+
+	#run the test instance and collect the result
+	test_failed, error = run_single_test(t, generate, dry_run)
+
+	# update output based on current action
+	if generate :
+		failed_txt = "ERROR"
+		success_txt = "Done"
+	else :
+		failed_txt = "FAILED"
+		success_txt = "PASSED"
+
+	#print result with error if needed
+	text = name_txt + (failed_txt if test_failed else success_txt)
+	out = sys.stdout
+	if error :
+		text = text + "\n" + error
+		out = sys.stderr
+
+	print(text, file = out);
+	sys.stdout.flush()
+	sys.stderr.flush()
+
+	return test_failed
+
 # run the given list of tests with the given parameters
 def run_tests(tests, generate, dry_run, jobs) :
@@ -174,40 +204,21 @@
 		print( "Regenerate tests for: " )
 
-	failed = False;
-	# for eeach test to run
-	for t in tests:
-		# print formated name
-		name_txt = "%20s  " % t.name
-
-		#run the test instance and collect the result
-		test_failed, error = run_test_instance(t, generate, dry_run)
-
-		# aggregate test suite result
-		failed = test_failed or failed
-
-		# update output based on current action
-		if generate :
-			failed_txt = "ERROR"
-			success_txt = "Done"
-		else :
-			failed_txt = "FAILED"
-			success_txt = "PASSED"
-
-		#print result with error if needed
-		text = name_txt + (failed_txt if test_failed else success_txt)
-		out = sys.stdout
-		if error :
-			text = text + "\n" + error
-			out = sys.stderr
-
-		print(text, file = out);
-		sys.stdout.flush()
-		sys.stderr.flush()
-
+	# for each test to run
+	pool = Pool(jobs)
+	try :
+		results = pool.map_async(partial(run_test_instance, generate=generate, dry_run=dry_run), tests ).get(99999999)
+	except KeyboardInterrupt:
+		pool.terminate()
+		print("Tests interrupted by user")
+		sys.exit(1)
 
 	#clean the workspace
 	sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
 
-	return 1 if failed else 0
+	for failed in results:
+		if failed :
+			return 1
+
+	return 0
 
 ################################################################################
@@ -279,9 +290,11 @@
 
 # make sure we have a valid number of jobs that corresponds to user input
-options.jobs = int(make_max_jobs) if make_max_jobs else options.jobs
+options.jobs = int(make_max_jobs) if make_max_jobs else (options.jobs if options.jobs else 1)
 if options.jobs <= 0 :
 	print('ERROR: Invalid number of jobs', file=sys.stderr)
 	sys.exit(1)
 
+print('Running on %i cores' % options.jobs)
+
 # users may want to simply list the tests
 if options.list :
