]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
b9e879a37babdac714c3168748d14d310266ef2b
[tmp/jakarta-migration.git] /
1 /**\r
2  * This document is a part of the source code and related artifacts\r
3  * for CollectionSpace, an open source collections management system\r
4  * for museums and related institutions:\r
5  *\r
6  * http://www.collectionspace.org\r
7  * http://wiki.collectionspace.org\r
8  *\r
9  * Copyright (c) 2009 Regents of the University of California\r
10  *\r
11  * Licensed under the Educational Community License (ECL), Version 2.0.\r
12  * You may not use this file except in compliance with this License.\r
13  *\r
14  * You may obtain a copy of the ECL 2.0 License at\r
15  * https://source.collectionspace.org/collection-space/LICENSE.txt\r
16  *\r
17  *  Unless required by applicable law or agreed to in writing, software\r
18  *  distributed under the License is distributed on an "AS IS" BASIS,\r
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
20  *  See the License for the specific language governing permissions and\r
21  *  limitations under the License.\r
22  */\r
23 \r
24 package org.collectionspace.services.IntegrationTests.xmlreplay;\r
25 \r
26 import org.apache.commons.httpclient.Header;\r
27 import org.collectionspace.services.common.api.Tools;\r
28 \r
29 import java.util.ArrayList;\r
30 import java.util.HashMap;\r
31 import java.util.List;\r
32 import java.util.Map;\r
33 \r
34 /**\r
35  * User: laramie\r
36  * $LastChangedRevision:  $\r
37  * $LastChangedDate:  $\r
38  */\r
39 public class ServiceResult {\r
40     public String testID = "";\r
41     public String testGroupID = "";\r
42     public String fullURL = "";\r
43     public String deleteURL = "";\r
44     public String location = "";\r
45     public String CSID = "";\r
46     public String subresourceCSID = "";\r
47     public String requestPayload = "";  //just like requestPayloadRaw, but may have multipart boundary and headers.\r
48     public String requestPayloadsRaw = "";\r
49     public String result = "";\r
50     public int responseCode = 0;\r
51     public String responseMessage = "";\r
52     public String method = "";\r
53     public String error = "";\r
54     public String fromTestID = "";\r
55     public String auth = "";\r
56     public String boundary = "";\r
57     public String payloadStrictness = "";\r
58     public long contentLength = 0;\r
59     public String failureReason = "";\r
60     public String expectedContentExpanded = "";\r
61     public Header[] responseHeaders = new Header[0];\r
62     public List<Integer> expectedCodes = new ArrayList<Integer>();\r
63     public Map<String,String>  vars = new HashMap<String,String>();\r
64     public void addVars(Map<String,String> newVars){\r
65         vars.putAll(newVars);\r
66     }\r
67     private Map<String, TreeWalkResults> partSummaries = new HashMap<String, TreeWalkResults>();\r
68     public void addPartSummary(String label, TreeWalkResults list){\r
69         partSummaries.put(label, list);\r
70     }\r
71     public String partsSummary(boolean detailed){\r
72         StringBuffer buf = new StringBuffer();\r
73         if (!isDomWalkOK()){\r
74             if (detailed) buf.append("\r\nDOM CHECK FAILED:\r\n");\r
75             else buf.append("; DOM CHECK FAILED:");\r
76         }\r
77         for (Map.Entry<String,TreeWalkResults> entry : partSummaries.entrySet()) {\r
78             String key = entry.getKey();\r
79             TreeWalkResults value = entry.getValue();\r
80             buf.append(" label:"+key+": ");\r
81             if (detailed){\r
82                 buf.append("\r\n");\r
83                 buf.append(value.fullSummary());\r
84             } else {\r
85                 buf.append(value.miniSummary());\r
86             }\r
87 \r
88         }\r
89         return buf.toString();\r
90     }\r
91     public boolean codeInSuccessRange(int code){\r
92         if (0<=code && code<200){\r
93             return false;\r
94         } else if (400<=code) {\r
95             return false;\r
96         }\r
97         return true;\r
98     }\r
99 \r
100     public boolean isDomWalkOK(){\r
101         if (Tools.isEmpty(payloadStrictness)){\r
102             return true;\r
103         }\r
104         PAYLOAD_STRICTNESS strictness = PAYLOAD_STRICTNESS.valueOf(payloadStrictness);\r
105         for (Map.Entry<String,TreeWalkResults> entry : partSummaries.entrySet()) {\r
106             String key = entry.getKey();\r
107             TreeWalkResults value = entry.getValue();\r
108             if (value.hasDocErrors()){\r
109                 failureReason = " : DOM DOC_ERROR; ";\r
110                 return false;\r
111             }\r
112             switch (strictness){\r
113             case STRICT:\r
114                 if (!value.isStrictMatch()) {\r
115                     failureReason = " : DOM NOT STRICT; ";\r
116                     return false;\r
117                 }\r
118                 break;\r
119             case ADDOK:\r
120                 if (value.countFor(TreeWalkResults.TreeWalkEntry.STATUS.TEXT_DIFFERENT)>0) {\r
121                     failureReason = " : DOM TEXT_DIFFERENT; ";\r
122                     return false;\r
123                 }\r
124                 if (value.countFor(TreeWalkResults.TreeWalkEntry.STATUS.R_MISSING)>0){\r
125                     failureReason = " : DOM R_MISSING; ";\r
126                     return false;\r
127                 }\r
128                 break;\r
129             case TEXT:\r
130                 if (value.countFor(TreeWalkResults.TreeWalkEntry.STATUS.TEXT_DIFFERENT)>0) {\r
131                     failureReason = " : DOM TEXT_DIFFERENT; ";\r
132                     return false;\r
133                 }\r
134                 break;\r
135             case TREE:\r
136                 if (!value.treesMatch()) {\r
137                     failureReason = " : DOM TREE MISMATCH; ";\r
138                     return false;\r
139                 }\r
140                 break;\r
141             case TREE_TEXT:\r
142                 if (value.countFor(TreeWalkResults.TreeWalkEntry.STATUS.TEXT_DIFFERENT)>0) {\r
143                     failureReason = " : DOM TEXT_DIFFERENT; ";\r
144                     return false;\r
145                 }\r
146                 if (!value.treesMatch()) {\r
147                     failureReason = " : DOM TREE MISMATCH; ";\r
148                     return false;\r
149                 }\r
150                 break;\r
151             case ZERO:\r
152                 break;\r
153             }\r
154         }\r
155         return true;\r
156     }\r
157 \r
158     private boolean overrideExpectedResult = false;\r
159 \r
160     /** Call this method to create a ServiceResult mock object, for when you are doing autoDelete, and you come\r
161      *  across a GET : GETs don't have a DELETE url, so they don't need to be autoDeleted, so an empty ServiceResult object\r
162      *  signifies this.\r
163      */\r
164     public void overrideGotExpectedResult(){\r
165         overrideExpectedResult = true;\r
166     }\r
167 \r
168     public boolean gotExpectedResult(){\r
169         if (overrideExpectedResult){\r
170             return true;\r
171         }\r
172         //if (Tools.notEmpty(failureReason)){\r
173         //    return false;\r
174         //}\r
175         for (Integer oneExpected : expectedCodes){\r
176             if (responseCode == oneExpected){\r
177                 failureReason = "";\r
178                 return isDomWalkOK();\r
179             }\r
180         }\r
181         if ( expectedCodes.size()>0 && codeInSuccessRange(responseCode)){ //none found, but result expected.\r
182             for (Integer oneExpected : expectedCodes){\r
183                 if ( ! codeInSuccessRange(oneExpected)){\r
184                     failureReason = "";\r
185                     return isDomWalkOK();\r
186                 }\r
187             }\r
188         }\r
189         boolean ok = codeInSuccessRange(responseCode);\r
190         if (ok) {\r
191             failureReason = "";\r
192             return isDomWalkOK();\r
193         }\r
194         failureReason = " : STATUS CODE UNEXPECTED; ";\r
195         return false;\r
196     }\r
197 \r
198     //public static final String[] DUMP_OPTIONS = {"minimal", "detailed", "full"};\r
199     public static enum DUMP_OPTIONS {minimal, detailed, full, auto};\r
200 \r
201     public static enum PAYLOAD_STRICTNESS {ZERO, ADDOK, TREE, TEXT, TREE_TEXT, STRICT};\r
202 \r
203     public String toString(){\r
204         return detail(true);\r
205 \r
206     }\r
207 \r
208     private static final String LINE = "\r\n==================================";\r
209     private static final String CRLF = "\r\n";\r
210 \r
211     public String detail(boolean includePayloads){\r
212         String res =  "{"\r
213                 + ( gotExpectedResult() ? "SUCCESS" : "FAILURE"  )\r
214                 + failureReason\r
215                 +"; "+method\r
216                 +"; "+responseCode\r
217                 + ( (expectedCodes.size()>0) ? "; expectedCodes:"+expectedCodes : "" )\r
218                 + ( Tools.notEmpty(testID) ? "; testID:"+testID : "" )\r
219                 + ( Tools.notEmpty(testGroupID) ? "; testGroupID:"+testGroupID : "" )\r
220                 + ( Tools.notEmpty(fromTestID) ? "; fromTestID:"+fromTestID : "" )\r
221                 + ( Tools.notEmpty(responseMessage) ? "; msg:"+responseMessage : "" )\r
222                 +"; URL:"+fullURL\r
223                 +"; auth: "+auth\r
224                 + ( Tools.notEmpty(deleteURL) ? "; deleteURL:"+deleteURL : "" )\r
225                 + ( Tools.notEmpty(location) ? "; location.CSID:"+location : "" )\r
226                 + ( Tools.notEmpty(error) ? "; ERROR:"+error : "" )\r
227                 + "; gotExpected:"+gotExpectedResult()\r
228                 //+";result:"+result+";"\r
229                 + ( partsSummary(true))\r
230                 +"}"\r
231                 + ( includePayloads && Tools.notBlank(requestPayload) ? LINE+"requestPayload:"+LINE+CRLF+requestPayload+LINE : "" )\r
232                 + ( includePayloads && Tools.notBlank(result) ? LINE+"result:"+LINE+CRLF+result : "" );\r
233         return res;\r
234     }\r
235 \r
236     public String minimal(){\r
237         return minimal(false);\r
238     }\r
239 \r
240     public String minimal(boolean verbosePartsSummary){\r
241         return "{"\r
242                 + ( gotExpectedResult() ? "SUCCESS" : "FAILURE"  )\r
243                 + failureReason\r
244                 + ( Tools.notEmpty(testID) ? "; "+testID : "" )\r
245                 +"; "+method\r
246                 +"; "+responseCode\r
247                 + (expectedCodes.size()>0 ? "; expected:"+expectedCodes : "")\r
248                 + ( Tools.notEmpty(responseMessage) ? "; msg:"+responseMessage : "" )\r
249                 +"; URL:"+fullURL\r
250                 //for auth, see detail()   +"; auth: "+auth\r
251                 + ( Tools.notEmpty(error) ? "; ERROR:"+error : "" )\r
252                 + (verbosePartsSummary ? partsSummary(true) : partsSummary(false) )\r
253                 +"}";\r
254     }\r
255     public String dump(ServiceResult.DUMP_OPTIONS opt, boolean hasError){\r
256         switch (opt){\r
257             case minimal:\r
258                 return minimal(false);\r
259             case detailed:\r
260                 return detail(false);\r
261             case full:\r
262                 return detail(true);\r
263             case auto:\r
264                 return minimal(hasError);\r
265             default:\r
266                 return toString();\r
267         }\r
268     }\r
269 \r
270     /** This method may be called from a test case, using a syntax like ${testID3.resValue("persons_common", "//refName")}   */\r
271     public String got(String xpath) throws Exception {\r
272         try {\r
273             //PayloadLogger.HttpTraffic traffic = PayloadLogger.readPayloads(this.result, this.boundary, this.contentLength);\r
274             //PayloadLogger.Part partFromServer = traffic.getPart(partName);\r
275             //String source = partFromServer.getContent();\r
276             String source = this.result;\r
277             if (Tools.isBlank(source)){\r
278                 return "";\r
279             }\r
280             org.jdom.Element element = (org.jdom.Element) XmlCompareJdom.selectSingleNode(source, xpath, null);  //todo: passing null for namespace may not work.\r
281             String sr = element != null ? element.getText() : "";\r
282             return sr;\r
283         } catch (Exception e){\r
284             return "ERROR reading response value: "+e;\r
285         }\r
286     }\r
287 \r
288     /** This method may be called from a test case, using a syntax like ${oe9.reqValue("personauthorities_common","//shortIdentifier")}    */\r
289     public String sent(String xpath) throws Exception {\r
290         try {\r
291             String source = this.requestPayload; // REM - 5/9/2012 : Changing to requestPayload from requestPayloadsRaw to get actual sent payload \r
292             if (source == null){\r
293                 return "ERROR:null:requestPayloadsRaw";\r
294             }\r
295             org.jdom.Element element = (org.jdom.Element) XmlCompareJdom.selectSingleNode(source, xpath, null);   //e.g. "//shortIdentifier");  //todo: passing null for namespace may not work.\r
296             String sr = element != null ? element.getText() : "";\r
297             return sr;\r
298         } catch (Exception e){\r
299             return "ERROR reading request value: "+e;\r
300         }\r
301     }\r
302 \r
303     public String get(String what){\r
304         if ("CSID".equals(what)){\r
305             return CSID;\r
306         } else if ("location".equals(what)){\r
307             return location;\r
308         } else if ("testID".equals(what)){\r
309             return testID;\r
310         } else if ("testGroupID".equals(what)){\r
311             return testGroupID;\r
312         } else if ("fullURL".equals(what)){\r
313             return fullURL;\r
314         } else if ("deleteURL".equals(what)){\r
315             return deleteURL;\r
316         } else if ("responseCode".equals(what)){\r
317             return ""+responseCode;\r
318         } else if ("method".equals(what)){\r
319             return method;\r
320         }\r
321         if (vars.containsKey(what)){\r
322             return vars.get(what);\r
323         }\r
324         return "";\r
325     }\r
326 \r
327 }\r