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