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