00001
00002
00003 #include "common.h"
00004 #include "hash.h"
00005 #include "dystring.h"
00006 #include "portable.h"
00007 #include "htmlPage.h"
00008 #include "errabort.h"
00009 #include "errCatch.h"
00010 #include "htmshell.h"
00011 #include "qa.h"
00012
00013 char *qaStringBetween(char *text, char *startPattern, char *endPattern)
00014
00015
00016
00017 {
00018 char *startMid = stringIn(startPattern, text);
00019 if (startMid != NULL)
00020 {
00021 char *endMid;
00022 int midSize;
00023 startMid += strlen(startPattern);
00024 endMid = stringIn(startMid, endPattern);
00025 if (endMid == NULL)
00026 {
00027 midSize = strlen(startMid);
00028 if (midSize > 100)
00029 midSize = 100;
00030 }
00031 else
00032 midSize = endMid - startMid;
00033 return cloneStringZ(startMid, midSize);
00034 }
00035 return NULL;
00036 }
00037
00038 char *qaScanForErrorMessage(char *text)
00039
00040
00041 {
00042 return qaStringBetween(text, htmlWarnStartPattern(), htmlWarnEndPattern());
00043 }
00044
00045 int qaCountBetween(char *s, char *startPattern, char *endPattern,
00046 char *midPattern)
00047
00048 {
00049 int count = 0;
00050 char *e;
00051 s = stringIn(startPattern, s);
00052 if (s != NULL)
00053 {
00054 s += strlen(startPattern);
00055 e = stringIn(endPattern, s);
00056 while (s < e)
00057 {
00058 if (startsWith(midPattern, s))
00059 ++count;
00060 s += 1;
00061 }
00062 }
00063 return count;
00064 }
00065
00066 void qaStatusReportOne(FILE *f, struct qaStatus *qs, char *format, ...)
00067
00068 {
00069 char *errMessage = qs->errMessage;
00070 char *severity = "ok";
00071 va_list args;
00072 va_start(args, format);
00073 if (errMessage == NULL)
00074 errMessage = "";
00075 else
00076 {
00077 if (qs->hardError)
00078 severity = "hard";
00079 else
00080 severity = "soft";
00081 }
00082
00083 vfprintf(f, format, args);
00084 fprintf(f, " %4.3fs (%s) %s\n", 0.001*qs->milliTime, severity, errMessage);
00085 va_end(args);
00086 }
00087
00088 static struct qaStatus *qaStatusOnPage(struct errCatch *errCatch,
00089 struct htmlPage *page, long startTime, struct htmlPage **retPage)
00090
00091
00092
00093
00094 {
00095 char *errMessage = NULL;
00096 struct qaStatus *qs;
00097 AllocVar(qs);
00098 if (errCatch->gotError || page == NULL)
00099 {
00100 errMessage = errCatch->message->string;
00101 qs->hardError = TRUE;
00102 }
00103 else
00104 {
00105 if (page->status->status != 200)
00106 {
00107 dyStringPrintf(errCatch->message, "HTTP status code %d\n",
00108 page->status->status);
00109 errMessage = errCatch->message->string;
00110 qs->hardError = TRUE;
00111 htmlPageFree(&page);
00112 }
00113 else
00114 {
00115 errMessage = qaScanForErrorMessage(page->fullText);
00116 }
00117 }
00118 qs->errMessage = cloneString(errMessage);
00119 if (qs->errMessage != NULL)
00120 subChar(qs->errMessage, '\n', ' ');
00121 qs->milliTime = clock1000() - startTime;
00122 if (retPage != NULL)
00123 *retPage = page;
00124 else
00125 htmlPageFree(&page);
00126 return qs;
00127 }
00128
00129 struct qaStatus *qaPageGet(char *url, struct htmlPage **retPage)
00130
00131 {
00132 struct errCatch *errCatch = errCatchNew();
00133 struct qaStatus *qs;
00134 struct htmlPage *page = NULL;
00135 long startTime = clock1000();
00136 if (errCatchStart(errCatch))
00137 {
00138 page = htmlPageGet(url);
00139 htmlPageValidateOrAbort(page);
00140 }
00141 else
00142 {
00143 htmlPageFree(&page);
00144 }
00145 errCatchEnd(errCatch);
00146 qs = qaStatusOnPage(errCatch, page, startTime, retPage);
00147 errCatchFree(&errCatch);
00148 return qs;
00149 }
00150
00151 struct qaStatus *qaPageFromForm(struct htmlPage *origPage, struct htmlForm *form,
00152 char *buttonName, char *buttonVal, struct htmlPage **retPage)
00153
00154 {
00155 struct errCatch *errCatch = errCatchNew();
00156 struct qaStatus *qs;
00157 struct htmlPage *page = NULL;
00158 long startTime = clock1000();
00159 if (errCatchStart(errCatch))
00160 {
00161 page = htmlPageFromForm(origPage, form, buttonName, buttonVal);
00162 htmlPageValidateOrAbort(page);
00163 }
00164 else
00165 {
00166 htmlPageFree(&page);
00167 }
00168 errCatchEnd(errCatch);
00169 qs = qaStatusOnPage(errCatch, page, startTime, retPage);
00170 errCatchFree(&errCatch);
00171 return qs;
00172 }
00173
00174 void qaStatusSoftError(struct qaStatus *qs, char *format, ...)
00175
00176 {
00177 struct dyString *dy = dyStringNew(0);
00178 va_list args;
00179 va_start(args, format);
00180 vaWarn(format, args);
00181 if (qs->errMessage)
00182 {
00183 dyStringAppend(dy, qs->errMessage);
00184 dyStringAppendC(dy, '\n');
00185 }
00186 dyStringVaPrintf(dy, format, args);
00187 va_end(args);
00188 freez(&qs->errMessage);
00189 qs->errMessage = cloneString(dy->string);
00190 dyStringFree(&dy);
00191 }
00192
00193 void qaStatisticsAdd(struct qaStatistics *stats, struct qaStatus *qs)
00194
00195 {
00196 stats->testCount += 1;
00197 stats->milliTotal += qs->milliTime;
00198 if (qs->errMessage)
00199 {
00200 if (qs->hardError)
00201 stats->hardCount += 1;
00202 else
00203 stats->softCount += 1;
00204 }
00205 }
00206
00207 void qaStatisticsReport(struct qaStatistics *stats, char *label, FILE *f)
00208
00209 {
00210 fprintf(f, "%20s: %3d tests, %2d soft errors, %2d hard errors, %5.2f seconds\n",
00211 label, stats->testCount, stats->softCount, stats->hardCount,
00212 0.001 * stats->milliTotal);
00213 }
00214
00215