Merge all the source files of exactness binary
It will be easier to refactor everything after that
This commit is contained in:
parent
76a433273e
commit
83e34fec36
|
@ -2,12 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||
|
||||
bin_PROGRAMS = exactness exactness_helper exactness_play exactness_record
|
||||
|
||||
exactness_SOURCES = \
|
||||
exactness.c \
|
||||
list_file.c \
|
||||
exactness_config.c \
|
||||
scheduler.c \
|
||||
run_test.c
|
||||
exactness_SOURCES = exactness.c
|
||||
|
||||
exactness_helper_SOURCES = exactness_helper.c
|
||||
|
||||
|
|
|
@ -1,12 +1,417 @@
|
|||
#include "config.h"
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Getopt.h>
|
||||
#include <Emile.h>
|
||||
|
||||
#include "list_file.h"
|
||||
#include "exactness_config.h"
|
||||
#include "run_test.h"
|
||||
#include "scheduler.h"
|
||||
#include "exactness_private.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
typedef struct _List_Entry List_Entry;
|
||||
|
||||
struct _List_Entry
|
||||
{
|
||||
EINA_INLIST;
|
||||
char *name;
|
||||
const char *command;
|
||||
};
|
||||
|
||||
typedef struct _Exactness_Config Exactness_Config;
|
||||
|
||||
struct _Exactness_Config
|
||||
{
|
||||
unsigned short jobs;
|
||||
char *base_dir;
|
||||
char *dest_dir;
|
||||
char *wrap_command;
|
||||
Eina_Bool verbose;
|
||||
Eina_Bool store_objects;
|
||||
};
|
||||
|
||||
typedef struct _Exactness_Ctx Exactness_Ctx;
|
||||
|
||||
struct _Exactness_Ctx
|
||||
{
|
||||
unsigned int tests_executed;
|
||||
Eina_List *errors;
|
||||
Eina_List *compare_errors;
|
||||
};
|
||||
|
||||
#define SCHEDULER_CMD_SIZE 1024
|
||||
|
||||
typedef void (*Scheduler_Cb)(const List_Entry *, char *);
|
||||
|
||||
Exactness_Config exactness_config;
|
||||
Exactness_Ctx exactness_ctx;
|
||||
|
||||
#define ORIG_SUBDIR "orig"
|
||||
#define CURRENT_SUBDIR "current"
|
||||
|
||||
#define EXACTNESS_PATH_MAX 1024
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#define CONFIG "ELM_SCALE=1 ELM_FINGER_SIZE=10"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RUN_SIMULATION,
|
||||
RUN_PLAY,
|
||||
RUN_RECORD,
|
||||
RUN_INIT
|
||||
} Run_Mode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Scheduler_Cb prepare_func;
|
||||
List_Entry *last;
|
||||
unsigned short jobs;
|
||||
} Scheduler_Ctx;
|
||||
|
||||
static Ecore_Event_Handler *_job_del_callback_handler = NULL;
|
||||
|
||||
static Eina_Bool _job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx);
|
||||
|
||||
static Eina_Bool
|
||||
_job_deleted_cb(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event;
|
||||
Scheduler_Ctx *ctx = data;
|
||||
|
||||
if ((msg->exit_code != 0) || (msg->exit_signal != 0))
|
||||
{
|
||||
List_Entry *ent = ecore_exe_data_get(msg->exe);
|
||||
exactness_ctx.errors = eina_list_append(exactness_ctx.errors, ent);
|
||||
}
|
||||
|
||||
ctx->jobs++;
|
||||
|
||||
exactness_ctx.tests_executed++;
|
||||
|
||||
if (ctx->last && EINA_INLIST_GET(ctx->last)->next)
|
||||
{
|
||||
ctx->last = EINA_INLIST_CONTAINER_GET(
|
||||
EINA_INLIST_GET(ctx->last)->next, List_Entry);
|
||||
|
||||
_job_dispatch(ctx->last, ctx);
|
||||
}
|
||||
|
||||
/* If all jobs are done. */
|
||||
if (ctx->jobs == exactness_config.jobs)
|
||||
{
|
||||
free(ctx);
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx)
|
||||
{
|
||||
char buf[SCHEDULER_CMD_SIZE];
|
||||
Ecore_Exe *exe;
|
||||
|
||||
if (ctx->jobs == 0)
|
||||
return EINA_FALSE;
|
||||
ctx->jobs--;
|
||||
|
||||
ctx->prepare_func(ent, buf);
|
||||
|
||||
if (!_job_del_callback_handler)
|
||||
{
|
||||
_job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||
_job_deleted_cb, ctx);
|
||||
}
|
||||
|
||||
exe = ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent);
|
||||
|
||||
if (!exe)
|
||||
{
|
||||
fprintf(stderr, "Failed executing test '%s'\n", ent->name);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
scheduler_run(Scheduler_Cb prepare_func, List_Entry *list)
|
||||
{
|
||||
Scheduler_Ctx *ctx = calloc(1, sizeof(*ctx));
|
||||
List_Entry *list_itr;
|
||||
ctx->jobs = exactness_config.jobs;
|
||||
ctx->prepare_func = prepare_func;
|
||||
|
||||
EINA_INLIST_FOREACH(list, list_itr)
|
||||
{
|
||||
if (!_job_dispatch(list_itr, ctx))
|
||||
break;
|
||||
ctx->last = list_itr;
|
||||
}
|
||||
}
|
||||
static void
|
||||
_run_command_prepare(const List_Entry *ent, Run_Mode mode, char *buf)
|
||||
{
|
||||
Eina_Strbuf *sbuf = eina_strbuf_new();
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_VERBOSE=%d ", exactness_config.verbose);
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_FILE_NAME='%s/%s.rec' ",
|
||||
exactness_config.base_dir, ent->name);
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_TEST_NAME='%s' ", ent->name);
|
||||
switch (mode)
|
||||
{
|
||||
case RUN_SIMULATION:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case RUN_PLAY:
|
||||
{
|
||||
eina_strbuf_append(sbuf, "ELM_ENGINE='buffer' ");
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s/%s' ",
|
||||
exactness_config.dest_dir, CURRENT_SUBDIR);
|
||||
if (exactness_config.store_objects)
|
||||
eina_strbuf_append(sbuf, "TSUITE_STORE_OBJECTS=1 ");
|
||||
break;
|
||||
}
|
||||
case RUN_INIT:
|
||||
{
|
||||
eina_strbuf_append(sbuf, "ELM_ENGINE='buffer' ");
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s/%s' ",
|
||||
exactness_config.dest_dir, ORIG_SUBDIR);
|
||||
if (exactness_config.store_objects)
|
||||
eina_strbuf_append(sbuf, "TSUITE_STORE_OBJECTS=1 ");
|
||||
break;
|
||||
}
|
||||
case RUN_RECORD:
|
||||
{
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s' ",
|
||||
exactness_config.dest_dir);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
eina_strbuf_append_printf(sbuf, "LD_PRELOAD='%s/exactness/libexactness_%s.so' %s %s %s",
|
||||
PACKAGE_LIBDIR, mode == RUN_RECORD ? "recorder" : "player",
|
||||
CONFIG, exactness_config.wrap_command, ent->command);
|
||||
strncpy(buf, eina_strbuf_string_get(sbuf), SCHEDULER_CMD_SIZE-1);
|
||||
eina_strbuf_free(sbuf);
|
||||
if (exactness_config.verbose) printf("Command: %s\n", buf);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_simulation(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_SIMULATION, buf);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_check_prefix(const char *prefix, const char *name)
|
||||
{
|
||||
unsigned int len = strlen(prefix);
|
||||
return (!strncmp(name, prefix, len) && (strlen(name) > len) && (name[len] == SHOT_DELIMITER));
|
||||
}
|
||||
|
||||
static void
|
||||
_prefix_rm_cb(const char *name, const char *path, void *data)
|
||||
{
|
||||
const char *prefix = data;
|
||||
if (_check_prefix(prefix, name))
|
||||
{
|
||||
char buf[EXACTNESS_PATH_MAX];
|
||||
snprintf(buf, EXACTNESS_PATH_MAX, "%s/%s", path, name);
|
||||
if (unlink(buf))
|
||||
{
|
||||
printf("Failed deleting '%s/%s': ", path, name);
|
||||
perror("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_prefix_rm(const char *dir, const char *prefix)
|
||||
{
|
||||
eina_file_dir_list(dir, 0, _prefix_rm_cb, (void *) prefix);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_play(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_PLAY, buf);
|
||||
|
||||
run_test_prefix_rm(CURRENT_SUBDIR, ent->name);
|
||||
if (exactness_config.verbose)
|
||||
{
|
||||
printf("Running %s\n", ent->name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_record(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_RECORD, buf);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_init(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_INIT, buf);
|
||||
|
||||
run_test_prefix_rm(ORIG_SUBDIR, ent->name);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_file_sha1_get(const char *filename, unsigned char *result)
|
||||
{
|
||||
Eina_File *f = NULL;
|
||||
const char *key = "0123456789abcde";
|
||||
int key_len = strlen(key);
|
||||
unsigned int size = 0;
|
||||
Eina_Binbuf *buf = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
f = eina_file_open(filename, EINA_FALSE);
|
||||
if (!f) goto false;
|
||||
size = eina_file_size_get(f);
|
||||
if (size < 1) goto false;
|
||||
data = eina_file_map_all(f, EINA_FILE_POPULATE);
|
||||
if (!data) goto false;
|
||||
|
||||
buf = eina_binbuf_manage_new(data, size, EINA_TRUE);
|
||||
if (!buf)
|
||||
{
|
||||
fprintf(stderr, "Could not create Binary Buffer");
|
||||
goto false;
|
||||
}
|
||||
if (!emile_binbuf_hmac_sha1(key, key_len, buf, result))
|
||||
{
|
||||
fprintf(stderr, "Cannot generate sha1 for image");
|
||||
goto false;
|
||||
}
|
||||
eina_binbuf_free(buf);
|
||||
eina_file_close(f);
|
||||
return EINA_TRUE;
|
||||
|
||||
false:
|
||||
if (buf) eina_binbuf_free(buf);
|
||||
if (f) eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
#define _DIGEST_SIZE 20
|
||||
static Eina_Bool
|
||||
_is_equal(const char *filename1, const char *filename2)
|
||||
{
|
||||
unsigned char res1[_DIGEST_SIZE], res2[_DIGEST_SIZE];
|
||||
if (!_file_sha1_get(filename1, res1))
|
||||
return EINA_FALSE;
|
||||
if (!_file_sha1_get(filename2, res2))
|
||||
return EINA_FALSE;
|
||||
|
||||
return !memcmp(res1, res2, _DIGEST_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
_compare_list_cb(const char *name, const char *path EINA_UNUSED, void *data)
|
||||
{
|
||||
const char *prefix = data;
|
||||
if (_check_prefix(prefix, name))
|
||||
{
|
||||
char filename1[EXACTNESS_PATH_MAX], filename2[EXACTNESS_PATH_MAX];
|
||||
snprintf(filename1, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, ORIG_SUBDIR, name);
|
||||
snprintf(filename2, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, CURRENT_SUBDIR, name);
|
||||
if (!_is_equal(filename1, filename2))
|
||||
{
|
||||
char buf[EXACTNESS_PATH_MAX];
|
||||
exactness_ctx.compare_errors =
|
||||
eina_list_append(exactness_ctx.compare_errors,
|
||||
strdup(name));
|
||||
|
||||
/* FIXME: Clean up. */
|
||||
snprintf(buf, EXACTNESS_PATH_MAX,
|
||||
"compare '%s' '%s' '%s/%s/comp_%s'",
|
||||
filename1, filename2,
|
||||
exactness_config.dest_dir,
|
||||
CURRENT_SUBDIR, name);
|
||||
if (system(buf))
|
||||
{
|
||||
fprintf(stderr, "Failed image comparing '%s'\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_compare(const List_Entry *ent)
|
||||
{
|
||||
char origdir[EXACTNESS_PATH_MAX];
|
||||
snprintf(origdir, EXACTNESS_PATH_MAX, "%s/%s", exactness_config.dest_dir, ORIG_SUBDIR);
|
||||
eina_file_dir_list(origdir, 0, _compare_list_cb, ent->name);
|
||||
}
|
||||
|
||||
List_Entry *
|
||||
list_file_load(const char *filename)
|
||||
{
|
||||
List_Entry *ret = NULL;
|
||||
char buf[BUF_SIZE] = "";
|
||||
FILE *file;
|
||||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
perror("Failed opening list file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(buf, BUF_SIZE, file))
|
||||
{
|
||||
/* Skip comment/empty lines. */
|
||||
if ((*buf == '#') || (*buf == '\n') || (!*buf))
|
||||
continue;
|
||||
|
||||
char *tmp;
|
||||
List_Entry *cur = calloc(1, sizeof(*cur));
|
||||
cur->name = strdup(buf);
|
||||
|
||||
/* Set the command to the second half and put a \0 in between. */
|
||||
tmp = strchr(cur->name, ' ');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
cur->command = tmp + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: error. */
|
||||
cur->command = "";
|
||||
}
|
||||
|
||||
/* Replace the newline char with a \0. */
|
||||
tmp = strchr(cur->command, '\n');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
ret = EINA_INLIST_CONTAINER_GET(
|
||||
eina_inlist_append(EINA_INLIST_GET(ret), EINA_INLIST_GET(cur)),
|
||||
List_Entry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
list_file_free(List_Entry *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
List_Entry *ent = list;
|
||||
list = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(list)->next,
|
||||
List_Entry);
|
||||
|
||||
free(ent->name);
|
||||
free(ent);
|
||||
/* we don't free ent->command because it's allocated together. */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_errors_sort_cb(List_Entry *a, List_Entry *b)
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#include "exactness_config.h"
|
||||
|
||||
Exactness_Config exactness_config;
|
||||
Exactness_Ctx exactness_ctx;
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef EXACTNESS_CONFIG_H
|
||||
#define EXACTNESS_CONFIG_H
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
typedef struct _Exactness_Config Exactness_Config;
|
||||
|
||||
struct _Exactness_Config
|
||||
{
|
||||
unsigned short jobs;
|
||||
char *base_dir;
|
||||
char *dest_dir;
|
||||
char *wrap_command;
|
||||
Eina_Bool verbose;
|
||||
Eina_Bool store_objects;
|
||||
};
|
||||
|
||||
extern Exactness_Config exactness_config;
|
||||
|
||||
typedef struct _Exactness_Ctx Exactness_Ctx;
|
||||
|
||||
struct _Exactness_Ctx
|
||||
{
|
||||
unsigned int tests_executed;
|
||||
Eina_List *errors;
|
||||
Eina_List *compare_errors;
|
||||
};
|
||||
|
||||
extern Exactness_Ctx exactness_ctx;
|
||||
|
||||
#define ORIG_SUBDIR "orig"
|
||||
#define CURRENT_SUBDIR "current"
|
||||
|
||||
#define EXACTNESS_PATH_MAX 1024
|
||||
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "list_file.h"
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
List_Entry *
|
||||
list_file_load(const char *filename)
|
||||
{
|
||||
List_Entry *ret = NULL;
|
||||
char buf[BUF_SIZE] = "";
|
||||
FILE *file;
|
||||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
perror("Failed opening list file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(buf, BUF_SIZE, file))
|
||||
{
|
||||
/* Skip comment/empty lines. */
|
||||
if ((*buf == '#') || (*buf == '\n') || (!*buf))
|
||||
continue;
|
||||
|
||||
char *tmp;
|
||||
List_Entry *cur = calloc(1, sizeof(*cur));
|
||||
cur->name = strdup(buf);
|
||||
|
||||
/* Set the command to the second half and put a \0 in between. */
|
||||
tmp = strchr(cur->name, ' ');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
cur->command = tmp + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: error. */
|
||||
cur->command = "";
|
||||
}
|
||||
|
||||
/* Replace the newline char with a \0. */
|
||||
tmp = strchr(cur->command, '\n');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
ret = EINA_INLIST_CONTAINER_GET(
|
||||
eina_inlist_append(EINA_INLIST_GET(ret), EINA_INLIST_GET(cur)),
|
||||
List_Entry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
list_file_free(List_Entry *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
List_Entry *ent = list;
|
||||
list = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(list)->next,
|
||||
List_Entry);
|
||||
|
||||
free(ent->name);
|
||||
free(ent);
|
||||
/* we don't free ent->command because it's allocated together. */
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef LIST_FILE_H
|
||||
#define LIST_FILE_H
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
typedef struct _List_Entry List_Entry;
|
||||
|
||||
struct _List_Entry
|
||||
{
|
||||
EINA_INLIST;
|
||||
char *name;
|
||||
const char *command;
|
||||
};
|
||||
|
||||
List_Entry *list_file_load(const char *filename);
|
||||
void list_file_free(List_Entry *list);
|
||||
#endif
|
|
@ -1,231 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "scheduler.h"
|
||||
#include "run_test.h"
|
||||
#include "list_file.h"
|
||||
#include "exactness_config.h"
|
||||
#include "exactness_private.h"
|
||||
|
||||
#include "tsuite_file_data.h"
|
||||
|
||||
#define CONFIG "ELM_SCALE=1 ELM_FINGER_SIZE=10"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RUN_SIMULATION,
|
||||
RUN_PLAY,
|
||||
RUN_RECORD,
|
||||
RUN_INIT
|
||||
} Run_Mode;
|
||||
|
||||
static void
|
||||
_run_command_prepare(const List_Entry *ent, Run_Mode mode, char *buf)
|
||||
{
|
||||
Eina_Strbuf *sbuf = eina_strbuf_new();
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_VERBOSE=%d ", exactness_config.verbose);
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_FILE_NAME='%s/%s.rec' ",
|
||||
exactness_config.base_dir, ent->name);
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_TEST_NAME='%s' ", ent->name);
|
||||
switch (mode)
|
||||
{
|
||||
case RUN_SIMULATION:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case RUN_PLAY:
|
||||
{
|
||||
eina_strbuf_append(sbuf, "ELM_ENGINE='buffer' ");
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s/%s' ",
|
||||
exactness_config.dest_dir, CURRENT_SUBDIR);
|
||||
if (exactness_config.store_objects)
|
||||
eina_strbuf_append(sbuf, "TSUITE_STORE_OBJECTS=1 ");
|
||||
break;
|
||||
}
|
||||
case RUN_INIT:
|
||||
{
|
||||
eina_strbuf_append(sbuf, "ELM_ENGINE='buffer' ");
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s/%s' ",
|
||||
exactness_config.dest_dir, ORIG_SUBDIR);
|
||||
if (exactness_config.store_objects)
|
||||
eina_strbuf_append(sbuf, "TSUITE_STORE_OBJECTS=1 ");
|
||||
break;
|
||||
}
|
||||
case RUN_RECORD:
|
||||
{
|
||||
eina_strbuf_append_printf(sbuf, "TSUITE_DEST_DIR='%s' ",
|
||||
exactness_config.dest_dir);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
eina_strbuf_append_printf(sbuf, "LD_PRELOAD='%s/exactness/libexactness_%s.so' %s %s %s",
|
||||
PACKAGE_LIBDIR, mode == RUN_RECORD ? "recorder" : "player",
|
||||
CONFIG, exactness_config.wrap_command, ent->command);
|
||||
strncpy(buf, eina_strbuf_string_get(sbuf), SCHEDULER_CMD_SIZE-1);
|
||||
eina_strbuf_free(sbuf);
|
||||
if (exactness_config.verbose) printf("Command: %s\n", buf);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_simulation(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_SIMULATION, buf);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_play(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_PLAY, buf);
|
||||
|
||||
run_test_prefix_rm(CURRENT_SUBDIR, ent->name);
|
||||
if (exactness_config.verbose)
|
||||
{
|
||||
printf("Running %s\n", ent->name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_record(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_RECORD, buf);
|
||||
}
|
||||
|
||||
void
|
||||
run_test_init(const List_Entry *ent, char *buf)
|
||||
{
|
||||
_run_command_prepare(ent, RUN_INIT, buf);
|
||||
|
||||
run_test_prefix_rm(ORIG_SUBDIR, ent->name);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_file_sha1_get(const char *filename, unsigned char *result)
|
||||
{
|
||||
Eina_File *f = NULL;
|
||||
const char *key = "0123456789abcde";
|
||||
int key_len = strlen(key);
|
||||
unsigned int size = 0;
|
||||
Eina_Binbuf *buf = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
f = eina_file_open(filename, EINA_FALSE);
|
||||
if (!f) goto false;
|
||||
size = eina_file_size_get(f);
|
||||
if (size < 1) goto false;
|
||||
data = eina_file_map_all(f, EINA_FILE_POPULATE);
|
||||
if (!data) goto false;
|
||||
|
||||
buf = eina_binbuf_manage_new(data, size, EINA_TRUE);
|
||||
if (!buf)
|
||||
{
|
||||
fprintf(stderr, "Could not create Binary Buffer");
|
||||
goto false;
|
||||
}
|
||||
if (!emile_binbuf_hmac_sha1(key, key_len, buf, result))
|
||||
{
|
||||
fprintf(stderr, "Cannot generate sha1 for image");
|
||||
goto false;
|
||||
}
|
||||
eina_binbuf_free(buf);
|
||||
eina_file_close(f);
|
||||
return EINA_TRUE;
|
||||
|
||||
false:
|
||||
if (buf) eina_binbuf_free(buf);
|
||||
if (f) eina_file_close(f);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
#define _DIGEST_SIZE 20
|
||||
static Eina_Bool
|
||||
_is_equal(const char *filename1, const char *filename2)
|
||||
{
|
||||
unsigned char res1[_DIGEST_SIZE], res2[_DIGEST_SIZE];
|
||||
if (!_file_sha1_get(filename1, res1))
|
||||
return EINA_FALSE;
|
||||
if (!_file_sha1_get(filename2, res2))
|
||||
return EINA_FALSE;
|
||||
|
||||
return !memcmp(res1, res2, _DIGEST_SIZE);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_check_prefix(const char *prefix, const char *name)
|
||||
{
|
||||
unsigned int len = strlen(prefix);
|
||||
return (!strncmp(name, prefix, len) && (strlen(name) > len) && (name[len] == SHOT_DELIMITER));
|
||||
}
|
||||
|
||||
static void
|
||||
_compare_list_cb(const char *name, const char *path EINA_UNUSED, void *data)
|
||||
{
|
||||
const char *prefix = data;
|
||||
if (_check_prefix(prefix, name))
|
||||
{
|
||||
char filename1[EXACTNESS_PATH_MAX], filename2[EXACTNESS_PATH_MAX];
|
||||
snprintf(filename1, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, ORIG_SUBDIR, name);
|
||||
snprintf(filename2, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, CURRENT_SUBDIR, name);
|
||||
if (!_is_equal(filename1, filename2))
|
||||
{
|
||||
const char *ext = strrchr(name, '.');
|
||||
if (!strcmp(ext, ".eet"))
|
||||
{
|
||||
if (!objects_files_compare(filename1, filename2, EINA_FALSE))
|
||||
{
|
||||
fprintf(stderr, "Failed objects comparing '%s'\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[EXACTNESS_PATH_MAX];
|
||||
exactness_ctx.compare_errors =
|
||||
eina_list_append(exactness_ctx.compare_errors,
|
||||
strdup(name));
|
||||
|
||||
/* FIXME: Clean up. */
|
||||
snprintf(buf, EXACTNESS_PATH_MAX,
|
||||
"compare '%s' '%s' '%s/%s/comp_%s'",
|
||||
filename1, filename2,
|
||||
exactness_config.dest_dir,
|
||||
CURRENT_SUBDIR, name);
|
||||
if (system(buf))
|
||||
{
|
||||
fprintf(stderr, "Failed image comparing '%s'\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_compare(const List_Entry *ent)
|
||||
{
|
||||
char origdir[EXACTNESS_PATH_MAX];
|
||||
snprintf(origdir, EXACTNESS_PATH_MAX, "%s/%s", exactness_config.dest_dir, ORIG_SUBDIR);
|
||||
eina_file_dir_list(origdir, 0, _compare_list_cb, ent->name);
|
||||
}
|
||||
|
||||
static void
|
||||
_prefix_rm_cb(const char *name, const char *path, void *data)
|
||||
{
|
||||
const char *prefix = data;
|
||||
if (_check_prefix(prefix, name))
|
||||
{
|
||||
char buf[EXACTNESS_PATH_MAX];
|
||||
snprintf(buf, EXACTNESS_PATH_MAX, "%s/%s", path, name);
|
||||
if (unlink(buf))
|
||||
{
|
||||
printf("Failed deleting '%s/%s': ", path, name);
|
||||
perror("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_test_prefix_rm(const char *dir, const char *prefix)
|
||||
{
|
||||
eina_file_dir_list(dir, 0, _prefix_rm_cb, (void *) prefix);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef RUN_TEST_H
|
||||
#define RUN_TEST_H
|
||||
|
||||
#include <Emile.h>
|
||||
|
||||
#include "list_file.h"
|
||||
void run_test_simulation(const List_Entry *ent, char *buf);
|
||||
void run_test_play(const List_Entry *ent, char *buf);
|
||||
void run_test_record(const List_Entry *ent, char *buf);
|
||||
void run_test_init(const List_Entry *ent, char *buf);
|
||||
|
||||
void run_test_compare(const List_Entry *ent);
|
||||
|
||||
void run_test_prefix_rm(const char *dir, const char *prefix);
|
||||
|
||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||
#include <Ecore.h>
|
||||
|
||||
#include "scheduler.h"
|
||||
#include "exactness_config.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Scheduler_Cb prepare_func;
|
||||
List_Entry *last;
|
||||
unsigned short jobs;
|
||||
} Scheduler_Ctx;
|
||||
|
||||
static Ecore_Event_Handler *_job_del_callback_handler = NULL;
|
||||
|
||||
static Eina_Bool _job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx);
|
||||
|
||||
static Eina_Bool
|
||||
_job_deleted_cb(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event;
|
||||
Scheduler_Ctx *ctx = data;
|
||||
|
||||
if ((msg->exit_code != 0) || (msg->exit_signal != 0))
|
||||
{
|
||||
List_Entry *ent = ecore_exe_data_get(msg->exe);
|
||||
exactness_ctx.errors = eina_list_append(exactness_ctx.errors, ent);
|
||||
}
|
||||
|
||||
ctx->jobs++;
|
||||
|
||||
exactness_ctx.tests_executed++;
|
||||
|
||||
if (ctx->last && EINA_INLIST_GET(ctx->last)->next)
|
||||
{
|
||||
ctx->last = EINA_INLIST_CONTAINER_GET(
|
||||
EINA_INLIST_GET(ctx->last)->next, List_Entry);
|
||||
|
||||
_job_dispatch(ctx->last, ctx);
|
||||
}
|
||||
|
||||
/* If all jobs are done. */
|
||||
if (ctx->jobs == exactness_config.jobs)
|
||||
{
|
||||
free(ctx);
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx)
|
||||
{
|
||||
char buf[SCHEDULER_CMD_SIZE];
|
||||
Ecore_Exe *exe;
|
||||
|
||||
if (ctx->jobs == 0)
|
||||
return EINA_FALSE;
|
||||
ctx->jobs--;
|
||||
|
||||
ctx->prepare_func(ent, buf);
|
||||
|
||||
if (!_job_del_callback_handler)
|
||||
{
|
||||
_job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||
_job_deleted_cb, ctx);
|
||||
}
|
||||
|
||||
exe = ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent);
|
||||
|
||||
if (!exe)
|
||||
{
|
||||
fprintf(stderr, "Failed executing test '%s'\n", ent->name);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
scheduler_run(Scheduler_Cb prepare_func, List_Entry *list)
|
||||
{
|
||||
Scheduler_Ctx *ctx = calloc(1, sizeof(*ctx));
|
||||
List_Entry *list_itr;
|
||||
ctx->jobs = exactness_config.jobs;
|
||||
ctx->prepare_func = prepare_func;
|
||||
|
||||
EINA_INLIST_FOREACH(list, list_itr)
|
||||
{
|
||||
if (!_job_dispatch(list_itr, ctx))
|
||||
break;
|
||||
ctx->last = list_itr;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef SCHEDULER_H
|
||||
#define SCHEDULER_H
|
||||
|
||||
#include "list_file.h"
|
||||
|
||||
#define SCHEDULER_CMD_SIZE 1024
|
||||
|
||||
typedef void (*Scheduler_Cb)(const List_Entry *, char *);
|
||||
|
||||
void scheduler_run(Scheduler_Cb prepare_func, List_Entry *list);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue