Forum Discussion

mmoser18's avatar
mmoser18
Frequent Contributor
9 years ago

Regular expressions again...

I am using Scripted Assertions that use regular expressions. I.e. the Groovy code ends up in a statement like:

	assert response =~ pattern

 

In about 100 test-cases this works brilliantly but with two testcases I am currently pulling my hair.

 

I am by now writing both, the response and the pattern, to two files for debugging purposes, so I can see what exactly goes into the above statement.

 

The content of those files I am putting into RegExBuddy, an excellent tool that allows to analyze and single step regular expressions and follow their operation (https://www.regexbuddy.com/).

 

Both cases do work in RegExBuddy, i.e. I claim, those regular expressions are correct and should match! But the Matcher in soapUI obviously thinks otherwise. I had similar cases before (e.g. https://community.smartbear.com/t5/SoapUI-Open-Source/How-to-debug-regular-expressions-in-soapUI/m-p/104274/highlight/true#M18178) which in the end turned out to be stack overflows in the RegExMatcher.

 

But this time, both the regular expression and the response are rather small and I also tried to increase the soapUI stackspace up to tenfold its current size, but that didn't have any effect this time. So, I seem really stuck here!

 

Does anyone have an idea, what could be causing this? Or a suggestion how one could debug/analyze this pattern matching process in soapUI/Groovy/Java?

 

Michael

 

 

 

 

  • nmrao's avatar
    nmrao
    Champion Level 3

    Do you want to show the response and pattern that you were trying and they are failing? That would help to understand the issue.

     

    By the way, this link should help to improve the understanding of regex in groovy.

    • mmoser18's avatar
      mmoser18
      Frequent Contributor

      > Do you want to show the response and pattern that you were trying...

       

      Sure - no problem:

       

      The regexp reads e.g.:

      <AirlineResource>
      \s*<Airlines>
      (\s*<Airline>
      (\s*<OtherIDs>
      (\s*<OtherID Description="Short Name">.*</OtherID>
      )*\s*</OtherIDs>
      )?\s*<AirlineID>\w{2}</AirlineID>
      (\s*<AirlineID_ICAO>(\\N|\w{3})</AirlineID_ICAO>
      )?\s*<Names>
      (\s*<Name LanguageCode="\S{2}">.+</Name>
      )+\s*</Names>
      \s*</Airline>
      )*\s*</Airlines>
      \s*<Meta Version="1\.0\.0">
      \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines(\?lang=DE)?" Rel="self"/>
      \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines/\{airlineCode\}(\?lang=DE)?" Rel="related"/>
      \s*</Meta>
      </AirlineResource>

      The captured response I attach as file.

       

       

      I also attach two screenshots of RegExBuddy in action, the first showing the above entered into the RegEx-field (top) and the response (bottom area). The yellow background color indicates a match.

      The second screenshot shows the result of the "tracing", i.e. one can see the misc. matching steps and the backtracking.

      At the bottom you see that a full match was found after 2565 steps.

       

      But - as I said: when the same is compared within soapUI I get a popup:

      Error

      An error occured  ...

       

      From the log I capture the following:

      Sat Jun 11 16:51:07 CEST 2016:ERROR:Exception caught: org.codehaus.groovy.runtime.powerassert.PowerAssertionError: msg=assert response =~ pattern
             |        |  |
             |        |  <AirlineResource>
             |        |  \s*<Airlines>
             |        |  (\s*<Airline>
             |        |  (\s*<OtherIDs>
             |        |  (\s*<OtherID Description="Short Name">.*</OtherID>
             |        |  )*\s*</OtherIDs>
             |        |  )?\s*<AirlineID>\w{2}</AirlineID>
             |        |  (\s*<AirlineID_ICAO>(\\N|\w{3})</AirlineID_ICAO>
             |        |  )?\s*<Names>
             |        |  (\s*<Name LanguageCode="\S{2}">.+</Name>
             |        |  )+\s*</Names>
             |        |  \s*</Airline>
             |        |  )*\s*</Airlines>
             |        |  \s*<Meta Version="1\.0\.0">
             |        |  \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines(\?lang=DE)?" Rel="self"/>
             |        |  \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines/\{airlineCode\}(\?lang=DE)?" Rel="related"/>
             |        |  \s*</Meta>
             |        |  </AirlineResource>
             |        java.util.regex.Matcher[pattern=<AirlineResource>
             |        \s*<Airlines>
             |        (\s*<Airline>
             |        (\s*<OtherIDs>
             |        (\s*<OtherID Description="Short Name">.*</OtherID>
             |        )*\s*</OtherIDs>
             |        )?\s*<AirlineID>\w{2}</AirlineID>
             |        (\s*<AirlineID_ICAO>(\\N|\w{3})</AirlineID_ICAO>
             |        )?\s*<Names>
             |        (\s*<Name LanguageCode="\S{2}">.+</Name>
             |        )+\s*</Names>
             |        \s*</Airline>
             |        )*\s*</Airlines>
             |        \s*<Meta Version="1\.0\.0">
             |        \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines(\?lang=DE)?" Rel="self"/>
             |        \s*<Link Href="https://52\.58\.16\.38:9895/references_v1\.1\.0/airlines/\{airlineCode\}(\?lang=DE)?" Rel="related"/>
             |        \s*</Meta>
             |        </AirlineResource> region=0,322697 lastmatch=]
             ...entire response here - removed for brevity...
      [org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:399), 
      org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:655), 
      lhapi_tests.PatternMatcher.check_pattern(PatternMatcher.groovy:58), 
      lhapi_tests.PatternMatcher$check_pattern.call(Unknown Source), 
      Script1.run(Script1.groovy:1), 
      com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:92), 
      com.eviware.soapui.impl.wsdl.teststeps.assertions.basic.GroovyScriptAssertion.assertScript(GroovyScriptAssertion.java:116), 
      com.eviware.soapui.impl.wsdl.teststeps.assertions.basic.GroovyScriptAssertion.access$600(GroovyScriptAssertion.java:82), 
      com.eviware.soapui.impl.wsdl.teststeps.assertions.basic.GroovyScriptAssertion$GroovyScriptAssertionPanel$RunAction.actionPerformed(GroovyScriptAssertion.java:375), 
      javax.swing.AbstractButton.fireActionPerformed(Unknown Source), 
      javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source), 
      javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source), 
      javax.swing.DefaultButtonModel.setPressed(Unknown Source), 
      javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source), 
      java.awt.AWTEventMulticaster.mouseReleased(Unknown Source), 
      java.awt.Component.processMouseEvent(Unknown Source), 
      javax.swing.JComponent.processMouseEvent(Unknown Source), 
      java.awt.Component.processEvent(Unknown Source), 
      java.awt.Container.processEvent(Unknown Source), 
      java.awt.Component.dispatchEventImpl(Unknown Source), 
      java.awt.Container.dispatchEventImpl(Unknown Source), 
      java.awt.Component.dispatchEvent(Unknown Source), 
      java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source), 
      java.awt.LightweightDispatcher.processMouseEvent(Unknown Source), 
      java.awt.LightweightDispatcher.dispatchEvent(Unknown Source), 
      java.awt.Container.dispatchEventImpl(Unknown Source), 
      java.awt.Window.dispatchEventImpl(Unknown Source), 
      java.awt.Component.dispatchEvent(Unknown Source), 
      java.awt.EventQueue.dispatchEventImpl(Unknown Source), 
      java.awt.EventQueue.access$200(Unknown Source), 
      java.awt.EventQueue$3.run(Unknown Source), 
      java.awt.EventQueue$3.run(Unknown Source), 
      java.security.AccessController.doPrivileged(Native Method), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.awt.EventQueue$4.run(Unknown Source), java.awt.EventQueue$4.run(Unknown Source), 
      java.security.AccessController.doPrivileged(Native Method), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.awt.EventQueue.dispatchEvent(Unknown Source), 
      java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source), 
      java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source), 
      java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source), 
      java.awt.WaitDispatchSupport$2.run(Unknown Source), 
      java.awt.WaitDispatchSupport$4.run(Unknown Source), 
      java.security.AccessController.doPrivileged(Native Method), 
      java.awt.WaitDispatchSupport.enter(Unknown Source), 
      java.awt.Dialog.show(Unknown Source), 
      java.awt.Component.show(Unknown Source), 
      java.awt.Component.setVisible(Unknown Source), 
      java.awt.Window.setVisible(Unknown Source), 
      java.awt.Dialog.setVisible(Unknown Source), 
      com.eviware.soapui.support.UISupport.showDialog(UISupport.java:394), 
      com.eviware.soapui.impl.wsdl.teststeps.assertions.basic.GroovyScriptAssertion.configure(GroovyScriptAssertion.java:144), 
      com.eviware.soapui.impl.wsdl.panels.teststeps.AssertionsPanel$2.mouseClicked(AssertionsPanel.java:149), 
      java.awt.AWTEventMulticaster.mouseClicked(Unknown Source), 
      java.awt.Component.processMouseEvent(Unknown Source), 
      javax.swing.JComponent.processMouseEvent(Unknown Source), 
      java.awt.Component.processEvent(Unknown Source), 
      java.awt.Container.processEvent(Unknown Source), 
      java.awt.Component.dispatchEventImpl(Unknown Source), 
      java.awt.Container.dispatchEventImpl(Unknown Source), 
      java.awt.Component.dispatchEvent(Unknown Source), 
      java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source), 
      java.awt.LightweightDispatcher.processMouseEvent(Unknown Source), 
      java.awt.LightweightDispatcher.dispatchEvent(Unknown Source), 
      java.awt.Container.dispatchEventImpl(Unknown Source), 
      java.awt.Window.dispatchEventImpl(Unknown Source), 
      java.awt.Component.dispatchEvent(Unknown Source), 
      java.awt.EventQueue.dispatchEventImpl(Unknown Source), 
      java.awt.EventQueue.access$200(Unknown Source), 
      java.awt.EventQueue$3.run(Unknown Source), 
      java.awt.EventQueue$3.run(Unknown Source), 
      java.security.AccessController.doPrivileged(Native Method), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.awt.EventQueue$4.run(Unknown Source), 
      java.awt.EventQueue$4.run(Unknown Source), 
      java.security.AccessController.doPrivileged(Native Method), 
      java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source), 
      java.awt.EventQueue.dispatchEvent(Unknown Source), 
      java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source), 
      java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source), 
      java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source), 
      java.awt.EventDispatchThread.pumpEvents(Unknown Source), 
      java.awt.EventDispatchThread.pumpEvents(Unknown Source), 
      java.awt.EventDispatchThread.run(Unknown Source)]

       

      Does that give you any indication what's going wrong here and how to possibly avoid that?

       

      Regards,

      Michael