Commit 8978f1de by Vicent Marti

Merge branch 'clar2' into development

Conflicts:
	src/pqueue.c
	src/pqueue.h
	src/util.c
	tests-clar/merge/setup.c
parents 686a243a a7ffd936
/tests-clar/clar.h /tests-clar/clar.suite
/tests-clar/clar_main.c /tests-clar/.clarcache
/tests-clar/clar_main.c.rule
/apidocs /apidocs
/trash-*.exe /trash-*.exe
/libgit2.pc /libgit2.pc
......
...@@ -148,7 +148,7 @@ IF (MSVC) ...@@ -148,7 +148,7 @@ IF (MSVC)
# Precompiled headers # Precompiled headers
ELSE () ELSE ()
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes -Wmissing-prototypes ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes ${CMAKE_C_FLAGS}")
IF (MINGW) # MinGW always does PIC and complains if we tell it to IF (MINGW) # MinGW always does PIC and complains if we tell it to
STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
ELSE () ELSE ()
...@@ -233,7 +233,6 @@ INSTALL(FILES include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} ) ...@@ -233,7 +233,6 @@ INSTALL(FILES include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} )
# Tests # Tests
IF (BUILD_CLAR) IF (BUILD_CLAR)
FIND_PACKAGE(PythonInterp REQUIRED) FIND_PACKAGE(PythonInterp REQUIRED)
SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar/resources/") SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar/resources/")
...@@ -243,15 +242,22 @@ IF (BUILD_CLAR) ...@@ -243,15 +242,22 @@ IF (BUILD_CLAR)
ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\") ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\")
INCLUDE_DIRECTORIES(${CLAR_PATH}) INCLUDE_DIRECTORIES(${CLAR_PATH})
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/clar_helpers.c ${CLAR_PATH}/testlib.c) FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c)
SET(SRC_CLAR "${CLAR_PATH}/main.c" "${CLAR_PATH}/clar_libgit2.c" "${CLAR_PATH}/clar.c")
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
OUTPUT ${CLAR_PATH}/clar_main.c ${CLAR_PATH}/clar.h OUTPUT ${CLAR_PATH}/clar.suite
COMMAND ${PYTHON_EXECUTABLE} clar . COMMAND ${PYTHON_EXECUTABLE} generate.py -xonline .
DEPENDS ${CLAR_PATH}/clar ${SRC_TEST} DEPENDS ${SRC_TEST}
WORKING_DIRECTORY ${CLAR_PATH} WORKING_DIRECTORY ${CLAR_PATH}
) )
ADD_EXECUTABLE(libgit2_clar ${SRC_GIT2} ${SRC_OS} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1})
SET_SOURCE_FILES_PROPERTIES(
${CLAR_PATH}/clar.c
PROPERTIES OBJECT_DEPENDS ${CLAR_PATH}/clar.suite)
ADD_EXECUTABLE(libgit2_clar ${SRC_GIT2} ${SRC_OS} ${SRC_CLAR} ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1})
TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES}) TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES})
TARGET_OS_LIBRARIES(libgit2_clar) TARGET_OS_LIBRARIES(libgit2_clar)
MSVC_SPLIT_SOURCES(libgit2_clar) MSVC_SPLIT_SOURCES(libgit2_clar)
...@@ -262,7 +268,7 @@ IF (BUILD_CLAR) ...@@ -262,7 +268,7 @@ IF (BUILD_CLAR)
ENDIF () ENDIF ()
ENABLE_TESTING() ENABLE_TESTING()
ADD_TEST(libgit2_clar libgit2_clar -iall) ADD_TEST(libgit2_clar libgit2_clar)
ENDIF () ENDIF ()
IF (TAGS) IF (TAGS)
......
#include <assert.h>
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
/* required for sandboxing */
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
# include <windows.h>
# include <io.h>
# include <shellapi.h>
# include <direct.h>
# define _MAIN_CC __cdecl
# define stat(path, st) _stat(path, st)
# define mkdir(path, mode) _mkdir(path)
# define chdir(path) _chdir(path)
# define access(path, mode) _access(path, mode)
# define strdup(str) _strdup(str)
# define strcasecmp(a,b) _stricmp(a,b)
# ifndef __MINGW32__
# pragma comment(lib, "shell32")
# define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE)
# define W_OK 02
# define S_ISDIR(x) ((x & _S_IFDIR) != 0)
# define snprint_eq(buf,sz,fmt,a,b) _snprintf_s(buf,sz,_TRUNCATE,fmt,a,b)
# else
# define snprint_eq snprintf
# endif
typedef struct _stat STAT_T;
#else
# include <sys/wait.h> /* waitpid(2) */
# include <unistd.h>
# define _MAIN_CC
# define snprint_eq snprintf
typedef struct stat STAT_T;
#endif
#include "clar.h"
static void fs_rm(const char *_source);
static void fs_copy(const char *_source, const char *dest);
static const char *
fixture_path(const char *base, const char *fixture_name);
struct clar_error {
const char *test;
int test_number;
const char *suite;
const char *file;
int line_number;
const char *error_msg;
char *description;
struct clar_error *next;
};
static struct {
const char *active_test;
const char *active_suite;
int suite_errors;
int total_errors;
int tests_ran;
int suites_ran;
int report_errors_only;
int exit_on_error;
struct clar_error *errors;
struct clar_error *last_error;
void (*local_cleanup)(void *);
void *local_cleanup_payload;
jmp_buf trampoline;
int trampoline_enabled;
} _clar;
struct clar_func {
const char *name;
void (*ptr)(void);
};
struct clar_suite {
const char *name;
struct clar_func initialize;
struct clar_func cleanup;
const struct clar_func *tests;
size_t test_count;
int enabled;
};
/* From clar_print_*.c */
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_onsuite(const char *suite_name, int suite_index);
static void clar_print_onabort(const char *msg, ...);
/* From clar_sandbox.c */
static void clar_unsandbox(void);
static int clar_sandbox(void);
/* Load the declarations for the test suite */
#include "clar.suite"
/* Core test functions */
static void
clar_report_errors(void)
{
int i = 1;
struct clar_error *error, *next;
error = _clar.errors;
while (error != NULL) {
next = error->next;
clar_print_error(i++, error);
free(error->description);
free(error);
error = next;
}
_clar.errors = _clar.last_error = NULL;
}
static void
clar_run_test(
const struct clar_func *test,
const struct clar_func *initialize,
const struct clar_func *cleanup)
{
int error_st = _clar.suite_errors;
_clar.trampoline_enabled = 1;
if (setjmp(_clar.trampoline) == 0) {
if (initialize->ptr != NULL)
initialize->ptr();
test->ptr();
}
_clar.trampoline_enabled = 0;
if (_clar.local_cleanup != NULL)
_clar.local_cleanup(_clar.local_cleanup_payload);
if (cleanup->ptr != NULL)
cleanup->ptr();
_clar.tests_ran++;
/* remove any local-set cleanup methods */
_clar.local_cleanup = NULL;
_clar.local_cleanup_payload = NULL;
if (_clar.report_errors_only)
clar_report_errors();
else
clar_print_ontest(
test->name,
_clar.tests_ran,
(_clar.suite_errors > error_st)
);
}
static void
clar_run_suite(const struct clar_suite *suite)
{
const struct clar_func *test = suite->tests;
size_t i;
if (!suite->enabled)
return;
if (_clar.exit_on_error && _clar.total_errors)
return;
if (!_clar.report_errors_only)
clar_print_onsuite(suite->name, ++_clar.suites_ran);
_clar.active_suite = suite->name;
_clar.suite_errors = 0;
for (i = 0; i < suite->test_count; ++i) {
_clar.active_test = test[i].name;
clar_run_test(&test[i], &suite->initialize, &suite->cleanup);
if (_clar.exit_on_error && _clar.total_errors)
return;
}
}
static void
clar_usage(const char *arg)
{
printf("Usage: %s [options]\n\n", arg);
printf("Options:\n");
printf(" -sname\t\tRun only the suite with `name`\n");
printf(" -iname\t\tInclude the suite with `name`\n");
printf(" -xname\t\tExclude the suite with `name`\n");
printf(" -q \t\tOnly report tests that had an error\n");
printf(" -Q \t\tQuit as soon as a test fails\n");
printf(" -l \t\tPrint suite names\n");
exit(-1);
}
static void
clar_parse_args(int argc, char **argv)
{
int i;
for (i = 1; i < argc; ++i) {
char *argument = argv[i];
if (argument[0] != '-')
clar_usage(argv[0]);
switch (argument[1]) {
case 's':
case 'i':
case 'x': { /* given suite name */
int offset = (argument[2] == '=') ? 3 : 2;
char action = argument[1];
size_t j, len;
argument += offset;
len = strlen(argument);
if (len == 0)
clar_usage(argv[0]);
for (j = 0; j < _clar_suite_count; ++j) {
if (strncmp(argument, _clar_suites[j].name, len) == 0) {
switch (action) {
case 's': clar_run_suite(&_clar_suites[j]); break;
case 'i': _clar_suites[j].enabled = 1; break;
case 'x': _clar_suites[j].enabled = 0; break;
}
break;
}
}
if (j == _clar_suite_count) {
clar_print_onabort("No suite matching '%s' found.\n", argument);
exit(-1);
}
break;
}
case 'q':
_clar.report_errors_only = 1;
break;
case 'Q':
_clar.exit_on_error = 1;
break;
case 'l': {
size_t j;
printf("Test suites (use -s<name> to run just one):\n");
for (j = 0; j < _clar_suite_count; ++j)
printf(" %3d: %s\n", (int)j, _clar_suites[j].name);
exit(0);
}
default:
clar_usage(argv[0]);
}
}
}
int
clar_test(int argc, char **argv)
{
clar_print_init(
(int)_clar_callback_count,
(int)_clar_suite_count,
""
);
if (clar_sandbox() < 0) {
clar_print_onabort("Failed to sandbox the test runner.\n");
exit(-1);
}
if (argc > 1)
clar_parse_args(argc, argv);
if (!_clar.suites_ran) {
size_t i;
for (i = 0; i < _clar_suite_count; ++i)
clar_run_suite(&_clar_suites[i]);
}
clar_print_shutdown(
_clar.tests_ran,
(int)_clar_suite_count,
_clar.total_errors
);
clar_unsandbox();
return _clar.total_errors;
}
void
clar__assert(
int condition,
const char *file,
int line,
const char *error_msg,
const char *description,
int should_abort)
{
struct clar_error *error;
if (condition)
return;
error = calloc(1, sizeof(struct clar_error));
if (_clar.errors == NULL)
_clar.errors = error;
if (_clar.last_error != NULL)
_clar.last_error->next = error;
_clar.last_error = error;
error->test = _clar.active_test;
error->test_number = _clar.tests_ran;
error->suite = _clar.active_suite;
error->file = file;
error->line_number = line;
error->error_msg = error_msg;
if (description != NULL)
error->description = strdup(description);
_clar.suite_errors++;
_clar.total_errors++;
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);
}
}
void clar__assert_equal_s(
const char *s1,
const char *s2,
const char *file,
int line,
const char *err,
int should_abort)
{
int match = (s1 == NULL || s2 == NULL) ? (s1 == s2) : (strcmp(s1, s2) == 0);
if (!match) {
char buf[4096];
snprint_eq(buf, 4096, "'%s' != '%s'", s1, s2);
clar__assert(0, file, line, err, buf, should_abort);
}
}
void clar__assert_equal_i(
int i1,
int i2,
const char *file,
int line,
const char *err,
int should_abort)
{
if (i1 != i2) {
char buf[128];
snprint_eq(buf, 128, "%d != %d", i1, i2);
clar__assert(0, file, line, err, buf, should_abort);
}
}
void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
{
_clar.local_cleanup = cleanup;
_clar.local_cleanup_payload = opaque;
}
#include "clar/sandbox.h"
#include "clar/fixtures.h"
#include "clar/fs.h"
#include "clar/print.h"
#ifndef __CLAR_TEST_H__
#define __CLAR_TEST_H__
#include <stdlib.h>
int clar_test(int argc, char *argv[]);
void cl_set_cleanup(void (*cleanup)(void *), void *opaque);
void cl_fs_cleanup(void);
#ifdef CLAR_FIXTURE_PATH
const char *cl_fixture(const char *fixture_name);
void cl_fixture_sandbox(const char *fixture_name);
void cl_fixture_cleanup(const char *fixture_name);
#endif
/**
* Assertion macros with explicit error message
*/
#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 1)
#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 1)
/**
* Check macros with explicit error message
*/
#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 0)
#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 0)
/**
* Assertion macros with no error message
*/
#define cl_must_pass(expr) cl_must_pass_(expr, NULL)
#define cl_must_fail(expr) cl_must_fail_(expr, NULL)
#define cl_assert(expr) cl_assert_(expr, NULL)
/**
* Check macros with no error message
*/
#define cl_check_pass(expr) cl_check_pass_(expr, NULL)
#define cl_check_fail(expr) cl_check_fail_(expr, NULL)
#define cl_check(expr) cl_check_(expr, NULL)
/**
* Forced failure/warning
*/
#define cl_fail(desc) clar__assert(0, __FILE__, __LINE__, "Test failed.", desc, 1)
#define cl_warning(desc) clar__assert(0, __FILE__, __LINE__, "Warning during test execution:", desc, 0)
/**
* Typed assertion macros
*/
#define cl_assert_equal_s(s1,s2) clar__assert_equal_s((s1),(s2),__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2, 1)
#define cl_assert_equal_i(i1,i2) clar__assert_equal_i((i1),(i2),__FILE__,__LINE__,#i1 " != " #i2, 1)
#define cl_assert_equal_b(b1,b2) clar__assert_equal_i(!!(b1),!!(b2),__FILE__,__LINE__,#b1 " != " #b2, 1)
#define cl_assert_equal_p(p1,p2) cl_assert((p1) == (p2))
void clar__assert(
int condition,
const char *file,
int line,
const char *error,
const char *description,
int should_abort);
void clar__assert_equal_s(const char *,const char *,const char *,int,const char *,int);
void clar__assert_equal_i(int,int,const char *,int,const char *,int);
#endif
static const char *
fixture_path(const char *base, const char *fixture_name)
{
static char _path[4096];
size_t root_len;
root_len = strlen(base);
strncpy(_path, base, sizeof(_path));
if (_path[root_len - 1] != '/')
_path[root_len++] = '/';
if (fixture_name[0] == '/')
fixture_name++;
strncpy(_path + root_len,
fixture_name,
sizeof(_path) - root_len);
return _path;
}
#ifdef CLAR_FIXTURE_PATH
const char *cl_fixture(const char *fixture_name)
{
return fixture_path(CLAR_FIXTURE_PATH, fixture_name);
}
void cl_fixture_sandbox(const char *fixture_name)
{
fs_copy(cl_fixture(fixture_name), _clar_path);
}
void cl_fixture_cleanup(const char *fixture_name)
{
fs_rm(fixture_path(_clar_path, fixture_name));
}
#endif
#ifdef _WIN32
#define RM_RETRY_COUNT 5
#define RM_RETRY_DELAY 10
#ifdef __MINGW32__
/* These security-enhanced functions are not available
* in MinGW, so just use the vanilla ones */
#define wcscpy_s(a, b, c) wcscpy((a), (c))
#define wcscat_s(a, b, c) wcscat((a), (c))
#endif /* __MINGW32__ */
static int
fs__dotordotdot(WCHAR *_tocheck)
{
return _tocheck[0] == '.' &&
(_tocheck[1] == '\0' ||
(_tocheck[1] == '.' && _tocheck[2] == '\0'));
}
static int
fs_rmdir_rmdir(WCHAR *_wpath)
{
unsigned retries = 1;
while (!RemoveDirectoryW(_wpath)) {
/* Only retry when we have retries remaining, and the
* error was ERROR_DIR_NOT_EMPTY. */
if (retries++ > RM_RETRY_COUNT ||
ERROR_DIR_NOT_EMPTY != GetLastError())
return -1;
/* Give whatever has a handle to a child item some time
* to release it before trying again */
Sleep(RM_RETRY_DELAY * retries * retries);
}
return 0;
}
static void
fs_rmdir_helper(WCHAR *_wsource)
{
WCHAR buffer[MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
int buffer_prefix_len;
/* Set up the buffer and capture the length */
wcscpy_s(buffer, MAX_PATH, _wsource);
wcscat_s(buffer, MAX_PATH, L"\\");
buffer_prefix_len = wcslen(buffer);
/* FindFirstFile needs a wildcard to match multiple items */
wcscat_s(buffer, MAX_PATH, L"*");
find_handle = FindFirstFileW(buffer, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buffer + buffer_prefix_len, MAX_PATH - buffer_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_rmdir_helper(buffer);
else {
/* If set, the +R bit must be cleared before deleting */
if (FILE_ATTRIBUTE_READONLY & find_data.dwFileAttributes)
cl_assert(SetFileAttributesW(buffer, find_data.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(buffer));
}
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
/* Now that the directory is empty, remove it */
cl_assert(0 == fs_rmdir_rmdir(_wsource));
}
static int
fs_rm_wait(WCHAR *_wpath)
{
unsigned retries = 1;
DWORD last_error;
do {
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(_wpath))
last_error = GetLastError();
else
last_error = ERROR_SUCCESS;
/* Is the item gone? */
if (ERROR_FILE_NOT_FOUND == last_error ||
ERROR_PATH_NOT_FOUND == last_error)
return 0;
Sleep(RM_RETRY_DELAY * retries * retries);
}
while (retries++ <= RM_RETRY_COUNT);
return -1;
}
static void
fs_rm(const char *_source)
{
WCHAR wsource[MAX_PATH];
DWORD attrs;
/* The input path is UTF-8. Convert it to wide characters
* for use with the Windows API */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1, /* Indicates NULL termination */
wsource,
MAX_PATH));
/* Does the item exist? If not, we have no work to do */
attrs = GetFileAttributesW(wsource);
if (INVALID_FILE_ATTRIBUTES == attrs)
return;
if (FILE_ATTRIBUTE_DIRECTORY & attrs)
fs_rmdir_helper(wsource);
else {
/* The item is a file. Strip the +R bit */
if (FILE_ATTRIBUTE_READONLY & attrs)
cl_assert(SetFileAttributesW(wsource, attrs & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(wsource));
}
/* Wait for the DeleteFile or RemoveDirectory call to complete */
cl_assert(0 == fs_rm_wait(wsource));
}
static void
fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
{
WCHAR buf_source[MAX_PATH], buf_dest[MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
int buf_source_prefix_len, buf_dest_prefix_len;
wcscpy_s(buf_source, MAX_PATH, _wsource);
wcscat_s(buf_source, MAX_PATH, L"\\");
buf_source_prefix_len = wcslen(buf_source);
wcscpy_s(buf_dest, MAX_PATH, _wdest);
wcscat_s(buf_dest, MAX_PATH, L"\\");
buf_dest_prefix_len = wcslen(buf_dest);
/* Get an enumerator for the items in the source. */
wcscat_s(buf_source, MAX_PATH, L"*");
find_handle = FindFirstFileW(buf_source, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
/* Create the target directory. */
cl_assert(CreateDirectoryW(_wdest, NULL));
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buf_source + buf_source_prefix_len, MAX_PATH - buf_source_prefix_len, find_data.cFileName);
wcscpy_s(buf_dest + buf_dest_prefix_len, MAX_PATH - buf_dest_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_copydir_helper(buf_source, buf_dest);
else
cl_assert(CopyFileW(buf_source, buf_dest, TRUE));
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
}
static void
fs_copy(const char *_source, const char *_dest)
{
WCHAR wsource[MAX_PATH], wdest[MAX_PATH];
DWORD source_attrs, dest_attrs;
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
/* The input paths are UTF-8. Convert them to wide characters
* for use with the Windows API. */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1,
wsource,
MAX_PATH));
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_dest,
-1,
wdest,
MAX_PATH));
/* Check the source for existence */
source_attrs = GetFileAttributesW(wsource);
cl_assert(INVALID_FILE_ATTRIBUTES != source_attrs);
/* Check the target for existence */
dest_attrs = GetFileAttributesW(wdest);
if (INVALID_FILE_ATTRIBUTES != dest_attrs) {
/* Target exists; append last path part of source to target.
* Use FindFirstFile to parse the path */
find_handle = FindFirstFileW(wsource, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
wcscat_s(wdest, MAX_PATH, L"\\");
wcscat_s(wdest, MAX_PATH, find_data.cFileName);
FindClose(find_handle);
/* Check the new target for existence */
cl_assert(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(wdest));
}
if (FILE_ATTRIBUTE_DIRECTORY & source_attrs)
fs_copydir_helper(wsource, wdest);
else
cl_assert(CopyFileW(wsource, wdest, TRUE));
}
void
cl_fs_cleanup(void)
{
fs_rm(fixture_path(_clar_path, "*"));
}
#else
static int
shell_out(char * const argv[])
{
int status;
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr,
"System error: `fork()` call failed.\n");
exit(-1);
}
if (pid == 0) {
execv(argv[0], argv);
}
waitpid(pid, &status, 0);
return WEXITSTATUS(status);
}
static void
fs_copy(const char *_source, const char *dest)
{
char *argv[5];
char *source;
size_t source_len;
source = strdup(_source);
source_len = strlen(source);
if (source[source_len - 1] == '/')
source[source_len - 1] = 0;
argv[0] = "/bin/cp";
argv[1] = "-R";
argv[2] = source;
argv[3] = (char *)dest;
argv[4] = NULL;
cl_must_pass_(
shell_out(argv),
"Failed to copy test fixtures to sandbox"
);
free(source);
}
static void
fs_rm(const char *source)
{
char *argv[4];
argv[0] = "/bin/rm";
argv[1] = "-Rf";
argv[2] = (char *)source;
argv[3] = NULL;
cl_must_pass_(
shell_out(argv),
"Failed to cleanup the sandbox"
);
}
void
cl_fs_cleanup(void)
{
clar_unsandbox();
clar_sandbox();
}
#endif
static void clar_print_init(int test_count, int suite_count, const char *suite_names)
{
(void)test_count;
printf("Loaded %d suites: %s\n", (int)suite_count, suite_names);
printf("Started\n");
}
static void clar_print_shutdown(int test_count, int suite_count, int error_count)
{
(void)test_count;
(void)suite_count;
(void)error_count;
printf("\n\n");
clar_report_errors();
}
static void clar_print_error(int num, const struct clar_error *error)
{
printf(" %d) Failure:\n", num);
printf("%s::%s [%s:%d]\n",
error->suite,
error->test,
error->file,
error->line_number);
printf(" %s\n", error->error_msg);
if (error->description != NULL)
printf(" %s\n", error->description);
printf("\n");
fflush(stdout);
}
static void clar_print_ontest(const char *test_name, int test_number, int failed)
{
(void)test_name;
(void)test_number;
printf("%c", failed ? 'F' : '.');
fflush(stdout);
}
static void clar_print_onsuite(const char *suite_name, int suite_index)
{
/* noop */
(void)suite_index;
(void)suite_name;
}
static void clar_print_onabort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
vfprintf(stderr, msg, argp);
va_end(argp);
}
static char _clar_path[4096];
static int
is_valid_tmp_path(const char *path)
{
STAT_T st;
if (stat(path, &st) != 0)
return 0;
if (!S_ISDIR(st.st_mode))
return 0;
return (access(path, W_OK) == 0);
}
static int
find_tmp_path(char *buffer, size_t length)
{
#ifndef _WIN32
static const size_t var_count = 4;
static const char *env_vars[] = {
"TMPDIR", "TMP", "TEMP", "USERPROFILE"
};
size_t i;
for (i = 0; i < var_count; ++i) {
const char *env = getenv(env_vars[i]);
if (!env)
continue;
if (is_valid_tmp_path(env)) {
strncpy(buffer, env, length);
return 0;
}
}
/* If the environment doesn't say anything, try to use /tmp */
if (is_valid_tmp_path("/tmp")) {
strncpy(buffer, "/tmp", length);
return 0;
}
#else
if (GetTempPath((DWORD)length, buffer))
return 0;
#endif
/* This system doesn't like us, try to use the current directory */
if (is_valid_tmp_path(".")) {
strncpy(buffer, ".", length);
return 0;
}
return -1;
}
static void clar_unsandbox(void)
{
if (_clar_path[0] == '\0')
return;
#ifdef _WIN32
chdir("..");
#endif
fs_rm(_clar_path);
}
static int build_sandbox_path(void)
{
const char path_tail[] = "clar_tmp_XXXXXX";
size_t len;
if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
return -1;
len = strlen(_clar_path);
#ifdef _WIN32
{ /* normalize path to POSIX forward slashes */
size_t i;
for (i = 0; i < len; ++i) {
if (_clar_path[i] == '\\')
_clar_path[i] = '/';
}
}
#endif
if (_clar_path[len - 1] != '/') {
_clar_path[len++] = '/';
}
strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len);
#if defined(__MINGW32__)
if (_mktemp(_clar_path) == NULL)
return -1;
if (mkdir(_clar_path, 0700) != 0)
return -1;
#elif defined(_WIN32)
if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
return -1;
if (mkdir(_clar_path, 0700) != 0)
return -1;
#else
if (mkdtemp(_clar_path) == NULL)
return -1;
#endif
return 0;
}
static int clar_sandbox(void)
{
if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
return -1;
if (chdir(_clar_path) != 0)
return -1;
return 0;
}
...@@ -2,17 +2,6 @@ ...@@ -2,17 +2,6 @@
#include "posix.h" #include "posix.h"
#include "path.h" #include "path.h"
void clar_on_init(void)
{
git_threads_init();
}
void clar_on_shutdown(void)
{
giterr_clear();
git_threads_shutdown();
}
void cl_git_mkfile(const char *filename, const char *content) void cl_git_mkfile(const char *filename, const char *content)
{ {
int fd; int fd;
......
...@@ -20,14 +20,14 @@ void test_clone_nonetwork__initialize(void) ...@@ -20,14 +20,14 @@ void test_clone_nonetwork__initialize(void)
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
} }
static void cleanup_repository(void *path) void test_clone_nonetwork__cleanup(void)
{ {
if (g_repo) { if (g_repo) {
git_repository_free(g_repo); git_repository_free(g_repo);
g_repo = NULL; g_repo = NULL;
} }
cl_fixture_cleanup((const char *)path); cl_fixture_cleanup("./foo");
} }
void test_clone_nonetwork__bad_url(void) void test_clone_nonetwork__bad_url(void)
...@@ -42,39 +42,30 @@ void test_clone_nonetwork__bad_url(void) ...@@ -42,39 +42,30 @@ void test_clone_nonetwork__bad_url(void)
void test_clone_nonetwork__local(void) void test_clone_nonetwork__local(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
} }
void test_clone_nonetwork__local_absolute_path(void) void test_clone_nonetwork__local_absolute_path(void)
{ {
const char *local_src; const char *local_src;
cl_set_cleanup(&cleanup_repository, "./foo");
local_src = cl_fixture("testrepo.git"); local_src = cl_fixture("testrepo.git");
cl_git_pass(git_clone(&g_repo, local_src, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, local_src, "./foo", &g_options));
} }
void test_clone_nonetwork__local_bare(void) void test_clone_nonetwork__local_bare(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.bare = true; g_options.bare = true;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
} }
void test_clone_nonetwork__fail_when_the_target_is_a_file(void) void test_clone_nonetwork__fail_when_the_target_is_a_file(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_mkfile("./foo", "Bar!"); cl_git_mkfile("./foo", "Bar!");
cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
} }
void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(void) void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
p_mkdir("./foo", GIT_DIR_MODE); p_mkdir("./foo", GIT_DIR_MODE);
cl_git_mkfile("./foo/bar", "Baz!"); cl_git_mkfile("./foo/bar", "Baz!");
cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -84,7 +75,6 @@ void test_clone_nonetwork__custom_origin_name(void) ...@@ -84,7 +75,6 @@ void test_clone_nonetwork__custom_origin_name(void)
{ {
git_remote *remote; git_remote *remote;
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.remote_name = "my_origin"; g_options.remote_name = "my_origin";
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -98,7 +88,6 @@ void test_clone_nonetwork__custom_push_url(void) ...@@ -98,7 +88,6 @@ void test_clone_nonetwork__custom_push_url(void)
git_remote *remote; git_remote *remote;
const char *url = "http://example.com"; const char *url = "http://example.com";
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.pushurl = url; g_options.pushurl = url;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -115,7 +104,6 @@ void test_clone_nonetwork__custom_fetch_spec(void) ...@@ -115,7 +104,6 @@ void test_clone_nonetwork__custom_fetch_spec(void)
const git_refspec *actual_fs; const git_refspec *actual_fs;
const char *spec = "+refs/heads/master:refs/heads/foo"; const char *spec = "+refs/heads/master:refs/heads/foo";
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.fetch_spec = spec; g_options.fetch_spec = spec;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -136,7 +124,6 @@ void test_clone_nonetwork__custom_push_spec(void) ...@@ -136,7 +124,6 @@ void test_clone_nonetwork__custom_push_spec(void)
const git_refspec *actual_fs; const git_refspec *actual_fs;
const char *spec = "+refs/heads/master:refs/heads/foo"; const char *spec = "+refs/heads/master:refs/heads/foo";
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.push_spec = spec; g_options.push_spec = spec;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -152,7 +139,6 @@ void test_clone_nonetwork__custom_autotag(void) ...@@ -152,7 +139,6 @@ void test_clone_nonetwork__custom_autotag(void)
{ {
git_strarray tags = {0}; git_strarray tags = {0};
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_NONE; g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
...@@ -162,8 +148,6 @@ void test_clone_nonetwork__custom_autotag(void) ...@@ -162,8 +148,6 @@ void test_clone_nonetwork__custom_autotag(void)
void test_clone_nonetwork__cope_with_already_existing_directory(void) void test_clone_nonetwork__cope_with_already_existing_directory(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
p_mkdir("./foo", GIT_DIR_MODE); p_mkdir("./foo", GIT_DIR_MODE);
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
} }
...@@ -171,7 +155,6 @@ void test_clone_nonetwork__cope_with_already_existing_directory(void) ...@@ -171,7 +155,6 @@ void test_clone_nonetwork__cope_with_already_existing_directory(void)
void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void)
{ {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.checkout_opts.checkout_strategy = 0; g_options.checkout_opts.checkout_strategy = 0;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
......
...@@ -431,11 +431,18 @@ void test_config_read__simple_read_from_specific_level(void) ...@@ -431,11 +431,18 @@ void test_config_read__simple_read_from_specific_level(void)
git_config_free(cfg); git_config_free(cfg);
} }
static void clean_empty_config(void *unused)
{
GIT_UNUSED(unused);
cl_fixture_cleanup("./empty");
}
void test_config_read__can_load_and_parse_an_empty_config_file(void) void test_config_read__can_load_and_parse_an_empty_config_file(void)
{ {
git_config *cfg; git_config *cfg;
int i; int i;
cl_set_cleanup(&clean_empty_config, NULL);
cl_git_mkfile("./empty", ""); cl_git_mkfile("./empty", "");
cl_git_pass(git_config_open_ondisk(&cfg, "./empty")); cl_git_pass(git_config_open_ondisk(&cfg, "./empty"));
cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither")); cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));
......
...@@ -14,6 +14,18 @@ static const char *env_vars[NUM_VARS] = { "HOME" }; ...@@ -14,6 +14,18 @@ static const char *env_vars[NUM_VARS] = { "HOME" };
static char *env_save[NUM_VARS]; static char *env_save[NUM_VARS];
static char *home_values[] = {
"fake_home",
"fáke_hõme", /* all in latin-1 supplement */
"fĀke_Ĥome", /* latin extended */
"fακε_hοmέ", /* having fun with greek */
"faงe_นome", /* now I have no idea, but thai characters */
"f\xe1\x9cx80ke_\xe1\x9c\x91ome", /* tagalog characters */
"\xe1\xb8\x9fẢke_hoṁe", /* latin extended additional */
"\xf0\x9f\x98\x98\xf0\x9f\x98\x82", /* emoticons */
NULL
};
void test_core_env__initialize(void) void test_core_env__initialize(void)
{ {
int i; int i;
...@@ -24,6 +36,8 @@ void test_core_env__initialize(void) ...@@ -24,6 +36,8 @@ void test_core_env__initialize(void)
void test_core_env__cleanup(void) void test_core_env__cleanup(void)
{ {
int i; int i;
char **val;
for (i = 0; i < NUM_VARS; ++i) { for (i = 0; i < NUM_VARS; ++i) {
cl_setenv(env_vars[i], env_save[i]); cl_setenv(env_vars[i], env_save[i]);
#ifdef GIT_WIN32 #ifdef GIT_WIN32
...@@ -31,11 +45,20 @@ void test_core_env__cleanup(void) ...@@ -31,11 +45,20 @@ void test_core_env__cleanup(void)
#endif #endif
env_save[i] = NULL; env_save[i] = NULL;
} }
/* these will probably have already been cleaned up, but if a test
* fails, then it's probably good to try and clear out these dirs
*/
for (val = home_values; *val != NULL; val++) {
if (**val != '\0')
(void)p_rmdir(*val);
}
} }
static void setenv_and_check(const char *name, const char *value) static void setenv_and_check(const char *name, const char *value)
{ {
char *check; char *check;
cl_git_pass(cl_setenv(name, value)); cl_git_pass(cl_setenv(name, value));
check = cl_getenv(name); check = cl_getenv(name);
cl_assert_equal_s(value, check); cl_assert_equal_s(value, check);
...@@ -46,17 +69,6 @@ static void setenv_and_check(const char *name, const char *value) ...@@ -46,17 +69,6 @@ static void setenv_and_check(const char *name, const char *value)
void test_core_env__0(void) void test_core_env__0(void)
{ {
static char *home_values[] = {
"fake_home",
"fáke_hõme", /* all in latin-1 supplement */
"fĀke_Ĥome", /* latin extended */
"fακε_hοmέ", /* having fun with greek */
"faงe_นome", /* now I have no idea, but thai characters */
"f\xe1\x9cx80ke_\xe1\x9c\x91ome", /* tagalog characters */
"\xe1\xb8\x9fẢke_hoṁe", /* latin extended additional */
"\xf0\x9f\x98\x98\xf0\x9f\x98\x82", /* emoticons */
NULL
};
git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
char testfile[16], tidx = '0'; char testfile[16], tidx = '0';
char **val; char **val;
...@@ -71,8 +83,10 @@ void test_core_env__0(void) ...@@ -71,8 +83,10 @@ void test_core_env__0(void)
* we are on a filesystem that doesn't support the * we are on a filesystem that doesn't support the
* characters in question and skip this test... * characters in question and skip this test...
*/ */
if (p_mkdir(*val, 0777) != 0) if (p_mkdir(*val, 0777) != 0) {
*val = ""; /* mark as not created */
continue; continue;
}
cl_git_pass(git_path_prettify(&path, *val, NULL)); cl_git_pass(git_path_prettify(&path, *val, NULL));
...@@ -122,6 +136,8 @@ void test_core_env__0(void) ...@@ -122,6 +136,8 @@ void test_core_env__0(void)
} }
} }
#endif #endif
(void)p_rmdir(*val);
} }
git_buf_free(&path); git_buf_free(&path);
......
#!/usr/bin/env python
from __future__ import with_statement
from string import Template
import re, fnmatch, os, codecs, pickle
class Module(object):
class Template(object):
def __init__(self, module):
self.module = module
def _render_callback(self, cb):
if not cb:
return '{ NULL, NULL }'
return '{ "%s", &%s }' % (cb['short_name'], cb['symbol'])
class DeclarationTemplate(Template):
def render(self):
out = "\n".join("extern %s;" % cb['declaration'] for cb in self.module.callbacks)
if self.module.initialize:
out += "extern %s;\n" % self.module.initialize['declaration']
if self.module.cleanup:
out += "extern %s;\n" % self.module.cleanup['declaration']
return out
class CallbacksTemplate(Template):
def render(self):
out = "static const struct clar_func _clar_cb_%s[] = {\n" % self.module.name
out += ",\n".join(self._render_callback(cb) for cb in self.module.callbacks)
out += "\n};\n"
return out
class InfoTemplate(Template):
def render(self):
return Template(
r"""{
"${clean_name}",
${initialize},
${cleanup},
${cb_ptr}, ${cb_count}, ${enabled}
}"""
).substitute(
clean_name = self.module.clean_name(),
initialize = self._render_callback(self.module.initialize),
cleanup = self._render_callback(self.module.cleanup),
cb_ptr = "_clar_cb_%s" % self.module.name,
cb_count = len(self.module.callbacks),
enabled = int(self.module.enabled)
)
def __init__(self, name):
self.name = name
self.mtime = 0
self.enabled = True
self.modified = False
def clean_name(self):
return self.name.replace("_", "::")
def _skip_comments(self, text):
SKIP_COMMENTS_REGEX = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE)
def _replacer(match):
s = match.group(0)
return "" if s.startswith('/') else s
return re.sub(SKIP_COMMENTS_REGEX, _replacer, text)
def parse(self, contents):
TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\(\s*void\s*\))\s*\{"
contents = self._skip_comments(contents)
regex = re.compile(TEST_FUNC_REGEX % self.name, re.MULTILINE)
self.callbacks = []
self.initialize = None
self.cleanup = None
for (declaration, symbol, short_name) in regex.findall(contents):
data = {
"short_name" : short_name,
"declaration" : declaration,
"symbol" : symbol
}
if short_name == 'initialize':
self.initialize = data
elif short_name == 'cleanup':
self.cleanup = data
else:
self.callbacks.append(data)
return self.callbacks != []
def refresh(self, path):
self.modified = False
try:
st = os.stat(path)
# Not modified
if st.st_mtime == self.mtime:
return True
self.modified = True
self.mtime = st.st_mtime
with open(path) as fp:
raw_content = fp.read()
except IOError:
return False
return self.parse(raw_content)
class TestSuite(object):
def __init__(self, path):
self.path = path
def should_generate(self, path):
if not os.path.isfile(path):
return True
if any(module.modified for module in self.modules.values()):
return True
return False
def find_modules(self):
modules = []
for root, _, files in os.walk(self.path):
module_root = root[len(self.path):]
module_root = [c for c in module_root.split(os.sep) if c]
tests_in_module = fnmatch.filter(files, "*.c")
for test_file in tests_in_module:
full_path = os.path.join(root, test_file)
module_name = "_".join(module_root + [test_file[:-2]])
modules.append((full_path, module_name))
return modules
def load_cache(self):
path = os.path.join(self.path, '.clarcache')
cache = {}
try:
fp = open(path)
cache = pickle.load(fp)
fp.close()
except IOError:
pass
return cache
def save_cache(self):
path = os.path.join(self.path, '.clarcache')
with open(path, 'w') as cache:
pickle.dump(self.modules, cache)
def load(self, force = False):
module_data = self.find_modules()
self.modules = {} if force else self.load_cache()
for path, name in module_data:
if name not in self.modules:
self.modules[name] = Module(name)
if not self.modules[name].refresh(path):
del self.modules[name]
def disable(self, excluded):
for exclude in excluded:
for module in self.modules.values():
name = module.clean_name()
if name.startswith(exclude):
module.enabled = False
module.modified = True
def suite_count(self):
return len(self.modules)
def callback_count(self):
return sum(len(module.callbacks) for module in self.modules.values())
def write(self):
output = os.path.join(self.path, 'clar.suite')
if not self.should_generate(output):
return False
with open(output, 'w') as data:
for module in self.modules.values():
t = Module.DeclarationTemplate(module)
data.write(t.render())
for module in self.modules.values():
t = Module.CallbacksTemplate(module)
data.write(t.render())
suites = "static struct clar_suite _clar_suites[] = {" + ','.join(
Module.InfoTemplate(module).render() for module in self.modules.values()
) + "};"
data.write(suites)
data.write("static const size_t _clar_suite_count = %d;" % self.suite_count())
data.write("static const size_t _clar_callback_count = %d;" % self.callback_count())
suite.save_cache()
return True
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option('-f', '--force', dest='force', default=False)
parser.add_option('-x', '--exclude', dest='excluded', action='append', default=[])
options, args = parser.parse_args()
for path in args or ['.']:
suite = TestSuite(path)
suite.load(options.force)
suite.disable(options.excluded)
if suite.write():
print "Written `clar.suite` (%d suites)" % len(suite.modules)
...@@ -24,7 +24,6 @@ static struct test_entry test_entries[] = { ...@@ -24,7 +24,6 @@ static struct test_entry test_entries[] = {
{48, "src/revobject.h", 1448, 0x4C3F7FE2} {48, "src/revobject.h", 1448, 0x4C3F7FE2}
}; };
// Helpers // Helpers
static void copy_file(const char *src, const char *dst) static void copy_file(const char *src, const char *dst)
{ {
...@@ -72,11 +71,6 @@ void test_index_tests__initialize(void) ...@@ -72,11 +71,6 @@ void test_index_tests__initialize(void)
{ {
} }
void test_index_tests__cleanup(void)
{
}
void test_index_tests__empty_index(void) void test_index_tests__empty_index(void)
{ {
git_index *index; git_index *index;
...@@ -203,6 +197,12 @@ void test_index_tests__sort1(void) ...@@ -203,6 +197,12 @@ void test_index_tests__sort1(void)
git_index_free(index); git_index_free(index);
} }
static void cleanup_myrepo(void *opaque)
{
GIT_UNUSED(opaque);
cl_fixture_cleanup("myrepo");
}
void test_index_tests__add(void) void test_index_tests__add(void)
{ {
git_index *index; git_index *index;
...@@ -211,6 +211,8 @@ void test_index_tests__add(void) ...@@ -211,6 +211,8 @@ void test_index_tests__add(void)
const git_index_entry *entry; const git_index_entry *entry;
git_oid id1; git_oid id1;
cl_set_cleanup(&cleanup_myrepo, NULL);
/* Intialize a new repository */ /* Intialize a new repository */
cl_git_pass(git_repository_init(&repo, "./myrepo", 0)); cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
......
#include "clar_libgit2.h"
int main(int argc, char *argv[])
{
int res;
git_threads_init();
/* Run the test suite */
res = clar_test(argc, argv);
giterr_clear();
git_threads_shutdown();
return res;
}
...@@ -44,22 +44,6 @@ void test_merge_setup__cleanup(void) ...@@ -44,22 +44,6 @@ void test_merge_setup__cleanup(void)
cl_git_sandbox_cleanup(); cl_git_sandbox_cleanup();
} }
static bool test_file_contents(const char *filename, const char *expected)
{
git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT;
bool equals;
git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename);
cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr));
equals = (strcmp(file_buf.ptr, expected) == 0);
git_buf_free(&file_path_buf);
git_buf_free(&file_buf);
return equals;
}
static void write_file_contents(const char *filename, const char *output) static void write_file_contents(const char *filename, const char *output)
{ {
git_buf file_path_buf = GIT_BUF_INIT; git_buf file_path_buf = GIT_BUF_INIT;
...@@ -77,18 +61,14 @@ struct merge_head_cb_data { ...@@ -77,18 +61,14 @@ struct merge_head_cb_data {
unsigned int i; unsigned int i;
}; };
int merge_head_foreach_cb(git_oid *oid, void *payload) static int merge_head_foreach_cb(const git_oid *oid, void *payload)
{ {
git_oid expected_oid; git_oid expected_oid;
struct merge_head_cb_data *cb_data = payload; struct merge_head_cb_data *cb_data = payload;
git_oid_fromstr(&expected_oid, cb_data->oid_str[cb_data->i]); git_oid_fromstr(&expected_oid, cb_data->oid_str[cb_data->i]);
cl_assert(git_oid_cmp(&expected_oid, oid) == 0); cl_assert(git_oid_cmp(&expected_oid, oid) == 0);
cb_data->i++; cb_data->i++;
return 0; return 0;
} }
......
...@@ -11,6 +11,11 @@ static void transfer_cb(const git_transfer_progress *stats, void *payload) ...@@ -11,6 +11,11 @@ static void transfer_cb(const git_transfer_progress *stats, void *payload)
(*callcount)++; (*callcount)++;
} }
static void cleanup_local_repo(void *path)
{
cl_fixture_cleanup((char *)path);
}
void test_network_fetchlocal__complete(void) void test_network_fetchlocal__complete(void)
{ {
git_repository *repo; git_repository *repo;
...@@ -19,6 +24,8 @@ void test_network_fetchlocal__complete(void) ...@@ -19,6 +24,8 @@ void test_network_fetchlocal__complete(void)
git_strarray refnames = {0}; git_strarray refnames = {0};
const char *url = cl_git_fixture_url("testrepo.git"); const char *url = cl_git_fixture_url("testrepo.git");
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
...@@ -35,6 +42,12 @@ void test_network_fetchlocal__complete(void) ...@@ -35,6 +42,12 @@ void test_network_fetchlocal__complete(void)
git_repository_free(repo); git_repository_free(repo);
} }
static void cleanup_sandbox(void *unused)
{
GIT_UNUSED(unused);
cl_git_sandbox_cleanup();
}
void test_network_fetchlocal__partial(void) void test_network_fetchlocal__partial(void)
{ {
git_repository *repo = cl_git_sandbox_init("partial-testrepo"); git_repository *repo = cl_git_sandbox_init("partial-testrepo");
...@@ -43,6 +56,7 @@ void test_network_fetchlocal__partial(void) ...@@ -43,6 +56,7 @@ void test_network_fetchlocal__partial(void)
git_strarray refnames = {0}; git_strarray refnames = {0};
const char *url; const char *url;
cl_set_cleanup(&cleanup_sandbox, NULL);
cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL)); cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
cl_assert_equal_i(1, (int)refnames.count); cl_assert_equal_i(1, (int)refnames.count);
...@@ -60,6 +74,4 @@ void test_network_fetchlocal__partial(void) ...@@ -60,6 +74,4 @@ void test_network_fetchlocal__partial(void)
git_strarray_free(&refnames); git_strarray_free(&refnames);
git_remote_free(origin); git_remote_free(origin);
cl_git_sandbox_cleanup();
} }
...@@ -11,8 +11,13 @@ static git_repository *repo; ...@@ -11,8 +11,13 @@ static git_repository *repo;
void test_odb_alternates__cleanup(void) void test_odb_alternates__cleanup(void)
{ {
size_t i;
git_buf_free(&destpath); git_buf_free(&destpath);
git_buf_free(&filepath); git_buf_free(&filepath);
for (i = 0; i < ARRAY_SIZE(paths); i++)
cl_fixture_cleanup(paths[i]);
} }
static void init_linked_repo(const char *path, const char *alternate) static void init_linked_repo(const char *path, const char *alternate)
......
...@@ -3,15 +3,13 @@ ...@@ -3,15 +3,13 @@
#include "git2/clone.h" #include "git2/clone.h"
#include "repository.h" #include "repository.h"
CL_IN_CATEGORY("network")
#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository" #define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository" #define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
static git_repository *g_repo; static git_repository *g_repo;
static git_clone_options g_options; static git_clone_options g_options;
void test_clone_network__initialize(void) void test_online_clone__initialize(void)
{ {
git_checkout_opts dummy_opts = GIT_CHECKOUT_OPTS_INIT; git_checkout_opts dummy_opts = GIT_CHECKOUT_OPTS_INIT;
...@@ -23,22 +21,19 @@ void test_clone_network__initialize(void) ...@@ -23,22 +21,19 @@ void test_clone_network__initialize(void)
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
} }
static void cleanup_repository(void *path) void test_online_clone__cleanup(void)
{ {
if (g_repo) { if (g_repo) {
git_repository_free(g_repo); git_repository_free(g_repo);
g_repo = NULL; g_repo = NULL;
} }
cl_fixture_cleanup((const char *)path); cl_fixture_cleanup("./foo");
} }
void test_online_clone__network_full(void)
void test_clone_network__network_full(void)
{ {
git_remote *origin; git_remote *origin;
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
cl_assert(!git_repository_is_bare(g_repo)); cl_assert(!git_repository_is_bare(g_repo));
cl_git_pass(git_remote_load(&origin, g_repo, "origin")); cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
...@@ -46,12 +41,10 @@ void test_clone_network__network_full(void) ...@@ -46,12 +41,10 @@ void test_clone_network__network_full(void)
git_remote_free(origin); git_remote_free(origin);
} }
void test_online_clone__network_bare(void)
void test_clone_network__network_bare(void)
{ {
git_remote *origin; git_remote *origin;
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.bare = true; g_options.bare = true;
cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
...@@ -61,12 +54,10 @@ void test_clone_network__network_bare(void) ...@@ -61,12 +54,10 @@ void test_clone_network__network_bare(void)
git_remote_free(origin); git_remote_free(origin);
} }
void test_clone_network__empty_repository(void) void test_online_clone__empty_repository(void)
{ {
git_reference *head; git_reference *head;
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options));
cl_assert_equal_i(true, git_repository_is_empty(g_repo)); cl_assert_equal_i(true, git_repository_is_empty(g_repo));
...@@ -93,7 +84,7 @@ static void fetch_progress(const git_transfer_progress *stats, void *payload) ...@@ -93,7 +84,7 @@ static void fetch_progress(const git_transfer_progress *stats, void *payload)
(*was_called) = true; (*was_called) = true;
} }
void test_clone_network__can_checkout_a_cloned_repo(void) void test_online_clone__can_checkout_a_cloned_repo(void)
{ {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
git_reference *head; git_reference *head;
...@@ -106,8 +97,6 @@ void test_clone_network__can_checkout_a_cloned_repo(void) ...@@ -106,8 +97,6 @@ void test_clone_network__can_checkout_a_cloned_repo(void)
g_options.fetch_progress_cb = &fetch_progress; g_options.fetch_progress_cb = &fetch_progress;
g_options.fetch_progress_payload = &fetch_progress_cb_was_called; g_options.fetch_progress_payload = &fetch_progress_cb_was_called;
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
...@@ -137,8 +126,6 @@ void test_clone_network__custom_remote_callbacks(void) ...@@ -137,8 +126,6 @@ void test_clone_network__custom_remote_callbacks(void)
git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT; git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT;
int callcount = 0; int callcount = 0;
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.remote_callbacks = &remote_callbacks; g_options.remote_callbacks = &remote_callbacks;
remote_callbacks.update_tips = update_tips; remote_callbacks.update_tips = update_tips;
remote_callbacks.payload = &callcount; remote_callbacks.payload = &callcount;
...@@ -179,8 +166,6 @@ void test_clone_network__credentials(void) ...@@ -179,8 +166,6 @@ void test_clone_network__credentials(void)
if (!remote_url) return; if (!remote_url) return;
cl_set_cleanup(&cleanup_repository, "./foo");
g_options.cred_acquire_cb = cred_acquire; g_options.cred_acquire_cb = cred_acquire;
g_options.cred_acquire_payload = &user_pass; g_options.cred_acquire_payload = &user_pass;
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
CL_IN_CATEGORY("network")
static git_repository *_repo; static git_repository *_repo;
static int counter; static int counter;
void test_network_fetch__initialize(void) void test_online_fetch__initialize(void)
{ {
cl_git_pass(git_repository_init(&_repo, "./fetch", 0)); cl_git_pass(git_repository_init(&_repo, "./fetch", 0));
} }
void test_network_fetch__cleanup(void) void test_online_fetch__cleanup(void)
{ {
git_repository_free(_repo); git_repository_free(_repo);
_repo = NULL; _repo = NULL;
...@@ -55,22 +53,22 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) ...@@ -55,22 +53,22 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
git_remote_free(remote); git_remote_free(remote);
} }
void test_network_fetch__default_git(void) void test_online_fetch__default_git(void)
{ {
do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6); do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
} }
void test_network_fetch__default_http(void) void test_online_fetch__default_http(void)
{ {
do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6); do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
} }
void test_network_fetch__no_tags_git(void) void test_online_fetch__no_tags_git(void)
{ {
do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3); do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
} }
void test_network_fetch__no_tags_http(void) void test_online_fetch__no_tags_http(void)
{ {
do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3); do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
} }
...@@ -83,7 +81,7 @@ static void transferProgressCallback(const git_transfer_progress *stats, void *p ...@@ -83,7 +81,7 @@ static void transferProgressCallback(const git_transfer_progress *stats, void *p
*invoked = true; *invoked = true;
} }
void test_network_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date(void) void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date(void)
{ {
git_repository *_repository; git_repository *_repository;
bool invoked = false; bool invoked = false;
......
...@@ -2,17 +2,15 @@ ...@@ -2,17 +2,15 @@
#include "repository.h" #include "repository.h"
#include "fetchhead.h" #include "fetchhead.h"
#include "fetchhead_data.h" #include "../fetchhead/fetchhead_data.h"
#include "git2/clone.h" #include "git2/clone.h"
CL_IN_CATEGORY("network")
#define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository" #define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository"
static git_repository *g_repo; static git_repository *g_repo;
static git_clone_options g_options; static git_clone_options g_options;
void test_fetchhead_network__initialize(void) void test_online_fetchhead__initialize(void)
{ {
g_repo = NULL; g_repo = NULL;
...@@ -20,21 +18,18 @@ void test_fetchhead_network__initialize(void) ...@@ -20,21 +18,18 @@ void test_fetchhead_network__initialize(void)
g_options.version = GIT_CLONE_OPTIONS_VERSION; g_options.version = GIT_CLONE_OPTIONS_VERSION;
} }
static void cleanup_repository(void *path) void test_online_fetchhead__cleanup(void)
{ {
if (g_repo) { if (g_repo) {
git_repository_free(g_repo); git_repository_free(g_repo);
g_repo = NULL; g_repo = NULL;
} }
cl_fixture_cleanup((const char *)path); cl_fixture_cleanup("./foo");
} }
static void fetchhead_test_clone(void) static void fetchhead_test_clone(void)
{ {
cl_set_cleanup(&cleanup_repository, "./foo");
cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
} }
...@@ -65,19 +60,19 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet ...@@ -65,19 +60,19 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
cl_assert(equals); cl_assert(equals);
} }
void test_fetchhead_network__wildcard_spec(void) void test_online_fetchhead__wildcard_spec(void)
{ {
fetchhead_test_clone(); fetchhead_test_clone();
fetchhead_test_fetch(NULL, FETCH_HEAD_WILDCARD_DATA); fetchhead_test_fetch(NULL, FETCH_HEAD_WILDCARD_DATA);
} }
void test_fetchhead_network__explicit_spec(void) void test_online_fetchhead__explicit_spec(void)
{ {
fetchhead_test_clone(); fetchhead_test_clone();
fetchhead_test_fetch("refs/heads/first-merge:refs/remotes/origin/first-merge", FETCH_HEAD_EXPLICIT_DATA); fetchhead_test_fetch("refs/heads/first-merge:refs/remotes/origin/first-merge", FETCH_HEAD_EXPLICIT_DATA);
} }
void test_fetchhead_network__no_merges(void) void test_online_fetchhead__no_merges(void)
{ {
git_config *config; git_config *config;
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#include "../submodule/submodule_helpers.h" #include "../submodule/submodule_helpers.h"
#include "push_util.h" #include "push_util.h"
CL_IN_CATEGORY("network")
static git_repository *_repo; static git_repository *_repo;
static char *_remote_url; static char *_remote_url;
...@@ -127,7 +125,7 @@ static void verify_refs(git_remote *remote, expected_ref expected_refs[], size_t ...@@ -127,7 +125,7 @@ static void verify_refs(git_remote *remote, expected_ref expected_refs[], size_t
git_vector_free(&actual_refs); git_vector_free(&actual_refs);
} }
void test_network_push__initialize(void) void test_online_push__initialize(void)
{ {
git_vector delete_specs = GIT_VECTOR_INIT; git_vector delete_specs = GIT_VECTOR_INIT;
size_t i; size_t i;
...@@ -207,7 +205,7 @@ void test_network_push__initialize(void) ...@@ -207,7 +205,7 @@ void test_network_push__initialize(void)
printf("GITTEST_REMOTE_URL unset; skipping push test\n"); printf("GITTEST_REMOTE_URL unset; skipping push test\n");
} }
void test_network_push__cleanup(void) void test_online_push__cleanup(void)
{ {
if (_remote) if (_remote)
git_remote_free(_remote); git_remote_free(_remote);
...@@ -271,12 +269,12 @@ static void do_push(const char *refspecs[], size_t refspecs_len, ...@@ -271,12 +269,12 @@ static void do_push(const char *refspecs[], size_t refspecs_len,
} }
/* Call push_finish() without ever calling git_push_add_refspec() */ /* Call push_finish() without ever calling git_push_add_refspec() */
void test_network_push__noop(void) void test_online_push__noop(void)
{ {
do_push(NULL, 0, NULL, 0, NULL, 0, 0); do_push(NULL, 0, NULL, 0, NULL, 0, 0);
} }
void test_network_push__b1(void) void test_online_push__b1(void)
{ {
const char *specs[] = { "refs/heads/b1:refs/heads/b1" }; const char *specs[] = { "refs/heads/b1:refs/heads/b1" };
push_status exp_stats[] = { { "refs/heads/b1", NULL } }; push_status exp_stats[] = { { "refs/heads/b1", NULL } };
...@@ -286,7 +284,7 @@ void test_network_push__b1(void) ...@@ -286,7 +284,7 @@ void test_network_push__b1(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__b2(void) void test_online_push__b2(void)
{ {
const char *specs[] = { "refs/heads/b2:refs/heads/b2" }; const char *specs[] = { "refs/heads/b2:refs/heads/b2" };
push_status exp_stats[] = { { "refs/heads/b2", NULL } }; push_status exp_stats[] = { { "refs/heads/b2", NULL } };
...@@ -296,7 +294,7 @@ void test_network_push__b2(void) ...@@ -296,7 +294,7 @@ void test_network_push__b2(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__b3(void) void test_online_push__b3(void)
{ {
const char *specs[] = { "refs/heads/b3:refs/heads/b3" }; const char *specs[] = { "refs/heads/b3:refs/heads/b3" };
push_status exp_stats[] = { { "refs/heads/b3", NULL } }; push_status exp_stats[] = { { "refs/heads/b3", NULL } };
...@@ -306,7 +304,7 @@ void test_network_push__b3(void) ...@@ -306,7 +304,7 @@ void test_network_push__b3(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__b4(void) void test_online_push__b4(void)
{ {
const char *specs[] = { "refs/heads/b4:refs/heads/b4" }; const char *specs[] = { "refs/heads/b4:refs/heads/b4" };
push_status exp_stats[] = { { "refs/heads/b4", NULL } }; push_status exp_stats[] = { { "refs/heads/b4", NULL } };
...@@ -316,7 +314,7 @@ void test_network_push__b4(void) ...@@ -316,7 +314,7 @@ void test_network_push__b4(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__b5(void) void test_online_push__b5(void)
{ {
const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
push_status exp_stats[] = { { "refs/heads/b5", NULL } }; push_status exp_stats[] = { { "refs/heads/b5", NULL } };
...@@ -326,7 +324,7 @@ void test_network_push__b5(void) ...@@ -326,7 +324,7 @@ void test_network_push__b5(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__multi(void) void test_online_push__multi(void)
{ {
const char *specs[] = { const char *specs[] = {
"refs/heads/b1:refs/heads/b1", "refs/heads/b1:refs/heads/b1",
...@@ -354,7 +352,7 @@ void test_network_push__multi(void) ...@@ -354,7 +352,7 @@ void test_network_push__multi(void)
exp_refs, ARRAY_SIZE(exp_refs), 0); exp_refs, ARRAY_SIZE(exp_refs), 0);
} }
void test_network_push__implicit_tgt(void) void test_online_push__implicit_tgt(void)
{ {
const char *specs1[] = { "refs/heads/b1:" }; const char *specs1[] = { "refs/heads/b1:" };
push_status exp_stats1[] = { { "refs/heads/b1", NULL } }; push_status exp_stats1[] = { { "refs/heads/b1", NULL } };
...@@ -375,7 +373,7 @@ void test_network_push__implicit_tgt(void) ...@@ -375,7 +373,7 @@ void test_network_push__implicit_tgt(void)
exp_refs2, ARRAY_SIZE(exp_refs2), 0); exp_refs2, ARRAY_SIZE(exp_refs2), 0);
} }
void test_network_push__fast_fwd(void) void test_online_push__fast_fwd(void)
{ {
/* Fast forward b1 in tgt from _oid_b1 to _oid_b6. */ /* Fast forward b1 in tgt from _oid_b1 to _oid_b6. */
...@@ -409,7 +407,7 @@ void test_network_push__fast_fwd(void) ...@@ -409,7 +407,7 @@ void test_network_push__fast_fwd(void)
exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0); exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0);
} }
void test_network_push__force(void) void test_online_push__force(void)
{ {
const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"}; const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"};
push_status exp_stats1[] = { { "refs/heads/tgt", NULL } }; push_status exp_stats1[] = { { "refs/heads/tgt", NULL } };
...@@ -435,7 +433,7 @@ void test_network_push__force(void) ...@@ -435,7 +433,7 @@ void test_network_push__force(void)
exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0); exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0);
} }
void test_network_push__delete(void) void test_online_push__delete(void)
{ {
const char *specs1[] = { const char *specs1[] = {
"refs/heads/b1:refs/heads/tgt1", "refs/heads/b1:refs/heads/tgt1",
...@@ -492,7 +490,7 @@ void test_network_push__delete(void) ...@@ -492,7 +490,7 @@ void test_network_push__delete(void)
exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0); exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0);
} }
void test_network_push__bad_refspecs(void) void test_online_push__bad_refspecs(void)
{ {
/* All classes of refspecs that should be rejected by /* All classes of refspecs that should be rejected by
* git_push_add_refspec() should go in this test. * git_push_add_refspec() should go in this test.
...@@ -510,7 +508,7 @@ void test_network_push__bad_refspecs(void) ...@@ -510,7 +508,7 @@ void test_network_push__bad_refspecs(void)
} }
} }
void test_network_push__expressions(void) void test_online_push__expressions(void)
{ {
/* TODO: Expressions in refspecs doesn't actually work yet */ /* TODO: Expressions in refspecs doesn't actually work yet */
const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" }; const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" };
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "iterator.h" #include "iterator.h"
#include "vector.h" #include "vector.h"
#include "posix.h"
static git_repository *_repo; static git_repository *_repo;
static git_revwalk *_revwalker; static git_revwalk *_revwalker;
...@@ -11,7 +12,7 @@ static int _commits_is_initialized; ...@@ -11,7 +12,7 @@ static int _commits_is_initialized;
void test_pack_packbuilder__initialize(void) void test_pack_packbuilder__initialize(void)
{ {
cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); _repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_revwalk_new(&_revwalker, _repo)); cl_git_pass(git_revwalk_new(&_revwalker, _repo));
cl_git_pass(git_packbuilder_new(&_packbuilder, _repo)); cl_git_pass(git_packbuilder_new(&_packbuilder, _repo));
cl_git_pass(git_vector_init(&_commits, 0, NULL)); cl_git_pass(git_vector_init(&_commits, 0, NULL));
...@@ -40,7 +41,7 @@ void test_pack_packbuilder__cleanup(void) ...@@ -40,7 +41,7 @@ void test_pack_packbuilder__cleanup(void)
git_indexer_free(_indexer); git_indexer_free(_indexer);
_indexer = NULL; _indexer = NULL;
git_repository_free(_repo); cl_git_sandbox_cleanup();
_repo = NULL; _repo = NULL;
} }
...@@ -88,9 +89,7 @@ static git_transfer_progress stats; ...@@ -88,9 +89,7 @@ static git_transfer_progress stats;
static int foreach_cb(void *buf, size_t len, void *payload) static int foreach_cb(void *buf, size_t len, void *payload)
{ {
git_indexer_stream *idx = (git_indexer_stream *) payload; git_indexer_stream *idx = (git_indexer_stream *) payload;
cl_git_pass(git_indexer_stream_add(idx, buf, len, &stats)); cl_git_pass(git_indexer_stream_add(idx, buf, len, &stats));
return 0; return 0;
} }
......
...@@ -32,6 +32,7 @@ void test_stash_save__cleanup(void) ...@@ -32,6 +32,7 @@ void test_stash_save__cleanup(void)
repo = NULL; repo = NULL;
cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES));
cl_fixture_cleanup("sorry-it-is-a-non-bare-only-party");
} }
static void assert_object_oid(const char* revision, const char* expected_oid, git_otype type) static void assert_object_oid(const char* revision, const char* expected_oid, git_otype type)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment