]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
d46c07926e65dd3beaa920a61c9724490a2d62b9
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.IntegrationTests.xmlreplay;
2
3 import org.collectionspace.services.common.XmlTools;
4 import org.collectionspace.services.common.api.FileTools;
5 import org.collectionspace.services.common.api.Tools;
6 import org.dom4j.Document;
7 import org.dom4j.DocumentHelper;
8
9 import javax.swing.text.Style;
10 import java.io.File;
11 import java.util.ArrayList;
12 import java.util.List;
13
14 /**  Format a report based on XmlReplay ServiceResult object from a test group.
15  * @author  laramie
16  */
17 public class XmlReplayReport {
18     protected static final String HTML_PAGE_END = "</body></html>";
19     protected static final String TOPLINKS = "<a class='TOPLINKS' href='javascript:openAll();'>Show All Payloads</a>" + "<a class='TOPLINKS' href='javascript:closeAll();'>Hide All Payloads</a>";
20
21     protected static final String HTML_TEST_START = "<div class='TESTCASE'>";
22     protected static final String HTML_TEST_END = "</div>";
23
24     protected static final String GROUP_START = "<div class='TESTGROUP'>";
25     protected static final String GROUP_END = "</div>";
26
27     protected static final String RUNINFO_START = "<div class='RUNINFO'>";
28     protected static final String RUNINFO_END = "</div>";
29
30
31     protected static final String DIV_END = "</div>";
32
33     protected static final String PRE_START = "<pre class='SUMMARY'>";
34     protected static final String PRE_END = "</pre>";
35     protected static final String BR = "<br />\r\n";
36
37     protected static final String DETAIL_START = "<table border='1' class='DETAIL_TABLE'><tr><td>\r\n";
38     protected static final String DETAIL_LINESEP = "</td></tr>\r\n<tr><td>";
39     protected static final String DETAIL_END = "</td></tr></table>";
40
41     private static final String SP = "&nbsp;&nbsp;&nbsp;";
42
43
44     protected static String formatCollapse(String myDivID, String linkText){
45         return  "<a href='javascript:;' onmousedown=\"toggleDiv('"+myDivID+"');\">"+linkText+"</a>"
46                  + BR
47                  + "<div ID='"+myDivID+"' class='PAYLOAD' style='display:none'>";
48     }
49
50
51     private StringBuffer header = new StringBuffer();
52     private StringBuffer buffer = new StringBuffer();
53     private String runInfo = "";
54
55     public String getPage(String basedir){
56         return    formatPageStart(basedir)
57                     +"<div class='REPORTTIME'>XmlReplay run  "+Tools.nowLocale()+"</div>"
58                     +header.toString()
59                     +this.runInfo
60                     +BR
61                     +getTOC("").toString()
62                     +BR
63                     +buffer.toString()
64                     +HTML_PAGE_END;
65     }
66
67     public String getTOC(String reportName){
68         StringBuffer tocBuffer = new StringBuffer();
69
70         if (Tools.notBlank(reportName)){
71             // We are generating a TOC for an index.html file that references other report files.
72             tocBuffer.append(this.header.toString());
73         } else {
74             // We are generating a single report file, so all links are relative to this file, and we should have the TOPLINKS which allow things like showAllPayloads..
75             tocBuffer.append(BR).append(TOPLINKS).append(BR);
76         }
77         for (TOC toc: tocList){
78               tocBuffer.append(BR+"<a href='"+reportName+"#TOC"+toc.tocID+"'>"+toc.testID+"</a> "+ toc.detail);
79         }
80         tocBuffer.append(BR+BR);
81         return tocBuffer.toString();
82     }
83
84     public void addRunInfo(String text){
85          this.runInfo = RUNINFO_START+text+RUNINFO_END;
86          //addText(this.runInfo);
87     }
88
89     /** Call this method to insert arbitrary HTML in your report file, at the point after the last call to addTestResult() or addTestGroup().    */
90     public void addText(String text){
91          buffer.append(text);
92     }
93
94     public void addTestGroup(String groupID, String controlFile){
95         header.append(GROUP_START);
96         header.append(lbl("Test Group")).append(groupID).append(SP).append(lbl("Control File")).append(controlFile);
97         header.append(GROUP_END);
98     }
99
100     private int divID = 0;
101
102     public void addTestResult(ServiceResult serviceResult){
103         buffer.append(HTML_TEST_START);
104         int tocID = ++divID;
105         buffer.append(formatSummary(serviceResult, tocID));
106         buffer.append(formatPayloads(serviceResult, tocID));
107         buffer.append(HTML_TEST_END);
108     }
109
110     public static class TOC {
111         public int tocID;
112         public String testID;
113         public String detail;
114     }
115     private List<TOC> tocList = new ArrayList<TOC>();
116
117     public static String formatPageStart(String xmlReplayBaseDir){
118             String script = FileTools.readFile(xmlReplayBaseDir, "TEST-REPORTS/reports-include.js");
119             String style =  FileTools.readFile(xmlReplayBaseDir, "TEST-REPORTS/reports-include.css");
120             return "<html><head><script type='text/javascript'>\r\n"
121                      +script
122                      +"\r\n</script>\r\n<style>\r\n"
123                      +style
124                      +"\r\n</style></head><body>";
125     }
126
127     public File saveReport(String xmlReplayBaseDir, String reportName)  {
128         try {
129             File resultFile = FileTools.saveFile(getReportsDir(xmlReplayBaseDir), reportName, this.getPage(xmlReplayBaseDir), true);
130             if (resultFile!=null) {
131                 String resultFileName =  resultFile.getCanonicalPath();
132                 //System.out.println("XmlReplay summary reports saved to directory: "+resultFile.getParent());
133                 System.out.println("XmlReplay summary report: "+resultFileName);
134                 return resultFile;
135             }
136         } catch (Exception e){
137             System.out.println("ERROR saving XmlReplay report in basedir: "+xmlReplayBaseDir+" reportName: "+reportName+" error: "+e);
138         }
139         return null;
140     }
141
142     public static String getReportsDir(String basename){
143         return Tools.glue(basename,"/","TEST-REPORTS");
144     }
145
146     /** @param localMasterFilename should be a local filename for the index of each xmlReplay master control file, e.g. objectexit.xml
147      *               so what gets written to disk will be something like index.objectexit.xml.html . The actual filename will be available from
148      *               the returned File object if successful.
149      *   @return File if successful, else returns null.
150      */
151     public static File saveIndexForMaster(String xmlReplayBaseDir, String localMasterFilename, List<String> reportsList){
152         String masterFilename =  "index."+localMasterFilename+".html";
153         try{
154             StringBuffer sb = new StringBuffer(formatPageStart(xmlReplayBaseDir));
155             String dateStr = Tools.nowLocale();
156             sb.append("<div class='REPORTTIME'>XmlReplay run  "+dateStr+" master: "+localMasterFilename+"</div>");
157             for (String oneToc: reportsList){
158                 sb.append(oneToc);
159                 sb.append("<hr />");
160             }
161             sb.append(HTML_PAGE_END);
162
163             return FileTools.saveFile(getReportsDir(xmlReplayBaseDir),masterFilename, sb.toString(), false);
164         } catch (Exception e){
165             System.out.println("ERROR saving XmlReplay report index: in  xmlReplayBaseDir: "+xmlReplayBaseDir+"localMasterFilename: "+localMasterFilename+" masterFilename: "+masterFilename+" list: "+reportsList+" error: "+e);
166             return null;
167         }
168     }
169
170     protected String formatSummary(ServiceResult serviceResult, int tocID){
171         TOC toc = new TOC();
172         toc.tocID = tocID;
173         toc.testID = serviceResult.testID;
174         toc.detail =  (serviceResult.gotExpectedResult() ? ok("SUCCESS") : red("FAILURE") );
175         tocList.add(toc);
176
177         StringBuffer fb = new StringBuffer();
178         fb.append("<a name='TOC"+tocID+"'></a>");
179         fb.append(detail(serviceResult, false, false, DETAIL_START, DETAIL_LINESEP, DETAIL_END, tocID));
180         return fb.toString();
181     }
182
183     protected String formatPayloads(ServiceResult serviceResult, int tocID){
184         StringBuffer fb = new StringBuffer();
185         fb.append(BR);
186         appendPayload(fb, serviceResult.requestPayload, "REQUEST", "REQUEST" + tocID);
187         appendPayload(fb, serviceResult.requestPayloadsRaw, "REQUEST (RAW)", "REQUESTRAW" + tocID);
188         appendPayload(fb, serviceResult.result, "RESPONSE", "RESPONSE" + tocID);
189         fb.append(BR);
190
191         return fb.toString();
192     }
193
194     protected void appendPayload( StringBuffer fb , String payload, String title, String theDivID){
195         if (Tools.notBlank(payload)){
196             //fb.append(BR+title+":"+BR);
197             try {
198                 String pretty = prettyPrint(payload);
199
200
201                 fb.append(formatCollapse(theDivID, title));  //starts a div.
202                 fb.append(PRE_START);
203                 fb.append(escape(pretty));
204                 fb.append(PRE_END);
205                 fb.append(DIV_END);                        //ends that div.
206             } catch (Exception e){
207                 String error = "<font color='red'>ERROR:</font> "+payload;
208                 fb.append(error);
209                 fb.append(BR).append(BR);
210             }
211         }
212     }
213
214     private String escape(String source){
215         try {
216             return Tools.searchAndReplace(source, "<", "&lt;");
217         } catch (Exception e){
218             return "ERROR escaping requestPayload"+e;
219         }
220     }
221
222     private String prettyPrint(String rawXml) throws Exception {
223         Document document = DocumentHelper.parseText(rawXml);
224         return XmlTools.prettyPrint(document, "    ");
225     }
226
227     private static final String LINE = "<hr />\r\n";
228     private static final String CRLF = "<br />\r\n";
229
230     protected String red(String label){
231         return "<span class='ERROR'>"+label+"</span> ";
232     }
233     protected String ok(String label){
234         return "<span class='OK'>"+label+"</span> ";
235     }
236     protected String lbl(String label){
237         return "<span class='LABEL'>"+label+":</span> ";
238     }
239     public String detail(ServiceResult s, boolean includePayloads, boolean includePartSummary, String start, String linesep, String end, int tocID){
240         String partSummary = s.partsSummary(includePartSummary);
241         String res =  start
242                 + ( s.gotExpectedResult() ? lbl("SUCCESS") : "<font color='red'><b>FAILURE</b></font>"  )
243                   + SP + ( Tools.notEmpty(s.testID) ? s.testID : "" )
244                   + SP +linesep
245                 +s.method+ SP +"<a href='"+s.fullURL+"'>"+s.fullURL+"</a>"                                     +linesep
246                 + s.responseCode+ SP +lbl("gotExpected")+s.gotExpectedResult()                                                       +linesep
247                 + (Tools.notBlank(s.failureReason) ? s.failureReason +linesep : "" )
248                 + ( (s.expectedCodes.size()>0) ? lbl("expectedCodes")+s.expectedCodes+linesep : "" )
249                 //+ ( Tools.notEmpty(s.testGroupID) ? "testGroupID:"+s.testGroupID+linesep : "" )
250                 //THIS WORKS, BUT IS VERBOSE: + ( Tools.notEmpty(s.fromTestID) ? "fromTestID:"+s.fromTestID+linesep : "" )
251                 + ( Tools.notEmpty(s.responseMessage) ? lbl("msg")+s.responseMessage+linesep : "" )
252                 +lbl("auth")+s.auth                                                                                        +linesep
253                 + ( Tools.notEmpty(s.deleteURL) ? lbl("deleteURL")+s.deleteURL+linesep : "" )
254                 + ( Tools.notEmpty(s.location) ? lbl("location.CSID")+s.location+linesep : "" )
255                 + ( Tools.notEmpty(s.error) ? "ERROR:"+s.error +linesep : "" )
256                 + ((includePartSummary && Tools.notBlank(partSummary)) ? lbl("part summary")+partSummary +linesep : "")
257                 + ( includePayloads && Tools.notBlank(s.requestPayload) ? LINE+lbl("requestPayload")+LINE+CRLF+s.requestPayload+LINE : "" )
258                 + ( includePayloads && Tools.notBlank(s.result) ? LINE+lbl("result")+LINE+CRLF+s.result : "" )
259                 +end;
260         return res;
261     }
262
263 }