From 5555a38c1e0e55422747f10d69ecc048993431db Mon Sep 17 00:00:00 2001 From: Daniel Zaoui Date: Thu, 25 Jan 2018 12:45:37 +0200 Subject: [PATCH] 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). --- src/bin/exactness.c | 11 ++- src/bin/inspect.c | 28 ++++--- src/bin/player.c | 155 ++++++++++++++++++++++++++----------- src/lib/tsuite_file_data.c | 9 ++- 4 files changed, 141 insertions(+), 62 deletions(-) diff --git a/src/bin/exactness.c b/src/bin/exactness.c index 32a4362..b51ae37 100644 --- a/src/bin/exactness.c +++ b/src/bin/exactness.c @@ -1,5 +1,6 @@ #include "config.h" #include +#include #include #include @@ -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."), diff --git a/src/bin/inspect.c b/src/bin/inspect.c index 218c173..51c59a6 100644 --- a/src/bin/inspect.c +++ b/src/bin/inspect.c @@ -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); diff --git a/src/bin/player.c b/src/bin/player.c index ad3bb5a..9e7a923 100644 --- a/src/bin/player.c +++ b/src/bin/player.c @@ -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(); diff --git a/src/lib/tsuite_file_data.c b/src/lib/tsuite_file_data.c index 05ac1a7..6e14cd5 100644 --- a/src/lib/tsuite_file_data.c +++ b/src/lib/tsuite_file_data.c @@ -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);