#include #include #include #include #include #include #include #include #include #include #include #include "outlog.h" #include "fileops.h" static FILE *ttys_out; static FILE *ttys_in; static int serial_before_all(struct list_head *TASK_LIST) { struct task *task; fprintf(ttys_out, "\n"); fprintf(ttys_out, "============================"); fprintf(ttys_out, " tasks list "); fprintf(ttys_out, "============================\n"); list_for_each_entry(task, TASK_LIST, lnode) fprintf(ttys_out, "%s\n", task->keypath); fprintf(ttys_out, "============================"); fprintf(ttys_out, " end "); fprintf(ttys_out, "============================\n"); return 0; } static int serial_after_one_end(struct task *task) { int ret = -1; struct tm *time; fprintf(ttys_out, "\n"); fprintf(ttys_out, "----------------------------"); fprintf(ttys_out, " %s ", task->keypath); fprintf(ttys_out, "----------------------------\n"); fprintf(ttys_out, "* task path : %s\n", task->keypath); fprintf(ttys_out, "* task command : %s\n", task->command); fprintf(ttys_out, "* run times(real/max) : %d/%d\n", task->run_times, task->env.limit.run_times); fprintf(ttys_out, "* run parallel : %s\n", task->env.limit.run_parallel == true ? "yes" : "no"); fprintf(ttys_out, "* run alone : %s\n", task->env.limit.run_alone == true ? "yes" : "no"); fprintf(ttys_out, "* may reboot : %s\n", task->env.limit.may_reboot == true ? "yes" : "no"); fprintf(ttys_out, "* run once time limit : %ds\n", task->env.limit.testcase_run_once_time_sec); fprintf(ttys_out, "* run time limit : %ds\n", task->env.limit.testcase_run_time_sec); fprintf(ttys_out, "* timeout with : %s\n", task->env.limit.timeout_with == TASK_RESULT_PASS ? "pass" : "failed"); fprintf(ttys_out, "* exit once failed : %s\n", task->env.limit.exit_once_failed == true ? "yes" : "no"); fprintf(ttys_out, "* real-time log: %s\n", task->env.info.real_time_log == true ? "yes" : "no"); if (task->env.limit.may_reboot == true) fprintf(ttys_out, "* reboot/run times : %d/%d\n", task->rebooted_times, task->run_times); if (task->env.info.date == true) { fprintf(ttys_out, "* begin date : %s", ctime(&task->begin_date)); fprintf(ttys_out, "* end date : %s", ctime(&task->end_date)); } fprintf(ttys_out, "* result :\n"); fprintf(ttys_out, "* num pid pgid return begin end note\n"); for (int num = 0; num < task->run_times; num++) { fprintf(ttys_out, "* %7d%7d%8d%10d", num, -task->pid[num], abs(task->shmem->pgid), task->result[num]); time = gmtime(&task->begin_time[num]); fprintf(ttys_out, " %2.2d:%2.2d:%2.2d", time->tm_hour, time->tm_min, time->tm_sec); time = gmtime(&task->end_time[num]); fprintf(ttys_out, " %2.2d:%2.2d:%2.2d", time->tm_hour, time->tm_min, time->tm_sec); if (task->killed[num]) fprintf(ttys_out, " killed by signal %s(%d)\n", strsignal(task->killed[num]), task->killed[num]); else fprintf(ttys_out, "\n"); } if (task->env.info.resource == true && task->res != NULL) { fprintf(ttys_out, "* task resource :\n"); fprintf(ttys_out, "* user cpu time = %ld.%ld\n", task->res->ru_utime.tv_sec, task->res->ru_utime.tv_usec/1000); fprintf(ttys_out, "* system cpu time = %ld.%ld\n", task->res->ru_stime.tv_sec, task->res->ru_stime.tv_usec/1000); fprintf(ttys_out, "* maximum resident size = %ldkB\n", task->res->ru_maxrss); fprintf(ttys_out, "* page faults break times (without I/O) = %ld\n", task->res->ru_minflt); fprintf(ttys_out, "* page faults break times (with I/O) = %ld\n", task->res->ru_majflt); fprintf(ttys_out, "* input times = %ld\n", task->res->ru_inblock); fprintf(ttys_out, "* output times = %ld\n", task->res->ru_oublock); fprintf(ttys_out, "* wait resource actively times = %ld\n", task->res->ru_nvcsw); fprintf(ttys_out, "* wait resource passively times = %ld\n", task->res->ru_nivcsw); } // log if (task->logpath != NULL) { int fd = open(task->logpath, O_RDONLY); if (fd < 0) { ERROR("%s open %s failed\n", task->keypath, task->logpath); goto out; } fprintf(ttys_out, "* run log :\n"); fprintf(ttys_out, "****************\n"); cp_fd(fd, fileno(ttys_out)); close(fd); } else { fprintf(ttys_out, "* run log: real_time_log was set, None!\n"); } fprintf(ttys_out, "----------------------------"); fprintf(ttys_out, " end "); fprintf(ttys_out, "----------------------------\n"); ret = 0; out: return ret; } static int serial_after_all(struct list_head *TASK_LIST) { int result = 0; int num = 0; fprintf(ttys_out, "\n"); fprintf(ttys_out, "============================"); fprintf(ttys_out, " tasks result "); fprintf(ttys_out, "============================\n"); struct task *task = NULL; list_for_each_entry(task, TASK_LIST, lnode) { for (result = 0, num = 0; num < task->run_times; num++) { if (task->result[num] != 0) { result = task->result[num]; break; } } fprintf(ttys_out, "%s - ", task->keypath); if (result != 0) fprintf(ttys_out, "NO (failed in %d times with %d back)\n", num, task->result[num]); else fprintf(ttys_out, "YES\n"); } fprintf(ttys_out, "============================"); fprintf(ttys_out, " end "); fprintf(ttys_out, "============================\n"); return 0; } static int serial_interact_common(const char *testcase, const char *ask, char *reply, int len) { int ret = 0; fprintf(ttys_out, "\n========================"); fprintf(ttys_out, " Testcase Information "); fprintf(ttys_out, " ========================\n"); fprintf(ttys_out, "<%s>:\n", testcase); fprintf(ttys_out, "%s\n", ask); if (len != 0 && reply != NULL) { /* No Use But Fix Static Check */ fseek(ttys_out, 0, SEEK_END); if (fgets(reply, len, ttys_in) == NULL) { ERROR("fgets failed - %s\n", strerror(errno)); ret = -1; } len = strlen(reply); if (reply[len - 1] == '\n') reply[len - 1] = '\0'; } fprintf(ttys_out, "================================"); fprintf(ttys_out, " END "); fprintf(ttys_out, "==================================\n"); return ret; } static int serial_ask(const char *testcase, const char *ask, char *reply, int len) { int ret = serial_interact_common(testcase, ask, reply, len); return ret; } static int serial_tips(const char *testcase, const char *tips) { char resp[10] = {0}; int ret = serial_interact_common(testcase, tips, resp, 10); return ret; } static int serial_istrue(const char *testcase, const char *ask) { int ret = -1; int len = strlen(ask); char *buf = calloc(1, len + 10); if (buf == NULL) goto out; if (buf[len - 1] == '\n') buf[len - 1] = '\0'; sprintf(buf, "%s [Y|n]: ", ask); char resp[MAX_TEXT] = {0}; for (len = 0; len < 20; len++) { serial_interact_common(testcase, buf, resp, MAX_TEXT); switch (resp[0]) { case 'Y': case 'y': case '\0': ret = true; goto out; case 'N': case 'n': ret = false; goto out; default: continue; } } out: free(buf); return ret; } void module_init(void) { char tty_buf[100]; if (get_tty(tty_buf, 100) < 0) return; ttys_out = fopen(tty_buf, "w"); if (ttys_out == NULL) return; setlinebuf(ttys_out); ttys_in = fopen(tty_buf, "r"); if (ttys_in == NULL) return; outlog_register( serial_before_all, NULL, serial_after_one_end, serial_after_all); interact_register( serial_ask, serial_tips, serial_istrue, NULL, NULL); }