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