[vala/wip/valadate: 38/71] Now runs tests in separate processes, including DBus
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/valadate: 38/71] Now runs tests in separate processes, including DBus
- Date: Sun, 19 Nov 2017 11:44:27 +0000 (UTC)
commit 20b1d49fac2a5307f3627daa27ce77ba4d9601ad
Author: chebizarro gmail com <chebizarro gmail com>
Date: Thu Jul 28 22:19:54 2016 -0700
Now runs tests in separate processes, including DBus
tests/Makefile.am | 2 +-
tests/valadatetests.vala | 25 +++-
tests/valatests.vala | 348 ++++++++++++++++++++----------------
valadate/Makefile.am | 2 -
valadate/compositetest.vala | 39 ----
valadate/tap.vala | 379 ---------------------------------------
valadate/tapresult.vala | 39 ----
valadate/testcase.vala | 11 +-
valadate/testconfig.vala | 9 +-
valadate/testexplorer.vala | 11 +-
valadate/testfailure.vala | 33 ----
valadate/testresult.vala | 151 +++++++++-------
valadate/testresultfactory.vala | 59 ------
valadate/testrunner.vala | 92 ++++++++--
valadate/testsuite.vala | 2 +
15 files changed, 404 insertions(+), 798 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0015acb..0bb1890 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,7 @@
include $(top_srcdir)/Makefile.common
include $(top_srcdir)/build-aux/glib-tap.mk
-test_programs = valadatetests #valactests@PACKAGE_SUFFIX@
+test_programs = valadatetests valactests@PACKAGE_SUFFIX@
# Valadate tests
valadatetests_VALAFLAGS = \
diff --git a/tests/valadatetests.vala b/tests/valadatetests.vala
index abaa7bb..d301bdd 100644
--- a/tests/valadatetests.vala
+++ b/tests/valadatetests.vala
@@ -33,10 +33,13 @@ public class Valadate.Tests.TestFixture : Valadate.TestCase {
public void test_testcase_1() {
message("This is a test of the system");
+ //skip("Because it broke");
+ //fail("No particular reason");
}
public void test_testcase_2() {
debug("This is a second test of the system");
+ message(Valadate.get_current_test_path());
skip("No reason");
}
@@ -44,7 +47,27 @@ public class Valadate.Tests.TestFixture : Valadate.TestCase {
//stdout.puts("Before");
//assert(false);
- fail("after");
+ //fail("after");
+
+ void* nullisland = null;
+
+ Object nullobj = nullisland as Object;
+
+ //nullobj.get_type().name();
+
}
}
+
+public class Valadate.Tests.TestFixtureTwo : Valadate.TestCase {
+
+ public void test_testcase() {
+
+ bug_base = "http://bugzilla.gnome.org/";
+
+ bug("555999");
+
+ stdout.puts("This is a test of the system");
+ }
+
+}
diff --git a/tests/valatests.vala b/tests/valatests.vala
index 47edc27..021cfb2 100644
--- a/tests/valatests.vala
+++ b/tests/valatests.vala
@@ -1,34 +1,67 @@
-namespace Vala.Tests {
+/**
+ * Vala.Tests
+ *
+ * Searchs all of the sub directories in the current directory for
+ * *.vala or *.test files, compiles and runs them.
+ *
+ * If the test is a self contained application (has its own main entry
+ * point), it will compile and run it. The test is deemed succesful if
+ * it compiles and runs without error.
+ *
+ * If the test is a collection of {@ref Valadate.TestCase}s then it
+ * compiles the test and runs it. The test results will be appeneded to
+ * the TestFixture's. Not yet implemented.
+ *
+ * If the test is a .test file it will be parsed, the components
+ * assembled, compiled and run. The test is deemed succesful if
+ * it compiles and runs without error.
+ *
+ * The tests can be run against the system compiler or the one in the
+ * source tree. This can be used to verify if a patch or other change
+ * to the compiler either fixes a bug or causes a regression (or both)
+ */
+
+public class Vala.Tests : Valadate.TestSuite {
- /**
- * Vala.Tests.Fixture
- *
- * Searchs all of the sub directories in the current directory for
- * *.vala or *.test files, compiles and runs them.
- *
- * If the test is a self contained application (has its own main entry
- * point), it will compile and run it. The test is deemed succesful if
- * it compiles and runs without error.
- *
- * If the test is a collection of {@ref Valadate.TestCase}s then it
- * compiles the test and runs it. The test results will be appeneded to
- * the TestFixture's. Not yet implemented.
- *
- * If the test is a .test file it will be parsed, the components
- * assembled, compiled and run. The test is deemed succesful if
- * it compiles and runs without error.
- *
- * The tests can be run against the system compiler or the one in the
- * source tree. This can be used to verify if a patch or other change
- * to the compiler either fixes a bug or causes a regression (or both)
- */
-
- public class Fixture : Valadate.TestCase {
-
- private delegate void CommandCallback(Subprocess process, size_t err, string buffer);
+ public Tests() {
+ load_tests();
+ }
+
+ private void load_tests() {
+ try {
+ var testdir = File.new_for_path(GLib.Environment.get_current_dir());
+ var testpath = Valadate.get_current_test_path();
+
+ if (testpath != null) {
+ var testpaths = testpath.split("/");
+ if (testpaths.length < 4)
+ return;
+ var runtest = testdir.get_child(testpaths[3]);
+ if(runtest.query_exists())
+ add_test(new ValaTest(runtest));
+ } else {
+ var tempdir = testdir.get_child(".tests");
+ if(!tempdir.query_exists())
+ tempdir.make_directory();
+
+ var enumerator = testdir.enumerate_children (FileAttribute.STANDARD_NAME, 0);
+ FileInfo file_info;
+ while ((file_info = enumerator.next_file ()) != null)
+ if (file_info.get_file_type() == GLib.FileType.DIRECTORY &&
+ !file_info.get_name().has_prefix("."))
+ add_test(new
ValaTest(testdir.get_child(file_info.get_name())));
+ }
+ } catch (Error e) {
+ stderr.printf ("Error: %s\n", e.message);
+ }
+ }
+
+
+ private class ValaTest : Valadate.TestCase {
+
+ private delegate void CommandCallback(bool err, string buffer);
- private SubprocessLauncher launcher =
- new SubprocessLauncher(GLib.SubprocessFlags.STDOUT_PIPE |
GLib.SubprocessFlags.STDERR_PIPE);
+ private static SubprocessLauncher launcher;
private const string VALA_FLAGS =
"""--main main --save-temps --disable-warnings --pkg gio-2.0
@@ -60,148 +93,139 @@ namespace Vala.Tests {
</repository>""";
private const string BUGZILLA_URL = "http://bugzilla.gnome.org/";
-
- private File testdir;
- private File buildir;
- private File vapidir;
- private File valadatedir;
- private File valac;
- private File vapigen;
- private File tempdir;
-
- private string vapidirs;
-
- public Fixture() {
- load_tests();
+
+ private static File testdir;
+ private static File tempdir;
+ private static File buildir;
+ private static File vapidir;
+ private static File valadatedir;
+ private static File valac;
+ private static File vapigen;
+ private static string vapidirs;
+
+ private File[] testfiles = {};
+
+ class construct {
+ testdir = File.new_for_path(GLib.Environment.get_current_dir());
+ tempdir = testdir.get_child(".tests");
+ buildir = testdir.get_parent();
+ vapidir = buildir.get_child("vapi");
+ valadatedir = buildir.get_child("valadate");
+ valac = buildir.get_child("compiler").get_child("valac");
+ vapigen = buildir.get_child("vapigen").get_child("vapigen");
+ vapidirs = "--vapidir %s".printf(vapidir.get_path());
+ launcher = new SubprocessLauncher(GLib.SubprocessFlags.STDOUT_PIPE |
GLib.SubprocessFlags.STDERR_MERGE);
+ launcher.set_cwd(tempdir.get_path());
}
- ~Fixture() {
- delete_tempdir();
+
+ public override void tear_down() {
+ foreach(var file in testfiles)
+ if(file.query_exists())
+ file.delete();
}
-
- private void load_tests() {
- try {
- testdir = File.new_for_path(GLib.Environment.get_current_dir());
- buildir = testdir.get_parent();
- vapidir = buildir.get_child("vapi");
- valadatedir = buildir.get_child("valadate");
- valac = buildir.get_child("compiler").get_child("valac");
- vapigen = buildir.get_child("vapigen").get_child("vapigen");
- tempdir = testdir.get_child(".tests");
- delete_tempdir();
- tempdir.make_directory();
-
- vapidirs = "--vapidir %s".printf(vapidir.get_path());
-
- launcher.set_cwd(tempdir.get_path());
-
- var enumerator = testdir.enumerate_children (FileAttribute.STANDARD_NAME, 0);
+
+ public ValaTest(File directory) throws Error {
+ this.name = directory.get_basename();
+ this.bug_base = BUGZILLA_URL;
+
+ string current_test = Valadate.get_current_test_path();
+
+ if(current_test != null) {
+ var basename = Path.get_basename(current_test);
+ if (directory.get_child(basename + ".vala").query_exists())
+ load_test(directory.get_child(basename + ".vala"));
+ else if (directory.get_child(basename + ".gs").query_exists())
+ load_test(directory.get_child(basename + ".gs"));
+ else if (directory.get_child(basename + ".test").query_exists())
+ load_test(directory.get_child(basename + ".test"));
+ } else {
+ var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,
0);
FileInfo file_info;
while ((file_info = enumerator.next_file ()) != null) {
- if (file_info.get_file_type() == GLib.FileType.DIRECTORY) {
- var subdir = testdir.get_child(file_info.get_name());
- load_tests_from_dir(subdir);
- }
- }
- } catch (Error e) {
- stderr.printf ("Error: %s\n", e.message);
- }
- }
+ if (file_info.get_file_type() == GLib.FileType.DIRECTORY)
+ continue;
- private void delete_tempdir() throws Error {
- if (tempdir == null || !tempdir.query_exists())
- return;
-
- var enumerator = tempdir.enumerate_children (FileAttribute.STANDARD_NAME, 0);
- FileInfo file_info;
- while ((file_info = enumerator.next_file ()) != null) {
- if (file_info.get_file_type() == GLib.FileType.REGULAR) {
- var file = tempdir.get_child(file_info.get_name());
- file.delete();
+ string fname = file_info.get_name();
+
+ load_test(directory.get_child(fname));
}
}
- tempdir.delete();
}
- private void load_tests_from_dir(File directory) throws Error {
- var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0);
- FileInfo file_info;
- while ((file_info = enumerator.next_file ()) != null) {
- string fname = file_info.get_name();
-
- if (file_info.get_file_type() == GLib.FileType.DIRECTORY) {
- load_tests_from_dir(directory.get_child(fname));
- continue;
- }
+ private void load_test(File testfile) throws Error {
+ string testname = testfile.get_basename().substring(
+ 0,testfile.get_basename().last_index_of("."));
- File testfile = directory.get_child(fname);
- string testname = testfile.get_basename().substring(
- 0,testfile.get_basename().last_index_of("."));
+ string fname = testfile.get_basename();
- if(fname.has_suffix(".vala") || fname.has_suffix(".gs")) {
+ if(fname.has_suffix(".vala") || fname.has_suffix(".gs")) {
+
+ add_test(testname,
+ ()=> {
string binary = testfile.get_basename().substring(
0,testfile.get_basename().last_index_of("."));
- string command = "%s %s %s --library %s -o %s %s".printf(
- valac.get_path(), vapidirs, VALA_FLAGS, binary,
+ string command = "%s %s %s -o %s %s".printf(
+ valac.get_path(), vapidirs, VALA_FLAGS,
binary, testfile.get_path());
- add_test(testname,
- ()=> {
- try {
- if(binary.has_prefix("bug")) {
- Test.bug_base (BUGZILLA_URL);
- Test.bug(binary.substring(3));
- }
- run_command(command);
- if(tempdir.get_child(binary).query_exists())
- run_command("./%s".printf(binary));
- else
- Test.fail();
- } catch (Error e) {
- Test.fail();
- stdout.printf ("%s", e.message);
- }});
- continue;
- }
-
- if(fname.has_suffix(".test")) {
- add_test(testname,
- ()=> {
- try {
- if(fname.has_prefix("bug")) {
- Test.bug_base (BUGZILLA_URL);
- Test.bug(fname.substring(3,fname.length-8));
- }
- parse_test(testfile);
- } catch (Error e) {
- Test.fail();
- stdout.printf ("%s", e.message);
- }});
- }
+ try {
+ if(binary.has_prefix("bug")) {
+ bug_base = BUGZILLA_URL;
+ bug(binary.substring(3));
+ }
+ run_command(command);
+
+ testfiles += tempdir.get_child(binary);
+ testfiles += tempdir.get_child(binary + ".c");
+
+ if(tempdir.get_child(binary).query_exists())
+ run_command("./%s".printf(binary));
+ else
+ fail("Binary not generated");
+ } catch (Error e) {
+ fail(e.message);
+ stdout.printf ("%s", e.message);
+ }});
+ }
+
+ if(fname.has_suffix(".test")) {
+ add_test(testname,
+ ()=> {
+ try {
+ if(fname.has_prefix("bug")) {
+ bug(fname.substring(3,fname.length-8));
+ }
+ parse_test(testfile);
+ } catch (Error e) {
+ fail(e.message);
+ stdout.printf ("%s", e.message);
+ }});
}
}
- private void default_callback(Subprocess process, size_t err, string buffer) {
- if (err > 0) {
- //Test.skip(buffer);
+ private void default_callback(bool err, string buffer) {
+ if (err) {
+ fail(buffer);
+ } else {
stdout.printf ("%s", buffer);
- Test.fail();
- process.force_exit();
}
}
private void run_command(string command, CommandCallback callback = default_callback) throws
Error {
string[] args;
Shell.parse_argv(command, out args);
-
+ string buffer = null;
var process = launcher.spawnv(args);
- var stderr_pipe = process.get_stderr_pipe();
- uint8 buffer[1028];
- var err = stderr_pipe.read(buffer);
-
- callback(process, err, (string)buffer);
+ process.communicate_utf8(null, null, out buffer, null);
+ try {
+ if(process.wait_check())
+ callback(false, buffer);
+ } catch (Error e) {
+ callback(true, buffer);
+ }
}
private void parse_test(File testfile) throws Error {
@@ -223,10 +247,12 @@ namespace Vala.Tests {
case "D-Bus":
var clientfile = tempdir.get_child(testname + ".client.vala");
+ testfiles += clientfile;
var serverfile = tempdir.get_child(testname + ".server.vala");
- var client = clientfile.create(FileCreateFlags.NONE);
+ testfiles += serverfile;
+ var client = clientfile.create(FileCreateFlags.REPLACE_DESTINATION);
var client_stream = new DataOutputStream (client);
- var server = serverfile.create(FileCreateFlags.NONE);
+ var server = serverfile.create(FileCreateFlags.REPLACE_DESTINATION);
var server_stream = new DataOutputStream (server);
do {} while ((line = stream.read_line (null)) != "Program: client");
@@ -254,9 +280,21 @@ namespace Vala.Tests {
string binary = serverfile.get_basename().substring(
0,serverfile.get_basename().last_index_of("."));
- command = "./" + binary;
+ testfiles += tempdir.get_child(binary);
+ testfiles += tempdir.get_child(binary + ".c");
+ testfiles += tempdir.get_child(testname + ".client");
+ testfiles += tempdir.get_child(testname + ".client.c");
- run_command(command);
+ command = "./" + binary;
+
+ Bus.watch_name(
+ BusType.SESSION,
+ "org.example.Test",
+ GLib.BusNameWatcherFlags.NONE,
+ null,
+ (c,n) => {
+ run_command(command);
+ });
break;
@@ -289,7 +327,8 @@ namespace Vala.Tests {
vapi += "\n}\n";
var girfile = tempdir.get_child(testname + ".gir");
- var girstream = girfile.create(FileCreateFlags.NONE);
+ testfiles += girfile;
+ var girstream = girfile.create(FileCreateFlags.REPLACE_DESTINATION);
girstream.write(GIRHEADER.printf(gir).data);
string command = "%s %s %s --library %s %s".printf(
@@ -303,17 +342,19 @@ namespace Vala.Tests {
uint8[] contents;
File file = tempdir.get_child(testname+".vapi");
+ testfiles += file;
file.load_contents (null, out contents, null);
if(strcmp(vapi, (string)contents) != 0)
- Test.fail();
+ fail((string)contents);
break;
case "Invalid Code":
var invalidfile = tempdir.get_child(testname + ".vala");
- var invalid_stream = new DataOutputStream
(invalidfile.create(FileCreateFlags.NONE));
+ testfiles += invalidfile;
+ var invalid_stream = new DataOutputStream
(invalidfile.create(FileCreateFlags.REPLACE_DESTINATION));
while ((line = stream.read_line (null)) != null) {
invalid_stream.put_string(line + "\n");
@@ -325,16 +366,16 @@ namespace Vala.Tests {
VALA_FLAGS,
invalidfile.get_path());
- run_command(command, (p,e,b) => {
- if (e <= 0)
- Test.fail();
+ run_command(command, (e,b) => {
+ if (!e)
+ fail(b);
});
break;
case "TestCase":
var testcasefile = tempdir.get_child(testname + ".vala");
- var testcase = testcasefile.create(FileCreateFlags.NONE);
+ var testcase =
testcasefile.create(FileCreateFlags.REPLACE_DESTINATION);
var testcase_stream = new DataOutputStream (testcase);
testcase_stream.put_string("namespace Vala.Tests {\n");
@@ -368,5 +409,4 @@ namespace Vala.Tests {
}
}
}
-
}
diff --git a/valadate/Makefile.am b/valadate/Makefile.am
index 4b084d0..58393ef 100644
--- a/valadate/Makefile.am
+++ b/valadate/Makefile.am
@@ -8,14 +8,12 @@ lib_LTLIBRARIES = \
libvaladate_la_SOURCES = \
assembly.vala \
module.vala \
- tap.vala \
test.vala \
testcase.vala \
testconfig.vala \
testexplorer.vala \
testfixture.vala \
testresult.vala \
- testfailure.vala \
testrunner.vala \
testsuite.vala \
$(NULL)
diff --git a/valadate/testcase.vala b/valadate/testcase.vala
index 121f0d7..44286f6 100644
--- a/valadate/testcase.vala
+++ b/valadate/testcase.vala
@@ -84,16 +84,17 @@ public abstract class Valadate.TestCase : Object, Test, TestFixture {
public void bug(string reference)
requires(bug_base != null)
{
- stdout.printf("MSG: Bug Reference: %s%s\n",bug_base, reference);
-
+ stdout.printf("MSG: Bug Reference: %s%s",bug_base, reference);
+ stdout.flush();
}
public void skip(string message) {
- stdout.printf("SKIP Skipping Test %s\n", message);
+ stderr.printf("SKIP %s", message);
+ stdout.flush();
}
- public void fail(string message) {
- error("FAIL Test %s\n", message);
+ public void fail(string? message = null) {
+ error("FAIL %s", message ?? "");
}
public virtual void set_up() {}
diff --git a/valadate/testconfig.vala b/valadate/testconfig.vala
index 6fcfaab..d61ac7e 100644
--- a/valadate/testconfig.vala
+++ b/valadate/testconfig.vala
@@ -19,15 +19,20 @@
* Authors:
* Chris Daley <chebizarro gmail com>
*/
+namespace Valadate {
+ public static string? get_current_test_path() {
+ return TestConfig._runtest;
+ }
+}
public class Valadate.TestConfig : Object {
private static string _seed;
private static string testplan;
- private static string _runtest;
+ internal static string _runtest;
private static string format = "tap";
private static bool list;
- private static bool _keepgoing;
+ private static bool _keepgoing = true;
private static bool quiet;
private static bool timed;
private static bool verbose;
diff --git a/valadate/testexplorer.vala b/valadate/testexplorer.vala
index fd34840..21d6d75 100644
--- a/valadate/testexplorer.vala
+++ b/valadate/testexplorer.vala
@@ -25,7 +25,7 @@ internal class Valadate.TestExplorer : Vala.CodeVisitor {
private TestConfig config;
private TestSuite current;
- internal delegate void* Constructor(string? name = null);
+ internal delegate void* Constructor();
internal delegate void TestMethod(TestCase self);
public TestExplorer(TestConfig config) {
@@ -48,9 +48,7 @@ internal class Valadate.TestExplorer : Vala.CodeVisitor {
} catch (ModuleError e) {
error(e.message);
}
-
class.accept_children(this);
-
}
private bool is_subtype_of(Vala.Class class, string typename) {
@@ -81,7 +79,6 @@ internal class Valadate.TestExplorer : Vala.CodeVisitor {
config.runtest != "/" + method.get_full_name().replace(".","/"))
continue;
-
unowned TestMethod testmethod = null;
var attr = new Vala.CCodeAttribute(method);
testmethod = (TestMethod)config.module.get_method(attr.name);
@@ -99,8 +96,10 @@ internal class Valadate.TestExplorer : Vala.CodeVisitor {
public TestSuite visit_testsuite(Vala.Class testclass) throws ModuleError {
unowned Constructor meth = get_constructor(testclass);
- var current_test = meth(testclass.name) as TestSuite;
- current_test.name = testclass.get_full_name();
+ var current_test = meth() as TestSuite;
+ current_test.name = testclass.name;
+ foreach(var test in current_test)
+ config.test_count += test.count;
return current_test;
}
diff --git a/valadate/testresult.vala b/valadate/testresult.vala
index f083816..3e3b62f 100644
--- a/valadate/testresult.vala
+++ b/valadate/testresult.vala
@@ -25,40 +25,33 @@ public class Valadate.TestResult : Object {
NOT_RUN,
RUNNING,
PASSED,
+ SKIPPED,
+ ERROR,
FAILED
}
-
- public signal void test_error(Test test, string error);
- public signal void test_failure(Test test, string error);
- public signal void test_complete(Test test);
- public signal void test_start(Test test);
-
- /*internal List<TestFailure> errors = new List<TestFailure>();
- internal List<TestFailure> failures = new List<TestFailure>();
-
- public bool should_stop {get;set;default=false;}
-
- public int error_count {
- get {
- return (int)errors.length();
- }
- }
+ private class TestReport {
- public int failure_count {
- get {
- return (int)failures.length();
+ public signal void report(TestStatus status);
+
+ public Test test {get;set;}
+
+ public TestStatus status {get;set;}
+
+ public int index {get;set;}
+
+ public string message {get;set;}
+
+ public TestReport(Test test, TestStatus status, int index, string? message = null) {
+ this.test = test;
+ this.status = status;
+ this.index = index;
+ this.message = message;
}
}
- public int run_count {get;private set;default=0;}
-
- public bool success {
- get {
- return (failure_count == 0 && error_count == 0);
- }
- }
- */
+ private Queue<TestReport> reports = new Queue<TestReport>();
+ private HashTable<Test, TestReport> tests = new HashTable<Test, TestReport>(direct_hash,
direct_equal);
public string binary {
get {
@@ -68,61 +61,81 @@ public class Valadate.TestResult : Object {
private TestConfig config;
private TestRunner runner;
+ private MainLoop loop;
- /*
- private HashTable<Test, TestRecord> _tests = new HashTable<Test, TestRecord>(direct_hash,
direct_equal);
-
- private class TestRecord : Object {
-
- public string path {get;set;}
- public int index {get;set;}
- public TestStatus status {get;set;}
-
- public TestRecord(string path, int index, TestStatus status) {
- this.path = path;
- this.index = index;
- this.status = status;
- }
-
- }*/
-
-
public TestResult(TestConfig config) {
this.config = config;
}
+ public void report() {
+ if (reports.is_empty()) {
+ loop.quit();
+ return;
+ }
+ var rpt = reports.peek_head();
+
+ if (rpt.status == TestStatus.PASSED ||
+ rpt.status == TestStatus.SKIPPED ||
+ rpt.status == TestStatus.FAILED ||
+ rpt.status == TestStatus.ERROR) {
+ if (rpt.message != null)
+ stdout.puts(rpt.message);
+ stdout.flush();
+ rpt.report(rpt.status);
+ reports.pop_head();
+ report();
+ }
+ }
+
public void add_error(Test test, string error) {
- stdout.printf("%s\n", error);
- stdout.printf("not ok %d %s\n", testno, test.name);
- //errors.append(new TestFailure(test, error));
- //test_error(test, error);
+ update_test(test, TestStatus.ERROR,"# %s\nnot ok %s %s\n".printf(error, "%d", test.name));
}
public void add_failure(Test test, string failure) {
- stdout.printf("%s\n", failure);
- stdout.printf("not ok %d %s\n", testno, test.name);
- //failures.append(new TestFailure(test, failure));
- //test_failure(test, failure);
+ update_test(test, TestStatus.FAILED,"# %s\nnot ok %s %s\n".printf(failure, "%d", test.name));
}
public void add_success(Test test, string message) {
- stdout.printf("%s\n", message);
- stdout.printf("ok %d %s\n", testno, test.name);
- //failures.append(new TestFailure(test, failure));
- //test_failure(test, failure);
+ update_test(test, TestStatus.PASSED,"# %s\nok %s %s\n".printf(message, "%d", test.name));
+ }
+
+ public void add_skip(Test test, string reason, string message) {
+ update_test(test, TestStatus.SKIPPED,"# %s\nok %s %s # %s\n".printf(message, "%d", test.name,
reason));
}
+ private void update_test(Test test, TestStatus status, string message) {
+ var rept = tests.get(test);
+ rept.status = status;
+ rept.message = message.printf(rept.index);
+ }
/**
- * Runs a {@link Valadate.Test}
+ * Runs a the {@link Valadate.Test}s using the supplied
+ * {@link Valadate.TestRunner}.
+ *
+ * @param runner
*/
public void run(TestRunner runner) {
+
this.runner = runner;
+
if (!config.list_only && config.runtest == null) {
stdout.printf("# random seed: %s\n", config.seed);
stdout.printf("1..%d\n", config.test_count);
}
+
run_test(config.root, "");
+
+ if (config.runtest == null) {
+ loop = new MainLoop();
+ var time = new TimeoutSource (5);
+ time.set_callback (() => {
+ report();
+ return true;
+ });
+ time.attach (loop.get_context ());
+ loop.run();
+ }
}
private int testno = 0;
@@ -131,13 +144,20 @@ public class Valadate.TestResult : Object {
foreach(var subtest in test) {
string testpath = "%s/%s".printf(path, subtest.name);
if(subtest is TestCase) {
- if(config.runtest == null)
- stdout.printf("# Start of %s tests\n", testpath);
- run_test(subtest, testpath);
- if(config.runtest == null)
- stdout.printf("# End of %s tests\n", testpath);
+ if(config.runtest == null) {
+ reports.push_tail(new TestReport(subtest, TestStatus.PASSED,-1,"#
Start of %s tests\n".printf(testpath)));
+ run_test(subtest, testpath);
+ reports.push_tail(new TestReport(subtest, TestStatus.PASSED,-1,"# End
of %s tests\n".printf(testpath)));
+ } else {
+ run_test(subtest, testpath);
+ }
} else if (subtest is TestSuite) {
run_test(subtest, testpath);
+ if(config.runtest == null) {
+ var rpt = new TestReport(subtest, TestStatus.PASSED,-1);
+ rpt.report.connect((s)=> ((TestSuite)subtest).tear_down());
+ reports.push_tail(rpt);
+ }
} else if (config.list_only) {
stdout.printf("%s\n", testpath);
} else if (config.runtest != null) {
@@ -146,7 +166,10 @@ public class Valadate.TestResult : Object {
} else {
testno++;
subtest.name = testpath;
- runner.run(subtest, this);
+ var rept = new TestReport(subtest, TestStatus.RUNNING, testno);
+ reports.push_tail(rept);
+ tests.insert(subtest, rept);
+ runner.run.begin(subtest, this);
}
}
}
diff --git a/valadate/testrunner.vala b/valadate/testrunner.vala
index 25b9947..8ff5363 100644
--- a/valadate/testrunner.vala
+++ b/valadate/testrunner.vala
@@ -22,9 +22,19 @@
public class Valadate.TestRunner : Object {
+ private uint _n_ongoing_tests = 0;
+ private Queue<DelegateWrapper> _pending_tests = new Queue<DelegateWrapper> ();
+
+ /* Change this to change the cap on the number of concurrent operations. */
+ private const uint _max_n_ongoing_tests = 15;
+
+ private class DelegateWrapper {
+ public SourceFunc cb;
+ }
+
private SubprocessLauncher launcher =
new SubprocessLauncher(GLib.SubprocessFlags.STDOUT_PIPE | GLib.SubprocessFlags.STDERR_MERGE);
-
+
private string binary;
public TestRunner(string binary) {
@@ -32,39 +42,93 @@ public class Valadate.TestRunner : Object {
this.launcher.setenv("G_MESSAGES_DEBUG","all", true);
this.launcher.setenv("G_DEBUG","fatal-criticals fatal-warnings gc-friendly", true);
this.launcher.setenv("G_SLICE","always-malloc debug-blocks", true);
+ GLib.set_printerr_handler (printerr_func_stack_trace);
+ Log.set_default_handler (log_func_stack_trace);
}
+
+ private static void printerr_func_stack_trace (string? text) {
+ if (text == null || str_equal (text, ""))
+ return;
+
+ stderr.printf (text);
+
+ /* Print a stack trace since we've hit some major issue */
+ GLib.on_error_stack_trace ("libtool --mode=execute gdb");
+ }
+
+ private void log_func_stack_trace (
+ string? log_domain,
+ LogLevelFlags log_levels,
+ string message) {
+ Log.default_handler (log_domain, log_levels, message);
+
+ /* Print a stack trace for any message at the warning level or above */
+ if ((log_levels & (
+ LogLevelFlags.LEVEL_WARNING |
+ LogLevelFlags.LEVEL_ERROR |
+ LogLevelFlags.LEVEL_CRITICAL)) != 0) {
+ GLib.on_error_stack_trace ("libtool --mode=execute gdb");
+ }
+ }
+
public void run_test(Test test, TestResult result) {
test.run(result);
}
- public void run(Test test, TestResult result) {
+ public async void run(Test test, TestResult result) {
string command = "%s -r %s".printf(binary, test.name);
-
string[] args;
-
string buffer = null;
-
+
+ if (_n_ongoing_tests > _max_n_ongoing_tests) {
+ var wrapper = new DelegateWrapper();
+ wrapper.cb = run.callback;
+ _pending_tests.push_tail((owned)wrapper);
+ yield;
+ }
+
try {
+ _n_ongoing_tests++;
+
Shell.parse_argv(command, out args);
-
var process = launcher.spawnv(args);
- process.communicate_utf8(null, null, out buffer, null);
+ yield process.communicate_utf8_async(null, null, out buffer, null);
- if(process.wait_check()) {
- result.add_success(test, buffer);
- }
+ if(process.wait_check())
+ process_buffer(test, result, buffer);
+
} catch (Error e) {
- result.add_error(test, buffer);
+ process_buffer(test, result, buffer, true);
+ } finally {
+ _n_ongoing_tests--;
+ var wrapper = _pending_tests.pop_head ();
+ if(wrapper != null)
+ wrapper.cb();
}
-
-
}
+ public void process_buffer(Test test, TestResult result, string buffer, bool failed = false) {
+ string skip = null;
+ string[] message = {};
+
+ foreach(string line in buffer.split("\n"))
+ if (line.has_prefix("SKIP "))
+ skip = line;
+ else
+ message += line;
+
+ if (skip != null)
+ result.add_skip(test, skip, string.joinv("\n",message));
+ else
+ if(failed)
+ result.add_failure(test, string.joinv("\n",message));
+ else
+ result.add_success(test, string.joinv("\n",message));
+ }
public static int main (string[] args) {
-
var config = new TestConfig();
int result = config.parse(args);
diff --git a/valadate/testsuite.vala b/valadate/testsuite.vala
index 37ca8b9..0c47872 100644
--- a/valadate/testsuite.vala
+++ b/valadate/testsuite.vala
@@ -73,5 +73,7 @@ public class Valadate.TestSuite : Object, Test {
return _tests.nth_data((uint)index);
}
+ public virtual void set_up() {}
+ public virtual void tear_down() {}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]