blob: 14538a1281b31dc0fffb0a21e16be9ebd1d4d57a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jmeter.assertions;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.jmeter.junit.JMeterTestCase;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XPathAssertionTest extends JMeterTestCase {
private static final Logger log = LoggerFactory.getLogger(XPathAssertionTest.class);
private XPathAssertion assertion;
private SampleResult result;
private JMeterVariables vars;
private JMeterContext jmctx;
@BeforeEach
public void setUp() throws Exception {
jmctx = JMeterContextService.getContext();
assertion = new XPathAssertion();
assertion.setThreadContext(jmctx);// This would be done by the run command
result = new SampleResult();
result.setResponseData(readFile("testfiles/XPathAssertionTest.xml"));
vars = new JMeterVariables();
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
}
private void setAlternateResponseData(){
String data = "<company-xmlext-query-ret>" + "<row>" + "<value field=\"RetCode\">LIS_OK</value>"
+ "<value field=\"RetCodeExtension\"></value>" + "<value field=\"alias\"></value>"
+ "<value field=\"positioncount\"></value>" + "<value field=\"invalidpincount\">0</value>"
+ "<value field=\"pinposition1\">1</value>" + "<value field=\"pinpositionvalue1\"></value>"
+ "<value field=\"pinposition2\">5</value>" + "<value field=\"pinpositionvalue2\"></value>"
+ "<value field=\"pinposition3\">6</value>" + "<value field=\"pinpositionvalue3\"></value>"
+ "</row>" + "</company-xmlext-query-ret>";
result.setResponseData(data, null);
}
private ByteArrayOutputStream readBA(String name) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(findTestFile(name)));
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
int len = 0;
byte[] data = new byte[512];
while ((len = bis.read(data)) >= 0) {
baos.write(data, 0, len);
}
bis.close();
return baos;
}
private byte[] readFile(String name) throws IOException {
return readBA(name).toByteArray();
}
@Test
public void testAssertionOK() throws Exception {
assertion.setXPathString("/");
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionFail() throws Exception {
assertion.setXPathString("//x");
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionPath1() throws Exception {
assertion.setXPathString("//*[code=1]");
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionPath1Negated() {
assertion.setXPathString("//*[code=1]");
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionPath2() throws Exception {
assertion.setXPathString("//*[code=2]"); // Not present
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionPath2Negated() {
assertion.setXPathString("//*[code=1]");
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionBool1() throws Exception {
assertion.setXPathString("count(//error)=2");
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionBool1Negated() {
assertion.setXPathString("count(//error)=2");
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should not be a failure");
assertEquals("Nodes Matched for count(//error)=2", res.getFailureMessage(), "when isNegated is true, when xpath matches, result should fail");
}
@Test
public void testAssertionBool2() throws Exception {
assertion.setXPathString("count(//*[code=1])=1");
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionBool2Negated() {
assertion.setXPathString("count(//*[code=1])=1");
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
assertEquals("Nodes Matched for count(//*[code=1])=1", res.getFailureMessage());
}
@Test
public void testAssertionBool3() throws Exception {
assertion.setXPathString("count(//error)=1"); // wrong
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
assertEquals("No Nodes Matched for count(//error)=1", res.getFailureMessage());
}
@Test
public void testAssertionBool3Negated() {
assertion.setXPathString("count(//error)=1"); // wrong
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testAssertionBool4() throws Exception {
assertion.setXPathString("count(//*[code=2])=1"); //Wrong
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionBool4Negated() throws Exception {
assertion.setXPathString("count(//*[code=2])=1"); //Wrong
AssertionResult res = assertion.getResult(result);
assertion.setNegated(true);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
assertEquals("No Nodes Matched for count(//*[code=2])=1", res.getFailureMessage());
}
@Test
public void testAssertionNumber() throws Exception {
assertion.setXPathString("count(//error)");// not yet handled
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionNoResult() throws Exception {
// result.setResponseData - not set
result = new SampleResult();
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertEquals(AssertionResult.RESPONSE_WAS_NULL, res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionEmptyResult() throws Exception {
result.setResponseData("", null);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertEquals(AssertionResult.RESPONSE_WAS_NULL, res.getFailureMessage());
assertFalse(res.isError(), "Should not be an error");
assertTrue(res.isFailure(), "Should be a failure");
}
@Test
public void testAssertionBlankResult() throws Exception {
result.setResponseData(" ", null);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertTrue(res.getFailureMessage().indexOf("Premature end of file") > 0);
assertTrue(res.isError(), "Should be an error");
assertFalse(res.isFailure(), "Should not be a failure");
}
@Test
public void testNoTolerance() throws Exception {
String data = "<html><head><title>testtitle</title></head>" + "<body>"
+ "<p><i><b>invalid tag nesting</i></b><hr>" + "</body></html>";
result.setResponseData(data, null);
vars = new JMeterVariables();
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/html/head/title");
assertion.setValidating(false);
assertion.setTolerant(false);
AssertionResult res = assertion.getResult(result);
log.debug("failureMessage: {}", res.getFailureMessage());
assertTrue(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testAssertion() throws Exception {
setAlternateResponseData();
assertion.setXPathString("//row/value[@field = 'alias']");
AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
log.debug(" res {}", res.isError());
log.debug(" failure {}", res.getFailureMessage());
assertFalse(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testNegateAssertion() throws Exception {
setAlternateResponseData();
assertion.setXPathString("//row/value[@field = 'noalias']");
assertion.setNegated(true);
AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
log.debug(" res {}", res.isError());
log.debug(" failure {}", res.getFailureMessage());
assertFalse(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testValidationFailure() throws Exception {
setAlternateResponseData();
assertion.setXPathString("//row/value[@field = 'alias']");
assertion.setNegated(false);
assertion.setValidating(true);
AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
log.debug("{} error: {} failure: {}", res.getFailureMessage(), res.isError(), res.isFailure());
assertTrue(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testValidationSuccess() throws Exception {
String data = "<?xml version=\"1.0\"?>" + "<!DOCTYPE BOOK [" + "<!ELEMENT p (#PCDATA)>"
+ "<!ELEMENT BOOK (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION | PART)+)>"
+ "<!ELEMENT OPENER (TITLE_TEXT)*>" + "<!ELEMENT TITLE_TEXT (#PCDATA)>"
+ "<!ELEMENT SUBTITLE (#PCDATA)>" + "<!ELEMENT INTRODUCTION (HEADER, p+)+>"
+ "<!ELEMENT PART (HEADER, CHAPTER+)>" + "<!ELEMENT SECTION (HEADER, p+)>"
+ "<!ELEMENT HEADER (#PCDATA)>" + "<!ELEMENT CHAPTER (CHAPTER_NUMBER, CHAPTER_TEXT)>"
+ "<!ELEMENT CHAPTER_NUMBER (#PCDATA)>" + "<!ELEMENT CHAPTER_TEXT (p)+>" + "]>" + "<BOOK>"
+ "<OPENER>" + "<TITLE_TEXT>All About Me</TITLE_TEXT>" + "</OPENER>" + "<PART>"
+ "<HEADER>Welcome To My Book</HEADER>" + "<CHAPTER>"
+ "<CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>" + "<CHAPTER_TEXT>"
+ "<p>Glad you want to hear about me.</p>" + "<p>There's so much to say!</p>"
+ "<p>Where should we start?</p>" + "<p>How about more about me?</p>" + "</CHAPTER_TEXT>"
+ "</CHAPTER>" + "</PART>" + "</BOOK>";
result.setResponseData(data, null);
vars = new JMeterVariables();
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/");
assertion.setValidating(true);
AssertionResult res = assertion.getResult(result);
assertFalse(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testValidationFailureWithDTD() throws Exception {
String data = "<?xml version=\"1.0\"?>" + "<!DOCTYPE BOOK [" + "<!ELEMENT p (#PCDATA)>"
+ "<!ELEMENT BOOK (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION | PART)+)>"
+ "<!ELEMENT OPENER (TITLE_TEXT)*>" + "<!ELEMENT TITLE_TEXT (#PCDATA)>"
+ "<!ELEMENT SUBTITLE (#PCDATA)>" + "<!ELEMENT INTRODUCTION (HEADER, p+)+>"
+ "<!ELEMENT PART (HEADER, CHAPTER+)>" + "<!ELEMENT SECTION (HEADER, p+)>"
+ "<!ELEMENT HEADER (#PCDATA)>" + "<!ELEMENT CHAPTER (CHAPTER_NUMBER, CHAPTER_TEXT)>"
+ "<!ELEMENT CHAPTER_NUMBER (#PCDATA)>" + "<!ELEMENT CHAPTER_TEXT (p)+>" + "]>" + "<BOOK>"
+ "<OPENER>" + "<TITLE_TEXT>All About Me</TITLE_TEXT>" + "</OPENER>" + "<PART>"
+ "<HEADER>Welcome To My Book</HEADER>" + "<CHAPTER>"
+ "<CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>" + "<CHAPTER_TEXT>"
+ "<p>Glad you want to hear about me.</p>" + "<p>There's so much to say!</p>"
+ "<p>Where should we start?</p>" + "<p>How about more about me?</p>" + "</CHAPTER_TEXT>"
+ "</CHAPTER>" + "<illegal>not defined in dtd</illegal>" + "</PART>" + "</BOOK>";
result.setResponseData(data, null);
vars = new JMeterVariables();
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/");
assertion.setValidating(true);
AssertionResult res = assertion.getResult(result);
log.debug("failureMessage: {}", res.getFailureMessage());
assertTrue(res.isError());
assertFalse(res.isFailure());
}
@Test
public void testTolerance() throws Exception {
String data = "<html><head><title>testtitle</title></head>" + "<body>"
+ "<p><i><b>invalid tag nesting</i></b><hr>" + "</body></html>";
result.setResponseData(data, null);
vars = new JMeterVariables();
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/html/head/title");
assertion.setValidating(true);
assertion.setTolerant(true);
AssertionResult res = assertion.getResult(result);
log.debug("failureMessage: {}", res.getFailureMessage());
assertFalse(res.isFailure());
assertFalse(res.isError());
}
@Test
public void testScope(){
String data = "<html><head><title>testtitle</title></head><body>"
+ "<p><i><b>invalid tag nesting</i></b><hr></body></html>";
assertion.setScopeVariable("testScope");
vars = new JMeterVariables();
vars.put("testScope", data);
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/html/head/title");
assertion.setValidating(true);
assertion.setTolerant(true);
AssertionResult res = assertion.getResult(result);
log.debug("failureMessage: {}", res.getFailureMessage());
assertFalse(res.isFailure(), "When xpath conforms to xml, the result of assertion "
+ "should be true ");
assertFalse(res.isError());
}
@Test
public void testScopeFailure(){
String data = "<html><head><title>testtitle</title></head><body>"
+ "<p><i><b>invalid tag nesting</i></b><hr></body></html>";
assertion.setScopeVariable("testScope");
vars = new JMeterVariables();
vars.put("testScope", data);
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
assertion.setXPathString("/html/head/tit");
assertion.setValidating(true);
assertion.setTolerant(true);
AssertionResult res = assertion.getResult(result);
log.debug("failureMessage: {}", res.getFailureMessage());
assertTrue(res.isFailure(), "When xpath doesn't conforms to xml, the result "
+ "of assertion should be false ");
assertFalse(res.isError());
}
@Test
public void testWrongXpathMethod() {
assertion.setXPathString("cou(//error)=1"); // wrong
assertion.setNegated(true);
AssertionResult res = assertion.getResult(result);
testLog.debug("isError() {} isFailure() {}", res.isError(), res.isFailure());
testLog.debug("failure message: {}", res.getFailureMessage());
assertTrue(res.isError(), "Should not be an error");
assertTrue(res.getFailureMessage().contains("TransformerException"), "A TransformerException should be thrown");
}
@Test
public void testWithoutSuitableNamespaces() {
setAlternateResponseData();
assertion.setNamespace(true);
assertion.setXPathString("//b:row/value[@field = 'alias']");
AssertionResult res = assertion.getResult(jmctx.getPreviousResult());
log.debug(" res {}", res.isError());
log.debug(" failure {}", res.getFailureMessage());
assertTrue(res.getFailureMessage().contains("TransformerException"), "When the user activates namespaces, a TransformerException should be thrown");
}
}