1 #include <cgreen/cdash_reporter.h> 2 #include <cgreen/reporter.h> 3 #include <cgreen/breadcrumb.h> 4 #include <errno.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <stdlib.h> 8 #include <stdio.h> 9 #include <time.h> 10 #include <string.h> 11 12 typedef int Printer(FILE *, const char *format, ...); 13 typedef time_t Timer(char *strtime); 14 typedef double DiffTimer(time_t t1, time_t t2); 15 16 typedef struct { 17 CDashInfo *cdash; 18 Printer *printer; 19 Timer *timer; 20 DiffTimer *difftimer; 21 int pipe_fd[2]; 22 time_t begin; 23 time_t startdatetime; 24 time_t enddatetime; 25 time_t teststarted; 26 time_t testfinished; 27 FILE *f_reporter; 28 } CdashMemo; 29 30 static void cdash_destroy_reporter(TestReporter *reporter); 31 static void cdash_reporter_suite_started(TestReporter *reporter, const char *name, const int number_of_tests); 32 static void cdash_reporter_testcase_started(TestReporter *reporter, const char *name); 33 34 static void show_failed(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments); 35 static void show_passed(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments); 36 static void show_incomplete(TestReporter *reporter, const char *name); 37 38 static void cdash_reporter_testcase_finished(TestReporter *reporter, const char *name); 39 static void cdash_reporter_suite_finished(TestReporter *reporter, const char *name); 40 41 static time_t cdash_build_stamp(char *sbuildstamp, size_t sb); 42 static time_t cdash_current_time(char *strtime); 43 static double cdash_enlapsed_time(time_t t1, time_t t2); 44 45 TestReporter *create_cdash_reporter(CDashInfo *cdash) { 46 TestReporter *reporter; 47 CdashMemo *memo; 48 FILE *fd; 49 char sbuildstamp[15]; 50 char strstart[30]; 51 char reporter_path[255]; 52 int rep_dir, strsize; 53 54 if (!cdash) 55 return NULL; 56 57 reporter = create_reporter(); 58 if (!reporter) 59 return NULL; 60 61 memo = (CdashMemo *) malloc(sizeof(CdashMemo)); 62 if (!memo) 63 return NULL; 64 65 memo->cdash = (CDashInfo *) cdash; 66 67 memo->printer = fprintf; 68 memo->timer = cdash_current_time; 69 memo->difftimer = cdash_enlapsed_time; 70 memo->begin = cdash_build_stamp(sbuildstamp, 15); 71 72 rep_dir = mkdir("./Testing", S_IXUSR|S_IRUSR|S_IWUSR|S_IXGRP|S_IRGRP|S_IXOTH|S_IRGRP); 73 if (rep_dir) 74 if (errno != EEXIST) 75 return NULL; 76 77 fd = fopen("./Testing/TAG", "w+"); 78 if (fd == NULL) 79 return NULL; 80 81 fprintf(fd,"%s\n%s\n", sbuildstamp, memo->cdash->type); 82 83 fclose(fd); 84 85 strsize = snprintf(reporter_path, 255, "./Testing/%s", sbuildstamp); 86 87 rep_dir = mkdir(reporter_path, S_IXUSR|S_IRUSR|S_IWUSR|S_IXGRP|S_IRGRP|S_IXOTH|S_IRGRP); 88 if (rep_dir) 89 if (errno != EEXIST) 90 return NULL; 91 92 strsize = snprintf( (char *) (reporter_path + strsize), (255 - strsize), "/Test.xml"); 93 94 fd = fopen(reporter_path, "w+"); 95 if (fd == NULL) 96 return NULL; 97 98 /* now the Test.xml is in place */ 99 memo->f_reporter = fd; 100 101 memo->startdatetime = cdash_current_time(strstart); 102 103 memo->printer(memo->f_reporter, 104 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 105 " <Site BuildName=\"%s\" BuildStamp=\"%s-%s\" Name=\"%s\" Generator=\"%s\"" 106 " OSName=\"%s\" Hostname=\"%s\" OSRelease=\"%s\"" 107 " OSVersion=\"%s\" OSPlatform=\"%s\"" 108 " Is64Bits=\"\" VendorString=\"\" VendorID=\"\"" 109 " FamilyID=\"\" ModelID=\"\" ProcessorCacheSize=\"\" NumberOfLogicalCPU=\"\"" 110 " NumberOfPhysicalCPU=\"\" TotalVirtualMemory=\"\" TotalPhysicalMemory=\"\"" 111 " LogicalProcessorsPerPhysical=\"\" ProcessorClockFrequency=\"\" >\n" 112 " <Testing>\n" 113 " <StartDateTime>%s</StartDateTime>\n" 114 " <TestList>\n" 115 " <Test></Test>\n" 116 " </TestList>\n", 117 memo->cdash->build, sbuildstamp, memo->cdash->type, memo->cdash->name, "Cgreen1.0.0", 118 memo->cdash->os_name, memo->cdash->hostname, memo->cdash->os_release, 119 memo->cdash->os_version, memo->cdash->os_platform, strstart); 120 121 fflush(memo->f_reporter); 122 123 reporter->destroy = &cdash_destroy_reporter; 124 reporter->start_suite = &cdash_reporter_suite_started; 125 reporter->start_test = &cdash_reporter_testcase_started; 126 reporter->show_fail = &show_failed; 127 reporter->show_pass = &show_passed; 128 reporter->show_incomplete = &show_incomplete; 129 reporter->finish_test = &cdash_reporter_testcase_finished; 130 reporter->finish_suite = &cdash_reporter_suite_finished; 131 reporter->memo = memo; 132 133 return reporter; 134 } 135 136 static void cdash_destroy_reporter(TestReporter *reporter) { 137 char endtime[30]; 138 139 CdashMemo *memo = (CdashMemo *)reporter->memo; 140 141 memo->enddatetime = cdash_current_time(endtime); 142 143 memo->printer(memo->f_reporter, " <EndDateTime>%s</EndDateTime>\n" 144 " <ElapsedMinutes>%.2f</ElapsedMinutes>\n" 145 " </Testing>\n" 146 "</Site>\n", endtime, memo->difftimer(memo->startdatetime, memo->enddatetime)); 147 148 destroy_reporter(reporter); 149 } 150 151 152 static void cdash_reporter_suite_started(TestReporter *reporter, const char *name, const int number_of_tests) { 153 reporter_start(reporter, name); 154 } 155 156 static void cdash_reporter_testcase_started(TestReporter *reporter, const char *name) { 157 CdashMemo *memo = (CdashMemo *)reporter->memo; 158 memo->teststarted = memo->timer(NULL); 159 reporter_start(reporter, name); 160 } 161 162 static void show_failed(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) { 163 const char *name; 164 char buffer[1000]; 165 float exectime; 166 CdashMemo *memo; 167 168 memo = (CdashMemo *)reporter->memo; 169 170 memo->testfinished = memo->timer(NULL); 171 172 exectime = memo->difftimer(memo->teststarted, memo->testfinished); 173 174 name = get_current_from_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb); 175 176 memo->printer(memo->f_reporter, 177 " <Test Status=\"failed\">\n"); 178 memo->printer(memo->f_reporter, 179 " <Name>%s</Name>\n" 180 " <Path>%s</Path>\n" 181 " <FullName>%s</FullName>\n" 182 " <FullCommandLine>at [%s] line [%d]</FullCommandLine>\n", name, file, file, file, line); 183 memo->printer(memo->f_reporter, 184 " <Results>\n" 185 " <NamedMeasurement type=\"numeric/double\" name=\"Execution Time\"><Value>%f</Value></NamedMeasurement>\n" 186 " <NamedMeasurement type=\"text/string\" name=\"Completion Status\"><Value>Completed</Value></NamedMeasurement>\n" 187 " <NamedMeasurement type=\"text/string\" name=\"Command Line\"><Value>%s</Value></NamedMeasurement>\n" 188 " <Measurement>\n" 189 " <Value>", exectime, name); 190 vsprintf(buffer, (message == NULL ? "Problem" : message), arguments); 191 memo->printer(memo->f_reporter, "%s", buffer); 192 memo->printer(memo->f_reporter, "</Value>\n" 193 " </Measurement>\n" 194 " </Results>\n" 195 " </Test>\n"); 196 } 197 198 static void show_passed(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) { 199 float exectime; 200 CdashMemo *memo = (CdashMemo *)reporter->memo; 201 const char *name = get_current_from_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb); 202 203 memo->testfinished = memo->timer(NULL); 204 exectime = memo->difftimer(memo->teststarted, memo->testfinished); 205 206 memo->printer(memo->f_reporter, 207 " <Test Status=\"passed\">\n"); 208 memo->printer(memo->f_reporter, "" 209 " <Name>%s</Name>\n" 210 " <Path>%s</Path>\n" 211 " <FullName>%s</FullName>\n" 212 " <FullCommandLine>at [%s] line [%d]</FullCommandLine>\n", name, file, file, file, line); 213 memo->printer(memo->f_reporter, 214 " <Results>\n" 215 " <NamedMeasurement type=\"numeric/double\" name=\"Execution Time\"><Value>%f</Value></NamedMeasurement>\n" 216 " <NamedMeasurement type=\"text/string\" name=\"Completion Status\"><Value>Completed</Value></NamedMeasurement>\n" 217 " <NamedMeasurement type=\"text/string\" name=\"Command Line\"><Value>%s</Value></NamedMeasurement>\n" 218 " <Measurement>\n" 219 " <Value></Value>\n" 220 " </Measurement>\n" 221 " </Results>\n" 222 " </Test>\n", exectime, name); 223 } 224 225 static void show_incomplete(TestReporter *reporter, const char *name) { 226 227 } 228 229 230 static void cdash_reporter_testcase_finished(TestReporter *reporter, const char *name) { 231 reporter_finish(reporter, name); 232 } 233 234 235 static void cdash_reporter_suite_finished(TestReporter *reporter, const char *name) { 236 reporter_finish(reporter, name); 237 } 238 239 static time_t cdash_build_stamp(char *sbuildstamp, size_t sb) { 240 time_t t1; 241 struct tm d1; 242 char s[15]; 243 244 t1 = time(0); 245 gmtime_r(&t1, &d1); 246 247 strftime(s, sizeof(s), "%Y%m%d-%H%M", &d1); 248 snprintf(sbuildstamp, sb, "%s", s); 249 250 return t1; 251 } 252 253 static time_t cdash_current_time(char *strtime) { 254 time_t t1; 255 struct tm d1; 256 char s[20]; 257 size_t i; 258 259 t1 = time(0); 260 gmtime_r(&t1, &d1); 261 262 if(strtime == NULL) 263 return t1; 264 265 i = strftime(s, 20, "%b %d %H:%M EDT", &d1); 266 267 strncpy(strtime, s, i+1); 268 269 return t1; 270 } 271 272 static double cdash_enlapsed_time(time_t t1, time_t t2) { 273 double diff; 274 275 diff = difftime(t2, t1); 276 return (diff == 0 ? 0 : (diff / 60)); 277 } 278