Lines 10-20
Link Here
|
10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.test.performance.ui; |
11 |
package org.eclipse.test.performance.ui; |
12 |
|
12 |
|
|
|
13 |
import java.io.PrintStream; |
14 |
import java.text.SimpleDateFormat; |
13 |
import java.util.ArrayList; |
15 |
import java.util.ArrayList; |
|
|
16 |
import java.util.Date; |
14 |
import java.util.Hashtable; |
17 |
import java.util.Hashtable; |
|
|
18 |
import java.util.StringTokenizer; |
15 |
|
19 |
|
|
|
20 |
import org.eclipse.test.internal.performance.PerformanceTestPlugin; |
16 |
import org.eclipse.test.internal.performance.db.DB; |
21 |
import org.eclipse.test.internal.performance.db.DB; |
17 |
import org.eclipse.test.internal.performance.db.Scenario; |
22 |
import org.eclipse.test.internal.performance.db.Scenario; |
|
|
23 |
import org.eclipse.test.internal.performance.db.SummaryEntry; |
18 |
import org.eclipse.test.internal.performance.db.Variations; |
24 |
import org.eclipse.test.internal.performance.db.Variations; |
19 |
|
25 |
|
20 |
public class ScenarioStatusTable { |
26 |
public class ScenarioStatusTable { |
Lines 24-41
Link Here
|
24 |
private String scenarioPattern; |
30 |
private String scenarioPattern; |
25 |
private ArrayList configNames=new ArrayList(); |
31 |
private ArrayList configNames=new ArrayList(); |
26 |
private Hashtable scenarioComments; |
32 |
private Hashtable scenarioComments; |
|
|
33 |
private SummaryEntry[] fingerprintEntries; |
27 |
private final String baseline; |
34 |
private final String baseline; |
28 |
|
35 |
|
29 |
private class ScenarioStatus{ |
36 |
private class ScenarioStatus{ |
30 |
Hashtable statusMap; |
37 |
Hashtable statusMap; |
31 |
String name; |
38 |
String name, shortName; |
32 |
Hashtable configStatus; |
39 |
Hashtable configStatus; |
|
|
40 |
Hashtable resultsMap; |
33 |
boolean hasSlowDownExplanation=false; |
41 |
boolean hasSlowDownExplanation=false; |
|
|
42 |
boolean fingerprint = false; |
43 |
boolean hasBaseline = true; |
34 |
|
44 |
|
35 |
public ScenarioStatus(String scenarioName){ |
45 |
public ScenarioStatus(String scenarioName){ |
36 |
name=scenarioName; |
46 |
name = scenarioName; |
37 |
statusMap=new Hashtable(); |
47 |
statusMap = new Hashtable(); |
38 |
configStatus=new Hashtable(); |
48 |
configStatus = new Hashtable(); |
|
|
49 |
resultsMap = new Hashtable(); |
39 |
} |
50 |
} |
40 |
|
51 |
|
41 |
} |
52 |
} |
Lines 48-207
Link Here
|
48 |
* @param scenarioPattern |
59 |
* @param scenarioPattern |
49 |
* @param configDescriptors |
60 |
* @param configDescriptors |
50 |
*/ |
61 |
*/ |
51 |
public ScenarioStatusTable(Variations variations,String scenarioPattern,Hashtable configDescriptors,Hashtable scenarioComments, String baseline){ |
62 |
public ScenarioStatusTable(Variations variations,String scenarioPattern,Hashtable configDescriptors,Hashtable scenarioComments, SummaryEntry[] fpSummaries, String baseline){ |
52 |
configMaps=configDescriptors; |
63 |
configMaps=configDescriptors; |
53 |
this.variations=variations; |
64 |
this.variations=variations; |
54 |
this.scenarioPattern=scenarioPattern; |
65 |
this.scenarioPattern=scenarioPattern; |
55 |
this.scenarioComments=scenarioComments; |
66 |
this.scenarioComments=scenarioComments; |
56 |
this.baseline= baseline; |
67 |
this.baseline= baseline; |
|
|
68 |
this.fingerprintEntries = fpSummaries; |
57 |
} |
69 |
} |
58 |
|
70 |
|
59 |
/** |
71 |
/** |
60 |
* Returns HTML representation of scenario status table. |
72 |
* Prints the HTML representation of scenario status table into the given stream. |
61 |
*/ |
73 |
*/ |
62 |
public String toString() { |
74 |
public void print(PrintStream stream, boolean filter) { |
63 |
String OS="config"; |
75 |
String OS="config"; |
64 |
String htmlTable=""; |
76 |
Scenario[] scenarios= DB.queryScenarios(variations, scenarioPattern, OS, null); |
65 |
Scenario[] scenarios= DB.queryScenarios(variations, scenarioPattern, OS, null); |
77 |
|
66 |
|
78 |
if (scenarios != null && scenarios.length > 0) { |
67 |
if (scenarios != null && scenarios.length > 0) { |
79 |
ArrayList scenarioStatusList=new ArrayList(); |
68 |
ArrayList scenarioStatusList=new ArrayList(); |
80 |
|
69 |
|
81 |
for (int i= 0; i < scenarios.length; i++) { |
70 |
for (int i= 0; i < scenarios.length; i++) { |
82 |
Scenario scenario= scenarios[i]; |
71 |
Scenario scenario= scenarios[i]; |
83 |
String scenarioName=scenario.getScenarioName(); |
72 |
String scenarioName=scenario.getScenarioName(); |
84 |
if (filter && !Utils.matchPattern(scenarioName, scenarioPattern)) continue; |
73 |
// if (!Utils.matchPattern(scenarioName, scenarioPattern)) continue; |
85 |
// returns the config names. Making assumption that indices in |
74 |
// returns the config names. Making assumption that indices in |
86 |
// the configs array map to the indices of the failure messages. |
75 |
// the configs array map to the indices of the failure messages. |
87 |
String[] configs=scenario.getTimeSeriesLabels(); |
76 |
String[] configs=scenario.getTimeSeriesLabels(); |
88 |
String[] failureMessages= scenario.getFailureMessages(); |
77 |
String[] failureMessages= scenario.getFailureMessages(); |
89 |
ScenarioStatus scenarioStatus=new ScenarioStatus(scenarioName); |
78 |
ScenarioStatus scenarioStatus=new ScenarioStatus(scenarioName); |
90 |
scenarioStatus.fingerprint = Utils.hasSummary(this.fingerprintEntries, scenarioName); |
79 |
scenarioStatusList.add(scenarioStatus); |
|
|
80 |
|
81 |
String scenarioComment= (String)scenarioComments.get(scenarioName); |
82 |
if (scenarioComment != null) |
83 |
scenarioStatus.hasSlowDownExplanation= true; |
84 |
|
85 |
for (int j=0;j<configs.length;j++){ |
86 |
if (!configNames.contains(configs[j])) |
87 |
configNames.add(configs[j]); |
88 |
|
89 |
double[] resultStats = Utils.resultStats(variations, scenarioName, baseline, configs[j]); |
90 |
int confidenceLevel = Utils.confidenceLevel(resultStats); |
91 |
|
92 |
boolean hasScenarioFailure = failureMessages[j] != null && failureMessages[j].indexOf(configs[j]) != -1; // ensure correct failure message relates to config |
93 |
StringBuffer buffer = new StringBuffer(); |
94 |
if (hasScenarioFailure) { |
95 |
buffer.append(failureMessages[j]); |
96 |
if (scenarioStatus.hasSlowDownExplanation) { |
97 |
buffer.append(" - Explanation comment: "); |
98 |
buffer.append(scenarioComment); |
99 |
} |
100 |
confidenceLevel |= Utils.DEV; |
101 |
} |
102 |
|
91 |
|
103 |
scenarioStatus.configStatus.put(configs[j], new Integer(confidenceLevel)); |
92 |
String scenarioComment= (String)scenarioComments.get(scenarioName); |
104 |
scenarioStatus.statusMap.put(configs[j], new Object[] { buffer.toString(), resultStats }); |
93 |
if (scenarioComment != null) |
105 |
} |
94 |
scenarioStatus.hasSlowDownExplanation= true; |
106 |
} |
95 |
|
107 |
|
96 |
int confsLength = configs.length; |
108 |
String label=null; |
97 |
for (int j=0; j<confsLength; j++){ |
109 |
htmlTable=htmlTable.concat("<br><h4>Scenario Status</h4>\n" + |
98 |
if (!configNames.contains(configs[j])) |
110 |
"The scenario status table shows all scenarios tests result for all performance test machines. It gives a complete but compact view of performance result for the component.<br>\n" + |
99 |
configNames.add(configs[j]); |
111 |
"For each test (ie. in each cell of this table), following information are displayed:\n" + |
100 |
|
112 |
"<ul>\n" + |
101 |
Variations v = (Variations) variations.clone(); |
113 |
"<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>\n" + |
102 |
v.put(PerformanceTestPlugin.CONFIG, configs[j]); |
114 |
"The legend for this icon is:\n" + |
103 |
double[] resultStats = Utils.resultStats(v, scenarioName, baseline, configs[j]); |
115 |
"<ul>\n" + |
104 |
if (resultStats == null) continue; |
116 |
"<li>Green (<img src=\""+Utils.OK_IMAGE+"\">): mark a <b>successful result</b>, which means this test has neither significant performance regression nor significant standard error</li>\n" + |
105 |
if (resultStats != null && resultStats[1] < 0 && scenarioStatus.hasBaseline) scenarioStatus.hasBaseline = false; |
117 |
"<li>Red (<img src=\""+Utils.FAIL_IMAGE+"\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>\n" + |
106 |
int confidenceLevel = Utils.confidenceLevel(resultStats); |
118 |
"<li>Gray (<img src=\""+Utils.FAIL_IMAGE_EXPLAINED+"\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>\n" + |
107 |
|
119 |
"<li>Yellow (<img src=\""+Utils.FAIL_IMAGE_WARN+"\"> or <img src=\""+Utils.OK_IMAGE_WARN+"\">): mark a <b>failing or successful result</b> with a significant standard error (more than "+Utils.STANDARD_ERROR_THRESHOLD_STRING+")</li>\n" + |
108 |
boolean hasScenarioFailure = failureMessages[j] != null && failureMessages[j].indexOf(configs[j]) != -1; // ensure correct failure message relates to config |
120 |
"<li>\"n/a\": mark a test for with <b>no</b> performance results</li>\n" + |
109 |
StringBuffer buffer = new StringBuffer(); |
121 |
"</ul></li>\n" + |
110 |
if (hasScenarioFailure) { |
122 |
"<li>the value of the deviation from the baseline as a percentage (ie. formula is: <code>(build_test_time - baseline_test_time) / baseline_test_time</code>)</li>\n" + |
111 |
buffer.append(failureMessages[j]); |
123 |
"<li>the value of the standard error of this deviation as a percentage (ie. formula is: <code>sqrt(build_test_stddev^2 / N + baseline_test_stddev^2 / N) / baseline_test_time</code>)<br>\n" + |
112 |
if (scenarioStatus.hasSlowDownExplanation) { |
124 |
"Note that errors equal to 0 are not shown (tests which have only one iteration).</li>\n" + |
113 |
buffer.append(" - Explanation comment: "); |
125 |
"</ul>" + |
114 |
buffer.append(scenarioComment); |
126 |
"For failing tests, value of deviation with its standard error is added at the beginning of the error message you can see flying over the corresponding image.<br>\n" + |
115 |
} |
127 |
"Follow the link on test box corresponding image for detailed results.<br>" + |
116 |
confidenceLevel |= Utils.DEV; |
128 |
"<br>\n"); |
117 |
} |
129 |
|
118 |
|
130 |
htmlTable=htmlTable.concat("<table border=\"1\"><tr><td><h4>All "+scenarios.length+" scenarios</h4></td>\n"); |
119 |
String text = Utils.failureMessage(resultStats, false); |
131 |
for (int i= 0; i < configNames.size(); i++){ |
120 |
if (text == null) continue; |
132 |
label=configNames.get(i).toString(); |
121 |
scenarioStatus.configStatus.put(configs[j], new Integer(confidenceLevel)); |
133 |
String columnTitle=label; |
122 |
scenarioStatus.statusMap.put(configs[j], buffer.toString()); |
134 |
if (configMaps!=null) { |
123 |
scenarioStatus.resultsMap.put(configs[j], text); |
135 |
Utils.ConfigDescriptor configDescriptor= (Utils.ConfigDescriptor)configMaps.get(label); |
124 |
if (scenarioStatus.shortName == null) { |
136 |
if (configDescriptor != null) |
125 |
long time = (long) resultStats[2]; |
137 |
columnTitle=configDescriptor.description; |
126 |
if (time == 0) { // baseline is OK |
138 |
} |
127 |
scenarioStatus.shortName = Utils.getScenarioShortName(scenarioName, -1); |
139 |
htmlTable=htmlTable.concat("<td><h5>"+columnTitle +"</h5></td>"); |
128 |
} else { |
140 |
} |
129 |
StringBuffer shortName = new StringBuffer("*"); |
141 |
|
130 |
shortName.append(Utils.getScenarioShortName(scenarioName, -1)); |
142 |
htmlTable=htmlTable.concat("</tr>\n"); |
131 |
shortName.append(" <small>(vs. "); |
143 |
|
132 |
if (time < 0) { |
144 |
// counter for js class Id's |
133 |
SimpleDateFormat dateFormat = new SimpleDateFormat("3.2_200606291905_yyyyMMddhhmm"); |
145 |
int jsIdCount=0; |
134 |
shortName.append(dateFormat.format(new Date(-time))); |
146 |
for (int j= 0; j < scenarioStatusList.size(); j++) { |
135 |
} else { |
147 |
|
136 |
SimpleDateFormat dateFormat = new SimpleDateFormat("IyyyyMMdd-hhmm"); |
148 |
ScenarioStatus status=(ScenarioStatus)scenarioStatusList.get(j); |
137 |
shortName.append(dateFormat.format(new Date(time))); |
149 |
|
138 |
} |
150 |
htmlTable=htmlTable.concat("<tr><td>"+status.name.substring(status.name.indexOf(".",status.name.indexOf(".test")+1)+1)+"</td>"); |
139 |
shortName.append(")</small>"); |
151 |
for (int i=0;i<configNames.size();i++){ |
140 |
scenarioStatus.shortName = shortName.toString(); |
152 |
String message=null; |
141 |
} |
153 |
String configName=configNames.get(i).toString(); |
142 |
} |
154 |
String aUrl=configName; |
143 |
|
155 |
double[] resultStats = null; |
144 |
if (!scenarioStatusList.contains(scenarioStatus)) { |
156 |
if(status.statusMap.get(configName)!=null){ |
145 |
scenarioStatusList.add(scenarioStatus); |
157 |
Object[] statusInfo = (Object[]) status.statusMap.get(configName); |
146 |
} |
158 |
message = (String) statusInfo[0]; |
147 |
} |
159 |
resultStats = (double[]) statusInfo[1]; |
148 |
} |
160 |
} |
149 |
|
161 |
|
150 |
String label=null; |
162 |
if (status.statusMap.containsKey(configName)){ |
151 |
stream.println("<br><h4>Scenario Status</h4>"); |
163 |
int confidence = ((Integer) status.configStatus.get(configName)).intValue(); |
152 |
stream.println("The scenario status table shows all scenarios tests result for all performance test machines."); |
164 |
String image = Utils.getImage(confidence, resultStats, status.hasSlowDownExplanation); |
153 |
stream.println("It gives a complete but compact view of performance result for the component.<br>"); |
165 |
StringBuffer html = new StringBuffer("\n<td><a "); |
154 |
stream.println("For each test (ie. in each cell of this table), following information are displayed:"); |
166 |
if ((confidence & Utils.DEV) == 0 || message.length() == 0){ |
155 |
stream.println("<ul>"); |
167 |
// write deviation with error in table when test pass |
156 |
stream.println("<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>"); |
168 |
html.append("href=\""); |
157 |
stream.println("The legend for this icon is:"); |
169 |
html.append(aUrl); |
158 |
stream.println("<ul>"); |
170 |
html.append('/'); |
159 |
stream.print("<li>Green (<img src=\""); |
171 |
html.append(status.name.replace('#', '.').replace(':', '_').replace('\\', '_')); |
160 |
stream.print(Utils.OK_IMAGE); |
172 |
html.append(".html\">\n<img hspace=\"10\" border=\"0\" src=\""); |
161 |
stream.print("\">): mark a <b>successful result</b>, which means this test has neither significant performance regression nor significant standard error</li>"); |
173 |
html.append(image); |
162 |
stream.print("<li>Red (<img src=\""); |
174 |
html.append("\"/></a>"); |
163 |
stream.print(Utils.FAIL_IMAGE); |
175 |
} else { |
164 |
stream.println("\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>"); |
176 |
// create message with tooltip text including deviation with error plus failure message |
165 |
stream.print("<li>Gray (<img src=\""); |
177 |
jsIdCount+=1; |
166 |
stream.print(Utils.FAIL_IMAGE_EXPLAINED); |
178 |
html.append("class=\"tooltipSource\" onMouseover=\"show_element('toolTip"); |
167 |
stream.println("\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>"); |
179 |
html.append(jsIdCount); |
168 |
stream.print("<li>Yellow (<img src=\""); |
180 |
html.append("')\" onMouseout=\"hide_element('toolTip"); |
169 |
stream.print(Utils.FAIL_IMAGE_WARN); |
181 |
html.append(jsIdCount); |
170 |
stream.print("\"> or <img src=\""); |
182 |
html.append("')\" \nhref=\""); |
171 |
stream.print(Utils.OK_IMAGE_WARN); |
183 |
html.append(aUrl); |
172 |
stream.print("\">): mark a <b>failing or successful result</b> with a significant standard error (more than "); |
184 |
html.append('/'); |
173 |
stream.print(Utils.STANDARD_ERROR_THRESHOLD_STRING); |
185 |
html.append(status.name.replace('#', '.').replace(':', '_').replace('\\', '_')); |
174 |
stream.println(")</li>"); |
186 |
html.append(".html\">\n<img hspace=\"10\" border=\"0\" src=\""); |
175 |
stream.println("<li>\"n/a\": mark a test for with <b>no</b> performance results</li>"); |
187 |
html.append(image); |
176 |
stream.println("</ul></li>"); |
188 |
html.append("\"/>\n<span class=\"hidden_tooltip\" id=\"toolTip"); |
177 |
stream.println("<li>the value of the deviation from the baseline as a percentage (ie. formula is: <code>(build_test_time - baseline_test_time) / baseline_test_time</code>)</li>"); |
189 |
html.append(jsIdCount); |
178 |
stream.println("<li>the value of the standard error of this deviation as a percentage (ie. formula is: <code>sqrt(build_test_stddev^2 / N + baseline_test_stddev^2 / N) / baseline_test_time</code>)<br>"); |
190 |
html.append("\">"); |
179 |
stream.println("Tests with only one iteration have no available error (replaced by \"[n/a]\".</li>"); |
191 |
html.append(message); |
180 |
stream.println("</ul>"); |
192 |
html.append("</span></a>"); |
181 |
stream.println("<u>Hints</u>:<ul>"); |
193 |
} |
182 |
stream.println("<li>fly over image of failing tests to see the complete error message</li>"); |
194 |
html.append(Utils.failureMessage(resultStats, false)); |
183 |
stream.println("<li>to look at the complete and detailed test results, click on its image</li>"); |
195 |
html.append("</td>"); |
184 |
stream.println("<li>scenario name may be <b>emphazised</b> when the results are also displayed in the fingerprint</li>"); |
196 |
htmlTable=htmlTable.concat(html.toString()); |
185 |
stream.println("<li>scenario name may start with an '*' when the scenario has no results in the last baseline run</li>"); |
197 |
}else{ |
186 |
stream.println("<li>standard error may be '<font color=\"#CCCC00\">[n/a]</font>' when it cannot be computed, typically when the test has only one measure!</li>"); |
198 |
htmlTable=htmlTable.concat("<td>n/a</td>"); |
187 |
stream.println("</ul>"); |
199 |
} |
188 |
stream.println(); |
200 |
} |
189 |
stream.println("<table border=\"1\">"); |
201 |
} |
190 |
stream.println("<tr>"); |
202 |
|
191 |
stream.print("<td><h4>All "); |
203 |
htmlTable=htmlTable.concat("</tr>\n"); |
192 |
stream.print(scenarios.length); |
204 |
} |
193 |
stream.println(" scenarios</h4></td>"); |
205 |
return htmlTable; |
194 |
|
206 |
} |
195 |
for (int i= 0; i < configNames.size(); i++){ |
|
|
196 |
label = configNames.get(i).toString(); |
197 |
String columnTitle = label; |
198 |
if (configMaps!=null) { |
199 |
Utils.ConfigDescriptor configDescriptor= (Utils.ConfigDescriptor)configMaps.get(label); |
200 |
if (configDescriptor != null) { |
201 |
int idx = configDescriptor.description.indexOf('('); |
202 |
if (idx < 0) { |
203 |
columnTitle = configDescriptor.description; |
204 |
} else { |
205 |
// first line |
206 |
StringTokenizer tokenizer = new StringTokenizer(configDescriptor.description.substring(0, idx).trim(), " "); |
207 |
StringBuffer buffer = new StringBuffer(tokenizer.nextToken()); |
208 |
while (tokenizer.hasMoreTokens()) { |
209 |
buffer.append(" "); |
210 |
buffer.append(tokenizer.nextToken()); |
211 |
} |
212 |
buffer.append(' '); |
213 |
// second line |
214 |
tokenizer = new StringTokenizer(configDescriptor.description.substring(idx).trim(), " "); |
215 |
buffer.append(tokenizer.nextToken()); |
216 |
while (tokenizer.hasMoreTokens()) { |
217 |
buffer.append(" "); |
218 |
buffer.append(tokenizer.nextToken()); |
219 |
} |
220 |
columnTitle = buffer.toString(); |
221 |
} |
222 |
} |
223 |
} |
224 |
stream.print("<td><h5>"); |
225 |
stream.print(columnTitle); |
226 |
stream.println("</h5>"); |
227 |
} |
228 |
|
229 |
// counter for js class Id's |
230 |
int jsIdCount=0; |
231 |
for (int j= 0; j < scenarioStatusList.size(); j++) { |
232 |
|
233 |
ScenarioStatus status=(ScenarioStatus)scenarioStatusList.get(j); |
234 |
|
235 |
stream.println("<tr>"); |
236 |
stream.print("<td>"); |
237 |
if (status.fingerprint) stream.print("<b>"); |
238 |
if (!status.hasBaseline) stream.print("*"); |
239 |
// stream.print(status.name.substring(status.name.indexOf(".",status.name.indexOf(".test")+1)+1)); |
240 |
stream.print(status.shortName); |
241 |
if (!status.hasBaseline) stream.print("</i>"); |
242 |
if (status.fingerprint) stream.print("</b>"); |
243 |
stream.println(); |
244 |
for (int i=0;i<configNames.size();i++){ |
245 |
String configName=configNames.get(i).toString(); |
246 |
String aUrl=configName; |
247 |
if (status.statusMap.containsKey(configName)){ |
248 |
String message = (String) status.statusMap.get(configName); |
249 |
int confidence = ((Integer) status.configStatus.get(configName)).intValue(); |
250 |
String image = Utils.getImage(confidence, status.hasSlowDownExplanation); |
251 |
stream.print("<td><a "); |
252 |
if ((confidence & Utils.DEV) == 0 || message.length() == 0){ |
253 |
// write deviation with error in table when test pass |
254 |
stream.print("href=\""); |
255 |
stream.print(aUrl); |
256 |
stream.print('/'); |
257 |
stream.print(status.name.replace('#', '.').replace(':', '_').replace('\\', '_')); |
258 |
stream.println(".html\">"); |
259 |
stream.print("<img hspace=\"10\" border=\"0\" src=\""); |
260 |
stream.print(image); |
261 |
stream.println("\"/></a>"); |
262 |
} else { |
263 |
// create message with tooltip text including deviation with error plus failure message |
264 |
jsIdCount+=1; |
265 |
stream.print("class=\"tooltipSource\" onMouseover=\"show_element('toolTip"); |
266 |
stream.print(jsIdCount); |
267 |
stream.print("')\" onMouseout=\"hide_element('toolTip"); |
268 |
stream.print(jsIdCount); |
269 |
stream.print("')\" \nhref=\""); |
270 |
stream.print(aUrl); |
271 |
stream.print('/'); |
272 |
stream.print(status.name.replace('#', '.').replace(':', '_').replace('\\', '_')); |
273 |
stream.println(".html\">"); |
274 |
stream.print("<img hspace=\"10\" border=\"0\" src=\""); |
275 |
stream.print(image); |
276 |
stream.println("\"/>"); |
277 |
stream.print("<span class=\"hidden_tooltip\" id=\"toolTip"); |
278 |
stream.print(jsIdCount); |
279 |
stream.print("\">"); |
280 |
stream.print(message); |
281 |
stream.println("</span></a>"); |
282 |
} |
283 |
String results = (String) status.resultsMap.get(configName); |
284 |
if (results != null) stream.println(results); |
285 |
}else{ |
286 |
stream.println("<td>n/a"); |
287 |
} |
288 |
} |
289 |
stream.flush(); |
290 |
} |
291 |
stream.append("</table>"); |
292 |
} |
293 |
} |
207 |
} |
294 |
} |