KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > assertions > XPathAssertion


1 /*
2  * Copyright 2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 package org.apache.jmeter.assertions;
19
20 import java.io.ByteArrayInputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.Serializable JavaDoc;
23
24 import javax.xml.parsers.ParserConfigurationException JavaDoc;
25 import javax.xml.transform.TransformerException JavaDoc;
26
27 import junit.framework.TestCase;
28 import junit.textui.TestRunner;
29
30 import org.apache.jmeter.samplers.SampleResult;
31 import org.apache.jmeter.testelement.AbstractTestElement;
32 import org.apache.jmeter.testelement.property.BooleanProperty;
33 import org.apache.jmeter.testelement.property.StringProperty;
34 import org.apache.jmeter.threads.JMeterContext;
35 import org.apache.jmeter.threads.JMeterContextService;
36 import org.apache.jmeter.threads.JMeterVariables;
37 import org.apache.jmeter.util.XPathUtil;
38 import org.apache.jorphan.logging.LoggingManager;
39 import org.apache.log.Logger;
40 import org.apache.xpath.XPathAPI;
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.NodeList JavaDoc;
43 import org.xml.sax.SAXException JavaDoc;
44
45
46
47 /**
48  * Checks if the result is a well-formed XML content and whether it matches an XPath
49  *
50  * author <a HREF="mailto:jspears@astrology.com">Justin Spears </a>
51  */

52 public class XPathAssertion extends AbstractTestElement implements
53         Serializable JavaDoc, Assertion {
54     private static final Logger log = LoggingManager.getLoggerForClass();
55
56
57     private static XPathAPI xpath = null;
58
59     private static final String JavaDoc XPATH_KEY = "XPath.xpath";
60     private static final String JavaDoc WHITESPACE_KEY = "XPath.whitespace";
61     private static final String JavaDoc VALIDATE_KEY = "XPath.validate";
62     private static final String JavaDoc TOLERANT_KEY = "XPath.tolerant";
63     private static final String JavaDoc NEGATE_KEY = "XPath.negate";
64     private static final String JavaDoc NAMESPACE_KEY = "XPath.namespace";
65
66     public static final String JavaDoc DEFAULT_XPATH = "/";
67     
68     
69
70     /**
71      * Returns the result of the Assertion. Checks if the result is well-formed
72      * XML, and that the XPath expression is matched (or not, as the case may
73      * be)
74      */

75     public AssertionResult getResult(SampleResult response) {
76         // no error as default
77
AssertionResult result = new AssertionResult();
78         if (response.getResponseData() == null) {
79             return setResultForNull(result);
80         }
81         result.setFailure(false);
82         result.setFailureMessage("");
83
84         if (log.isDebugEnabled()){
85             log.debug(new StringBuffer JavaDoc("Validation is set to ").append(isValidating()).toString());
86             log.debug(new StringBuffer JavaDoc("Whitespace is set to ").append(isWhitespace()).toString());
87             log.debug(new StringBuffer JavaDoc("Tolerant is set to ").append(isTolerant()).toString());
88         }
89
90         Document JavaDoc doc = null;
91
92         try {
93             doc = XPathUtil.makeDocument(
94                     new ByteArrayInputStream JavaDoc(response.getResponseData()),
95                     isValidating(), isWhitespace(), isNamespace(), isTolerant());
96         }catch (SAXException JavaDoc e) {
97             log.debug("Caught sax exception: "+e);
98             result.setError(true);
99             result.setFailureMessage(new StringBuffer JavaDoc("SAXException: ").append(e.getMessage()).toString());
100             return result;
101         } catch (IOException JavaDoc e) {
102             log.warn("Cannot parse result content", e);
103             result.setError(true);
104             result.setFailureMessage(new StringBuffer JavaDoc("IOException: ").append(e.getMessage()).toString());
105             return result;
106         } catch (ParserConfigurationException JavaDoc e) {
107             log.warn("Cannot parse result content", e);
108             result.setError(true);
109             result.setFailureMessage(new StringBuffer JavaDoc("ParserConfigurationException: ").append(e.getMessage()).toString());
110             return result;
111         }
112         
113         if ( doc == null || doc.getDocumentElement() == null){
114             result.setError(true);
115             result.setFailureMessage("Document is null, probably not parsable");
116             return result;
117         }
118
119         NodeList JavaDoc nodeList = null;
120
121         try {
122             nodeList = XPathAPI.selectNodeList(doc, getXPathString());
123         } catch (TransformerException JavaDoc e) {
124             result.setError(true);
125             result.setFailureMessage(new StringBuffer JavaDoc("TransformerException: ").append(e.getMessage()).toString());
126             return result;
127         }
128             
129         if ( nodeList == null || nodeList.getLength() == 0 ) {
130                 log.debug(new StringBuffer JavaDoc("nodeList null no match ").append(getXPathString()).toString());
131                 result.setFailure(!isNegated());
132                 result.setFailureMessage("No Nodes Matched " + getXPathString());
133                 return result;
134         }
135         log.debug("nodeList length "+nodeList.getLength());
136         if (log.isDebugEnabled() &! isNegated()){
137             for (int i=0; i< nodeList.getLength(); i++)
138                 log.debug(new StringBuffer JavaDoc("nodeList[").append(i).append("] ").append(nodeList.item(i)).toString());
139         }
140         result.setFailure(isNegated());
141         if (isNegated())
142             result.setFailureMessage("Specified XPath was found... Turn off negate if this is not desired");
143         return result;
144     }
145
146     private AssertionResult setResultForNull(AssertionResult result) {
147         result.setError(false);
148         result.setFailure(true);
149         result.setFailureMessage("Response was null");
150         return result;
151     }
152
153     /**
154      * Get The XPath String that will be used in matching the document
155      *
156      * @return String xpath String
157      */

158     public String JavaDoc getXPathString() {
159         return getPropertyAsString(XPATH_KEY, DEFAULT_XPATH);
160     }
161
162     /**
163      * Get a Property or return the default string
164      * @param key Property Key
165      * @param defaultValue Default Value
166      * @return String property
167      */

168     private String JavaDoc getPropertyAsString(String JavaDoc key, String JavaDoc defaultValue){
169         String JavaDoc str = getPropertyAsString(key);
170         return (str == null || str.length() == 0) ? defaultValue : str;
171     }
172
173     /**
174      * Set the XPath String this will be used as an xpath
175      * @param xpath String
176      */

177     public void setXPathString(String JavaDoc xpath) {
178         setProperty(new StringProperty(XPATH_KEY, xpath));
179     }
180
181     /**
182      * Set whether to ignore element whitespace
183      * @param whitespace
184      */

185     public void setWhitespace(boolean whitespace) {
186         setProperty(new BooleanProperty(WHITESPACE_KEY, whitespace));
187     }
188
189     /**
190      * Set use validation
191      * @param validate
192      */

193     public void setValidating(boolean validate) {
194         setProperty(new BooleanProperty(VALIDATE_KEY, validate));
195     }
196
197     /**
198      * Set whether this is namespace aware
199      * @param namespace
200      */

201     public void setNamespace(boolean namespace) {
202         setProperty(new BooleanProperty(NAMESPACE_KEY, namespace));
203     }
204
205     /**
206      * Set tolerant mode if required
207      * @param tolerant true/false
208      */

209     public void setTolerant(boolean tolerant) {
210         setProperty(new BooleanProperty(TOLERANT_KEY, tolerant));
211     }
212
213     public void setNegated(boolean negate){
214         setProperty(new BooleanProperty(NEGATE_KEY, negate));
215     }
216
217     /**
218      * Is this whitepsace ignored.
219      * @return boolean
220      */

221     public boolean isWhitespace() {
222         return getPropertyAsBoolean(WHITESPACE_KEY, false);
223     }
224
225     /**
226      * Is this validating
227      * @return boolean
228      */

229     public boolean isValidating() {
230         return getPropertyAsBoolean(VALIDATE_KEY, false);
231     }
232     /**
233      * Is this namespace aware?
234      * @return boolean
235      */

236     public boolean isNamespace() {
237         return getPropertyAsBoolean( NAMESPACE_KEY, false);
238     }
239
240     /**
241      * Is this using tolerant mode?
242      * @return boolean
243      */

244     public boolean isTolerant() {
245         return getPropertyAsBoolean(TOLERANT_KEY, false);
246     }
247
248     /**
249      * Negate the XPath test, that is return true if something
250      * is not found.
251      * @return boolean negated
252      */

253     public boolean isNegated() {
254         return getPropertyAsBoolean(NEGATE_KEY, false);
255     }
256     
257     ////////////////////////////////// TEST CASES //////////////////////////////
258

259     public static class XPathAssertionTest extends TestCase {
260
261         XPathAssertion assertion;
262         SampleResult result;
263         JMeterVariables vars;
264         JMeterContext jmctx;
265         public XPathAssertionTest() {super();}
266         public XPathAssertionTest(String JavaDoc name)
267         {
268             super(name);
269         }
270         public void setUp() {
271         jmctx = JMeterContextService.getContext();
272         assertion = new XPathAssertion();
273         assertion.setThreadContext(jmctx);// This would be done by the run command
274
// assertion.setRefName("regVal");
275

276         result = new SampleResult();
277         String JavaDoc data =
278             "<company-xmlext-query-ret>" +
279               "<row>" +
280                 "<value field=\"RetCode\">LIS_OK</value>" +
281                 "<value field=\"RetCodeExtension\"></value>" +
282                 "<value field=\"alias\"></value>" +
283                 "<value field=\"positioncount\"></value>" +
284                 "<value field=\"invalidpincount\">0</value>" +
285                 "<value field=\"pinposition1\">1</value>" +
286                 "<value field=\"pinpositionvalue1\"></value>" +
287                 "<value field=\"pinposition2\">5</value>" +
288                 "<value field=\"pinpositionvalue2\"></value>" +
289                 "<value field=\"pinposition3\">6</value>" +
290                 "<value field=\"pinpositionvalue3\"></value>" +
291               "</row>" +
292             "</company-xmlext-query-ret>";
293         result.setResponseData(data.getBytes());
294         vars = new JMeterVariables();
295         jmctx.setVariables(vars);
296         jmctx.setPreviousResult(result);
297         }
298
299         public void testAssertion() throws Exception JavaDoc {
300             assertion.setXPathString("//row/value[@field = 'alias']");
301             AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
302             log.debug(" res "+res.isError());
303             log.debug(" failure "+res.getFailureMessage());
304             assertFalse(res.isError());
305             assertFalse(res.isFailure());
306         }
307         public void testNegateAssertion() throws Exception JavaDoc {
308             assertion.setXPathString("//row/value[@field = 'noalias']");
309             assertion.setNegated(true);
310             
311             AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
312             log.debug(" res "+res.isError());
313             log.debug(" failure "+res.getFailureMessage());
314             assertFalse(res.isError());
315             assertFalse(res.isFailure());
316         }
317         public void testValidationFailure() throws Exception JavaDoc {
318             assertion.setXPathString("//row/value[@field = 'alias']");
319             assertion.setNegated(false);
320             assertion.setValidating(true);
321             AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
322             log.debug(res.getFailureMessage()+" error: "+res.isError()+" failure: "+res.isFailure());
323             assertTrue(res.isError());
324             assertFalse(res.isFailure());
325             
326         }
327         public void testValidationSuccess() throws Exception JavaDoc {
328              String JavaDoc data ="<?xml version=\"1.0\"?>"
329                         +"<!DOCTYPE BOOK ["
330                         +"<!ELEMENT p (#PCDATA)>"
331                         +"<!ELEMENT BOOK (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION | PART)+)>"
332                         +"<!ELEMENT OPENER (TITLE_TEXT)*>"
333                         +"<!ELEMENT TITLE_TEXT (#PCDATA)>"
334                         +"<!ELEMENT SUBTITLE (#PCDATA)>"
335                         +"<!ELEMENT INTRODUCTION (HEADER, p+)+>"
336                         +"<!ELEMENT PART (HEADER, CHAPTER+)>"
337                         +"<!ELEMENT SECTION (HEADER, p+)>"
338                         +"<!ELEMENT HEADER (#PCDATA)>"
339                         +"<!ELEMENT CHAPTER (CHAPTER_NUMBER, CHAPTER_TEXT)>"
340                         +"<!ELEMENT CHAPTER_NUMBER (#PCDATA)>"
341                         +"<!ELEMENT CHAPTER_TEXT (p)+>"
342                         +"]>"
343                         +"<BOOK>"
344                         +"<OPENER>"
345                         +"<TITLE_TEXT>All About Me</TITLE_TEXT>"
346                         +"</OPENER>"
347                         +"<PART>"
348                         +"<HEADER>Welcome To My Book</HEADER>"
349                         +"<CHAPTER>"
350                         +"<CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>"
351                         +"<CHAPTER_TEXT>"
352                         +"<p>Glad you want to hear about me.</p>"
353                         +"<p>There's so much to say!</p>"
354                         +"<p>Where should we start?</p>"
355                         +"<p>How about more about me?</p>"
356                         +"</CHAPTER_TEXT>"
357                         +"</CHAPTER>"
358                         +"</PART>"
359                         +"</BOOK>";
360              
361             result.setResponseData(data.getBytes());
362             vars = new JMeterVariables();
363             jmctx.setVariables(vars);
364             jmctx.setPreviousResult(result);
365             assertion.setXPathString("/");
366             assertion.setValidating(true);
367             AssertionResult res = assertion.getResult(result);
368             assertFalse(res.isError());
369             assertFalse(res.isFailure());
370         }
371         public void testValidationFailureWithDTD() throws Exception JavaDoc {
372          String JavaDoc data ="<?xml version=\"1.0\"?>"
373                     +"<!DOCTYPE BOOK ["
374                     +"<!ELEMENT p (#PCDATA)>"
375                     +"<!ELEMENT BOOK (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION | PART)+)>"
376                     +"<!ELEMENT OPENER (TITLE_TEXT)*>"
377                     +"<!ELEMENT TITLE_TEXT (#PCDATA)>"
378                     +"<!ELEMENT SUBTITLE (#PCDATA)>"
379                     +"<!ELEMENT INTRODUCTION (HEADER, p+)+>"
380                     +"<!ELEMENT PART (HEADER, CHAPTER+)>"
381                     +"<!ELEMENT SECTION (HEADER, p+)>"
382                     +"<!ELEMENT HEADER (#PCDATA)>"
383                     +"<!ELEMENT CHAPTER (CHAPTER_NUMBER, CHAPTER_TEXT)>"
384                     +"<!ELEMENT CHAPTER_NUMBER (#PCDATA)>"
385                     +"<!ELEMENT CHAPTER_TEXT (p)+>"
386                     +"]>"
387                     +"<BOOK>"
388                     +"<OPENER>"
389                     +"<TITLE_TEXT>All About Me</TITLE_TEXT>"
390                     +"</OPENER>"
391                     +"<PART>"
392                     +"<HEADER>Welcome To My Book</HEADER>"
393                     +"<CHAPTER>"
394                     +"<CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>"
395                     +"<CHAPTER_TEXT>"
396                     +"<p>Glad you want to hear about me.</p>"
397                     +"<p>There's so much to say!</p>"
398                     +"<p>Where should we start?</p>"
399                     +"<p>How about more about me?</p>"
400                     +"</CHAPTER_TEXT>"
401                     +"</CHAPTER>"
402                     +"<illegal>not defined in dtd</illegal>"
403                     +"</PART>"
404                     +"</BOOK>";
405             
406            result.setResponseData(data.getBytes());
407            vars = new JMeterVariables();
408            jmctx.setVariables(vars);
409            jmctx.setPreviousResult(result);
410            assertion.setXPathString("/");
411            assertion.setValidating(true);
412            AssertionResult res = assertion.getResult(result);
413            log.debug("failureMessage: "+res.getFailureMessage());
414            assertTrue(res.isError());
415            assertFalse(res.isFailure());
416        }
417         public void testTolerance() throws Exception JavaDoc {
418              String JavaDoc data ="<html><head><title>testtitle</title></head>"
419                 +"<body>"
420                 +"<p><i><b>invalid tag nesting</i></b><hr>"
421                 +"</body></html>";
422                
423               result.setResponseData(data.getBytes());
424               vars = new JMeterVariables();
425               jmctx.setVariables(vars);
426               jmctx.setPreviousResult(result);
427               assertion.setXPathString("/html/head/title");
428               assertion.setValidating(true);
429               assertion.setTolerant(true);
430               AssertionResult res = assertion.getResult(result);
431               log.debug("failureMessage: "+res.getFailureMessage());
432               assertFalse(res.isFailure());
433               assertFalse(res.isError());
434         }
435
436         public void testNoTolerance() throws Exception JavaDoc {
437              String JavaDoc data ="<html><head><title>testtitle</title></head>"
438                 +"<body>"
439                 +"<p><i><b>invalid tag nesting</i></b><hr>"
440                 +"</body></html>";
441               
442              result.setResponseData(data.getBytes());
443              vars = new JMeterVariables();
444              jmctx.setVariables(vars);
445              jmctx.setPreviousResult(result);
446              assertion.setXPathString("/html/head/title");
447              assertion.setValidating(false);
448              assertion.setTolerant(false);
449              AssertionResult res = assertion.getResult(result);
450              log.debug("failureMessage: "+res.getFailureMessage());
451              assertTrue(res.isError());
452              assertFalse(res.isFailure());
453          }
454         
455         public static void main(String JavaDoc[] args) {
456             TestRunner.run(XPathAssertionTest.class);
457         }
458     }
459 }
Popular Tags