Commit 9edc5271e6a547a4034df2ed2a5872d6d39c77b4

Vicent Marti 2014-04-03T09:52:42

Merge pull request #2239 from libgit2/vmg/clar-skip-test Skip tests on Clar

diff --git a/tests/blame/simple.c b/tests/blame/simple.c
index 11ff4cd..83e5e05 100644
--- a/tests/blame/simple.c
+++ b/tests/blame/simple.c
@@ -135,13 +135,17 @@ void test_blame_simple__trivial_libgit2(void)
 	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
 	git_object *obj;
 
-	cl_git_pass(git_repository_open(&g_repo, cl_fixture("../..")));
+	/* If we can't open the libgit2 repo or if it isn't a full repo
+	 * with proper history, just skip this test */
+	if (git_repository_open(&g_repo, cl_fixture("../..")) < 0)
+		cl_skip();
 
-	/* This test can't work on a shallow clone */
 	if (git_repository_is_shallow(g_repo))
-		return;
+		cl_skip();
+
+	if (git_revparse_single(&obj, g_repo, "359fc2d") < 0)
+		cl_skip();
 
-	cl_git_pass(git_revparse_single(&obj, g_repo, "359fc2d"));
 	git_oid_cpy(&opts.newest_commit, git_object_id(obj));
 	git_object_free(obj);
 
diff --git a/tests/clar.c b/tests/clar.c
index 2f81a19..1546447 100644
--- a/tests/clar.c
+++ b/tests/clar.c
@@ -109,10 +109,11 @@ static struct {
 	int argc;
 	char **argv;
 
+	enum cl_test_status test_status;
 	const char *active_test;
 	const char *active_suite;
 
-	int suite_errors;
+	int total_skipped;
 	int total_errors;
 
 	int tests_ran;
@@ -150,7 +151,7 @@ struct clar_suite {
 static void clar_print_init(int test_count, int suite_count, const char *suite_names);
 static void clar_print_shutdown(int test_count, int suite_count, int error_count);
 static void clar_print_error(int num, const struct clar_error *error);
-static void clar_print_ontest(const char *test_name, int test_number, int failed);
+static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status failed);
 static void clar_print_onsuite(const char *suite_name, int suite_index);
 static void clar_print_onabort(const char *msg, ...);
 
@@ -186,8 +187,7 @@ clar_run_test(
 	const struct clar_func *initialize,
 	const struct clar_func *cleanup)
 {
-	int error_st = _clar.suite_errors;
-
+	_clar.test_status = CL_TEST_OK;
 	_clar.trampoline_enabled = 1;
 
 	if (setjmp(_clar.trampoline) == 0) {
@@ -211,14 +211,11 @@ clar_run_test(
 	_clar.local_cleanup = NULL;
 	_clar.local_cleanup_payload = NULL;
 
-	if (_clar.report_errors_only)
+	if (_clar.report_errors_only) {
 		clar_report_errors();
-	else
-		clar_print_ontest(
-			test->name,
-			_clar.tests_ran,
-			(_clar.suite_errors > error_st)
-		);
+	} else {
+		clar_print_ontest(test->name, _clar.tests_ran, _clar.test_status);
+	}
 }
 
 static void
@@ -237,7 +234,6 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
 		clar_print_onsuite(suite->name, ++_clar.suites_ran);
 
 	_clar.active_suite = suite->name;
-	_clar.suite_errors = 0;
 
 	if (filter) {
 		size_t suitelen = strlen(suite->name);
@@ -413,6 +409,25 @@ clar_test(int argc, char **argv)
 	return errors;
 }
 
+static void abort_test(void)
+{
+	if (!_clar.trampoline_enabled) {
+		clar_print_onabort(
+				"Fatal error: a cleanup method raised an exception.");
+		clar_report_errors();
+		exit(-1);
+	}
+
+	longjmp(_clar.trampoline, -1);
+}
+
+void clar__skip(void)
+{
+	_clar.test_status = CL_TEST_SKIP;
+	_clar.total_skipped++;
+	abort_test();
+}
+
 void clar__fail(
 	const char *file,
 	int line,
@@ -440,19 +455,11 @@ void clar__fail(
 	if (description != NULL)
 		error->description = strdup(description);
 
-	_clar.suite_errors++;
 	_clar.total_errors++;
+	_clar.test_status = CL_TEST_FAILURE;
 
-	if (should_abort) {
-		if (!_clar.trampoline_enabled) {
-			clar_print_onabort(
-				"Fatal error: a cleanup method raised an exception.");
-			clar_report_errors();
-			exit(-1);
-		}
-
-		longjmp(_clar.trampoline, -1);
-	}
+	if (should_abort)
+		abort_test();
 }
 
 void clar__assert(
diff --git a/tests/clar.h b/tests/clar.h
index 8126305..f9df72e 100644
--- a/tests/clar.h
+++ b/tests/clar.h
@@ -9,6 +9,12 @@
 
 #include <stdlib.h>
 
+enum cl_test_status {
+	CL_TEST_OK,
+	CL_TEST_FAILURE,
+	CL_TEST_SKIP
+};
+
 void clar_test_init(int argc, char *argv[]);
 int clar_test_run(void);
 void clar_test_shutdown(void);
@@ -60,6 +66,8 @@ void cl_fixture_cleanup(const char *fixture_name);
 #define cl_fail(desc) clar__fail(__FILE__, __LINE__, "Test failed.", desc, 1)
 #define cl_warning(desc) clar__fail(__FILE__, __LINE__, "Warning during test execution:", desc, 0)
 
+#define cl_skip() clar__skip()
+
 /**
  * Typed assertion macros
  */
@@ -77,6 +85,7 @@ void cl_fixture_cleanup(const char *fixture_name);
 
 #define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
 
+void clar__skip(void);
 
 void clar__fail(
 	const char *file,
diff --git a/tests/clar/print.h b/tests/clar/print.h
index 368016f..6529b6b 100644
--- a/tests/clar/print.h
+++ b/tests/clar/print.h
@@ -35,11 +35,17 @@ static void clar_print_error(int num, const struct clar_error *error)
 	fflush(stdout);
 }
 
-static void clar_print_ontest(const char *test_name, int test_number, int failed)
+static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status status)
 {
 	(void)test_name;
 	(void)test_number;
-	printf("%c", failed ? 'F' : '.');
+
+	switch(status) {
+	case CL_TEST_OK: printf("."); break;
+	case CL_TEST_FAILURE: printf("F"); break;
+	case CL_TEST_SKIP: printf("S"); break;
+	}
+
 	fflush(stdout);
 }
 
diff --git a/tests/online/clone.c b/tests/online/clone.c
index 9919e8b..6e0e639 100644
--- a/tests/online/clone.c
+++ b/tests/online/clone.c
@@ -200,15 +200,8 @@ void test_online_clone__cred_callback_failure_return_code_is_tunnelled(void)
 	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
 	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
 
-	if (!remote_url) {
-		printf("GITTEST_REMOTE_URL unset; skipping clone test\n");
-		return;
-	}
-
-	if (!remote_user) {
-		printf("GITTEST_REMOTE_USER unset; skipping clone test\n");
-		return;
-	}
+	if (!remote_url || !remote_user)
+		clar__skip();
 
 	g_options.remote_callbacks.credentials = cred_failure_cb;
 
diff --git a/tests/online/push.c b/tests/online/push.c
index 55b97b2..716e2e9 100644
--- a/tests/online/push.c
+++ b/tests/online/push.c
@@ -315,46 +315,47 @@ void test_online_push__initialize(void)
 	_remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT");
 	_remote = NULL;
 
-	if (_remote_url) {
-		cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url));
+	/* Skip the test if we're missing the remote URL */
+	if (!_remote_url)
+		cl_skip();
 
-		record_callbacks_data_clear(&_record_cbs_data);
-		git_remote_set_callbacks(_remote, &_record_cbs);
+	cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url));
 
-		cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
+	record_callbacks_data_clear(&_record_cbs_data);
+	git_remote_set_callbacks(_remote, &_record_cbs);
 
-		/* Clean up previously pushed branches.  Fails if receive.denyDeletes is
-		 * set on the remote.  Also, on Git 1.7.0 and newer, you must run
-		 * 'git config receive.denyDeleteCurrent ignore' in the remote repo in
-		 * order to delete the remote branch pointed to by HEAD (usually master).
-		 * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt
-		 */
-		cl_git_pass(git_remote_ls(&heads, &heads_len, _remote));
-		cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len));
-		if (delete_specs.length) {
-			git_push *push;
+	cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
 
-			cl_git_pass(git_push_new(&push, _remote));
+	/* Clean up previously pushed branches.  Fails if receive.denyDeletes is
+	 * set on the remote.  Also, on Git 1.7.0 and newer, you must run
+	 * 'git config receive.denyDeleteCurrent ignore' in the remote repo in
+	 * order to delete the remote branch pointed to by HEAD (usually master).
+	 * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt
+	 */
+	cl_git_pass(git_remote_ls(&heads, &heads_len, _remote));
+	cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len));
+	if (delete_specs.length) {
+		git_push *push;
 
-			git_vector_foreach(&delete_specs, i, curr_del_spec) {
-				git_push_add_refspec(push, curr_del_spec);
-				git__free(curr_del_spec);
-			}
+		cl_git_pass(git_push_new(&push, _remote));
 
-			cl_git_pass(git_push_finish(push));
-			git_push_free(push);
+		git_vector_foreach(&delete_specs, i, curr_del_spec) {
+			git_push_add_refspec(push, curr_del_spec);
+			git__free(curr_del_spec);
 		}
 
-		git_remote_disconnect(_remote);
-		git_vector_free(&delete_specs);
+		cl_git_pass(git_push_finish(push));
+		git_push_free(push);
+	}
 
-		/* Now that we've deleted everything, fetch from the remote */
-		cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH));
-		cl_git_pass(git_remote_download(_remote));
-		cl_git_pass(git_remote_update_tips(_remote, NULL, NULL));
-		git_remote_disconnect(_remote);
-	} else
-		printf("GITTEST_REMOTE_URL unset; skipping push test\n");
+	git_remote_disconnect(_remote);
+	git_vector_free(&delete_specs);
+
+	/* Now that we've deleted everything, fetch from the remote */
+	cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH));
+	cl_git_pass(git_remote_download(_remote));
+	cl_git_pass(git_remote_update_tips(_remote, NULL, NULL));
+	git_remote_disconnect(_remote);
 }
 
 void test_online_push__cleanup(void)