Support exu file for Exactness

The exu is a EET file for Exactness (Exactness Unit). It currently
contains the scenario and the images shots.
exactness_inspect supports it, as well as the player (only as output).
This commit is contained in:
Daniel Zaoui 2018-01-25 12:45:37 +02:00
parent 3dd58276a2
commit 5555a38c1e
4 changed files with 141 additions and 62 deletions

View File

@ -1,5 +1,6 @@
#include "config.h"
#include <Ecore.h>
#include <Ecore_File.h>
#include <Ecore_Getopt.h>
#include <Emile.h>
@ -58,13 +59,17 @@ _printf(int verbose, const char *fmt, ...)
static void
_run_command_prepare(const List_Entry *ent, char *buf)
{
char scn_path[EXACTNESS_PATH_MAX];
Eina_Strbuf *sbuf = eina_strbuf_new();
sprintf(scn_path, "%s/%s.exu", _base_dir, ent->name);
if (!ecore_file_exists(scn_path))
sprintf(scn_path, "%s/%s.rec", _base_dir, ent->name);
eina_strbuf_append_printf(sbuf,
"%s %s exactness_play %s %s%.*s -t '%s/%s.rec' ",
"%s %s exactness_play %s %s%.*s %s-t '%s' ",
CONFIG, _wrap_command ? _wrap_command : "",
_mode == RUN_SIMULATION ? "-s" : "",
_verbose ? "-" : "", _verbose, "vvvvvvvvvv",
_base_dir, ent->name
scn_path
);
if (_mode == RUN_PLAY)
eina_strbuf_append_printf(sbuf, "-o '%s/%s' ", _dest_dir, CURRENT_SUBDIR);
@ -354,7 +359,7 @@ static const Ecore_Getopt optdesc = {
"A pixel perfect test suite for EFL based applications.",
0,
{
ECORE_GETOPT_STORE_STR('b', "base-dir", "The location of the rec files."),
ECORE_GETOPT_STORE_STR('b', "base-dir", "The location of the exu/rec files."),
ECORE_GETOPT_STORE_STR('o', "output", "The location of the images."),
ECORE_GETOPT_STORE_STR('w', "wrap", "Use a custom command to launch the tests (e.g valgrind)."),
ECORE_GETOPT_STORE_USHORT('j', "jobs", "The number of jobs to run in parallel."),

View File

@ -276,8 +276,7 @@ _scn_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UN
char *ret = NULL;
unsigned int timestamp = evt_time_get(0, v);
char specific_output[1024];
if (!timestamp) eina_strbuf_append(buf, "BAD_TIME: ");
else eina_strbuf_append_printf(buf, "%.3f: ", timestamp / 1000.0);
eina_strbuf_append_printf(buf, "%.3f: ", timestamp / 1000.0);
eina_strbuf_append_printf(buf, "%s", _event_name_get(v));
_event_specific_info_get(v, specific_output);
if (*specific_output) eina_strbuf_append_printf(buf, " - %s", specific_output);
@ -603,23 +602,29 @@ main(int argc, char *argv[])
fprintf(stderr, "Extension required\n");
goto end;
}
if (!strcmp(ext, ".rec"))
if (!strcmp(ext, ".exu"))
{
Exactness_Unit *ex_unit;
Eet_File *file = eet_open(argv[arg], EET_FILE_MODE_READ);
if (!file)
{
fprintf(stderr, "Impossible to extract EET from %s\n", argv[arg]);
goto end;
}
ex_unit = eet_data_read(file, unit_desc_make(), CACHE_FILE_ENTRY);
eet_close(file);
_units = eina_list_append(_units, ex_unit);
}
else if (!strcmp(ext, ".rec"))
{
Exactness_Unit *ex_unit = calloc(1, sizeof(*ex_unit));
Timer_Data td;
Variant_st *v;
Eina_List *itr;
list = read_events(argv[arg], &td);
if (!list)
{
fprintf(stderr, "Issue while reading %s\n", argv[arg]);
goto end;
}
EINA_LIST_FOREACH(list->variant_list, itr, v)
{
unsigned int tm = evt_time_get(0, v);
if (tm) evt_time_set(tm - list->first_timestamp, v);
}
ex_unit->events = list->variant_list;
_units = eina_list_append(_units, ex_unit);
}
@ -702,8 +707,7 @@ main(int argc, char *argv[])
{
char specific_output[1024];
unsigned int timestamp = evt_time_get(0, v);
if (!timestamp) printf("BAD_TIME: ");
else printf("%.3f: ", (list->first_timestamp ? timestamp - list->first_timestamp : timestamp) / 1000.0);
printf("%.3f: ", (list->first_timestamp ? timestamp - list->first_timestamp : timestamp) / 1000.0);
printf("%s", _event_name_get(v));
_event_specific_info_get(v, specific_output);
if (*specific_output) printf(" - %s", specific_output);

View File

@ -24,7 +24,17 @@
#define MAX_PATH 1024
#define IMAGE_FILENAME_EXT ".png"
static const char *_dest_dir = ".";
typedef enum
{
DEST_UNKNOWN,
DEST_DIR,
DEST_EXU
} Dest_Type;
static Dest_Type _dest_type = DEST_UNKNOWN;
static const char *_dest = NULL;
static Exactness_Unit *_dest_unit = NULL;
static const char *_rec_filename = NULL;
static const char *_test_name = NULL;
@ -54,50 +64,61 @@ _printf(int verbose, const char *fmt, ...)
static void
_shot_do(Evas *e)
{
Ecore_Evas *ee = NULL, *ee_orig;
Evas_Object *o;
Ecore_Evas *ee_orig;
unsigned int *pixels;
int w, h, dir_name_len = 0;
char *filename;
int w, h;
if (!e) return;
dir_name_len = strlen(_dest_dir) + 1; /* includes space of a '/' */
filename = malloc(strlen(_test_name) + strlen(IMAGE_FILENAME_EXT) +
dir_name_len + 8); /* also space for serial */
sprintf(filename, "%s/%s%c%03d%s", _dest_dir, _test_name,
SHOT_DELIMITER, _cur_shot_id, IMAGE_FILENAME_EXT);
_printf(1, "Shot taken (%s).\n", filename);
ee_orig = ecore_evas_ecore_evas_get(e);
ecore_evas_manual_render(ee_orig);
pixels = (void *)ecore_evas_buffer_pixels_get(ee_orig);
if (!pixels) goto end;
if (!pixels) return;
ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h);
if ((w < 1) || (h < 1)) goto end;
if ((w < 1) || (h < 1)) return;
_ignore_evas_creation++;
ee = ecore_evas_buffer_new(1, 1);
_ignore_evas_creation--;
o = evas_object_image_add(ecore_evas_get(ee));
evas_object_image_alpha_set(o, ecore_evas_alpha_get(ee_orig));
evas_object_image_size_set(o, w, h);
evas_object_image_data_set(o, pixels);
if (!evas_object_image_save(o, filename, NULL, NULL))
if (_dest_type == DEST_DIR)
{
printf("Cannot save widget to <%s>\n", filename);
}
int dir_name_len;
char *filename;
Evas_Object *o;
Ecore_Evas *ee;
end:
if (ee)
{
_ignore_evas_creation++;
ee = ecore_evas_buffer_new(1, 1);
_ignore_evas_creation--;
o = evas_object_image_add(ecore_evas_get(ee));
evas_object_image_alpha_set(o, ecore_evas_alpha_get(ee_orig));
evas_object_image_size_set(o, w, h);
evas_object_image_data_set(o, pixels);
dir_name_len = strlen(_dest) + 1; /* includes space of a '/' */
filename = malloc(strlen(_test_name) + strlen(IMAGE_FILENAME_EXT) +
dir_name_len + 8); /* also space for serial */
sprintf(filename, "%s/%s%c%03d%s", _dest, _test_name,
SHOT_DELIMITER, _cur_shot_id, IMAGE_FILENAME_EXT);
_printf(1, "Shot taken (%s).\n", filename);
if (!evas_object_image_save(o, filename, NULL, NULL))
{
printf("Cannot save widget to <%s>\n", filename);
}
free(filename);
ecore_evas_free(ee);
}
free(filename);
else if (_dest_type == DEST_EXU)
{
Exactness_Image *ex_img = malloc(sizeof(*ex_img));
ex_img->w = w;
ex_img->h = h;
ex_img->pixels_count = w * h * 4;
ex_img->pixels = malloc(ex_img->pixels_count);
memcpy(ex_img->pixels, pixels, ex_img->pixels_count);
_dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img);
_printf(1, "Shot taken (in .exu).\n");
}
}
static Eina_Bool
@ -312,10 +333,7 @@ _feed_event(void *data EINA_UNUSED)
_printf(2, "%s take shot timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
if (rect) evas_object_color_set(rect, 0, 0, 255, 255);
_cur_shot_id++;
if (_dest_dir)
{
if (e) _shot_do(e);
}
if (_dest_type != DEST_UNKNOWN && e) _shot_do(e);
break;
}
default: /* All non-input events are not handeled */
@ -470,8 +488,12 @@ _print_usage(const char *progn, FILE *outf)
fprintf(outf, "Usage: %s [options] [program]\n", progn);
fprintf(outf, "Options:\n"
" -s Show the application on the screen\n"
" -o shots_dest Set the destination folder for the shots.\n"
" If omitted, the shots are created in the current directory\n"
" -o shots_dir/output.exu Set the destination for the shots.\n"
" If a .exu is given, the shots are stored in the file.\n"
" Otherwise the given path is considered as a directory\n"
" where shots will be stored.\n"
" If omitted, the output type (exu or dir) is determined\n"
" by the given test extenstion (resp. exu or rec).\n"
" -t file.rec Test to run on the given application\n"
" -v Verbose mode\n"
" -h Print this message and exit\n"
@ -479,16 +501,17 @@ _print_usage(const char *progn, FILE *outf)
}
static Eina_Bool
_mkdir(const char *dir)
_mkdir(const char *path, Eina_Bool skip_last)
{
if (!ecore_file_exists(dir))
if (!ecore_file_exists(path))
{
const char *cur = dir + 1;
const char *cur = path + 1;
do
{
char *slash = strchr(cur, '/');
if (slash) *slash = '\0';
if (!ecore_file_exists(dir) && !ecore_file_mkdir(dir)) return EINA_FALSE;
else if (skip_last) return EINA_TRUE;
if (!ecore_file_exists(path) && !ecore_file_mkdir(path)) return EINA_FALSE;
if (slash) *slash = '/';
if (slash) cur = slash + 1;
else cur = NULL;
@ -532,17 +555,43 @@ int main(int argc, char **argv)
}
case 'o':
{
_dest_dir = eina_stringshare_add(optarg);
if (!_mkdir(_dest_dir))
_dest = eina_stringshare_add(optarg);
if (!strcmp(_dest + strlen(_dest) - 4,".exu"))
{
fprintf(stderr, "Directory %s cannot be created\n", _dest_dir);
goto end;
_dest_type = DEST_EXU;
if (!_mkdir(_dest, EINA_TRUE))
{
fprintf(stderr, "Path for %s cannot be created\n", _dest);
goto end;
}
}
else
{
_dest_type = DEST_DIR;
if (!_mkdir(_dest, EINA_FALSE))
{
fprintf(stderr, "Directory %s cannot be created\n", _dest);
goto end;
}
}
break;
}
case 't':
{
_rec_filename = eina_stringshare_add(optarg);
if (_dest_type == DEST_UNKNOWN)
{
if (!strcmp(_rec_filename + strlen(_rec_filename) - 4,".exu"))
{
_dest_type = DEST_EXU;
_dest = "./output.exu";
}
else if (!strcmp(_rec_filename + strlen(_rec_filename) - 4,".rec"))
{
_dest_type = DEST_DIR;
_dest = ".";
}
}
break;
}
case 'v':
@ -583,6 +632,10 @@ int main(int argc, char **argv)
if (dot) *dot = '\0';
}
if (_dest_type == DEST_EXU)
{
_dest_unit = calloc(1, sizeof(*_dest_unit));
}
efl_object_init();
evas_init();
@ -602,7 +655,17 @@ int main(int argc, char **argv)
_printf(1, "\n");
ecore_evas_callback_new_set(_my_evas_new);
pret = _prg_invoke(_prg_full_path_guess(argv[0]), argc - opt_args, argv);
_prg_invoke(_prg_full_path_guess(argv[0]), argc - optind, argv);
if (_dest_unit)
{
_dest_unit->events = _events_list->variant_list;
Eet_Data_Descriptor *unit_edd = unit_desc_make();
Eet_File *file = eet_open(_dest, EET_FILE_MODE_WRITE);
eet_data_write(file, unit_edd, CACHE_FILE_ENTRY, _dest_unit, EINA_TRUE);
eet_close(file);
}
pret = 0;
end:
eina_shutdown();

View File

@ -216,6 +216,8 @@ Lists_st *
read_events(const char *filename, Timer_Data *td)
{
Lists_st *vr_list;
Eina_List *itr;
Variant_st *v;
Eet_File *fp = eet_open(filename, EET_FILE_MODE_READ);
if (!fp)
{
@ -231,6 +233,11 @@ read_events(const char *filename, Timer_Data *td)
if (!vr_list->variant_list)
return NULL;
EINA_LIST_FOREACH(vr_list->variant_list, itr, v)
{
unsigned int tm = evt_time_get(0, v);
if (tm) evt_time_set(tm - vr_list->first_timestamp, v);
}
#ifdef DEBUG_TSUITE
print_events(vr_list);
#endif
@ -959,7 +966,7 @@ unit_desc_make(void)
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Image);
img_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(img_d, Exactness_Image, "w", w, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(img_d, Exactness_Image, "h", w, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(img_d, Exactness_Image, "h", h, EET_T_UINT);
eet_data_descriptor_element_add(img_d, "pixels", EET_T_INT, EET_G_VAR_ARRAY,
(char *)(&(ex_img.pixels)) - (char *)(&(ex_img)),
(char *)(&(ex_img.pixels_count)) - (char *)(&(ex_img)), NULL, NULL);