Summary:ASTERISK-15609: [patch] Design functionality test for dialplan pattern matching
Reporter:Leif Madsen (lmadsen)Labels:
Date Opened:2010-02-11 07:26:16.000-0600Date Closed:2010-02-16 12:29:45.000-0600
Versions:Frequency of
is related toASTERISK-18036 Enhance Automated Dialplan Tests
Environment:Attachments:( 0) test_pbx.diff
( 1) test_pbx2.diff
( 2) test_pbx3.diff
( 3) test_pbx4.diff
Description:Since we've had a couple of dialplan matching problems before in the past, I'd like to try and create a set of tests that run through a set of complex conditions, make sure they get the correct output (i.e. utilize the right pattern match).

This is based from an email that Jared had sent. I know he'll have a lot of examples to provide for this test!

****** STEPS TO REPRODUCE ******

We'd obviously need to set priority of one type of pattern matching over
the other, so that people have some sort of expectation how to structure
their extensions.  It's already hard enough for most people to know
which of the following would match if the user dialed extension 822 in
the context below...  Let's make sure we set clear rules for precedence,
or we'll only make matters worse.  

exten => _NXX      ,1,NoOp(1)
exten => _[1-8]22  ,1,NoOp(2)
exten => _[a-h]1X  ,1,NoOp(3)
exten => _X.       ,1,NoOp(4)
exten => _X2.      ,1,NoOp(5)
exten => _[0-9*#]11,1,NoOp(6)


Kevin Fleming responded with, "If it's not 2, we fail."
Comments:By: Jared Smith (jsmith) 2010-02-11 07:38:16.000-0600

; dial extension 249, and see which answers
exten => _N[2-4]X,1,NoOp(foo)
exten => _N[246]X,1,NoOp(bar)

; dial extensions 555 and 123 and see what happens
exten => _NXX/6104,1,NoOp(apple)
exten => _NXX/6104,2,NoOp(banana)
exten => _NXX/6104,3,NoOp(cherry)

exten => _NXX,1,NoOp(aardvark)
exten => _NXX,2,NoOp(bear)
exten => _NXX,3,NoOp(chihuahua)

exten => 123,1,Set(CALLERID(num)=6104)
exten => 123,n,DumpChan()
exten => 123,n,Goto(555,1)

By: Mark Michelson (mmichelson) 2010-02-11 09:36:46.000-0600

I started working on code in the tests directory yesterday to test pattern matching in the dialplan.

What I did was to create a context and add extensions to it, each having only a single priority. From there, I can test strings to see which extension, if any, is matched in that context.

It's rather simple to do in the code actually. If Jared, Leif, or anyone else wants to post some particularly "killer" examples which show

a. a sample dialplan
b. a set of strings to use as a test for that dialplan
c. a set of answers showing which extension should be matched by each string

that would be very helpful in helping me to get this test written. The example given by Jared above has the first two parts taken care of, but it does not tell which of the extensions are expected to match given the input.

By: Mark Michelson (mmichelson) 2010-02-11 11:07:04.000-0600

I've uploaded a file (test_pbx.diff) that shows my current test module. There are some comments in the test that show how it can easily be expanded.

Current limitations that I can think of are that there is only one context defined and we don't have the ability to do CID matching.

Both can be added in pretty easily, to be honest, but for the early proof of concept code, I think this shows how it's not especially difficult to write a test for pattern matching.

By: Mark Michelson (mmichelson) 2010-02-11 13:06:58.000-0600

Newer version with CID matching uploaded now.

By: Leif Madsen (lmadsen) 2010-02-11 13:20:43.000-0600

OK, from IRC, a few more ideas I wanted documented:

<jsmith> putnopvut: RE: M16809, how hard would it be to add multiple priorities for the same extension?
<putnopvut> jsmith: it wouldn't be all that difficult, I suppose.
<putnopvut> The benefit of doing so is not especially apparent to me though.
<jsmith> putnopvut: The reason that I ask is that I know one of the samples I uploaded to the notes on that bug dealt with priorities on CID matching
* atis_work has quit (Read error: Connection reset by peer)
<putnopvut> Ah, the goto.
<jsmith> putnopvut: (where the first priority would match the extension with the CID, but then it would go on to priority 2 *without* the CID match)

<Qwell> exten => _X.,1,foo()
<Qwell> exten => 201,2,bar()

<jsmith> [something]
<jsmith> include => else
<jsmith> exten => 123,1,Verbose(2,apple)
<jsmith> [else]
<jsmith> exten => 123,1,Verbose(2,alien)
<jsmith> exten => 123,2,Verbose(2,blargh)

By: Tilghman Lesher (tilghman) 2010-02-11 13:44:12.000-0600

exten => _2,1,Noop(foo)
exten => _[2],1,NoOp(bar)

Second item should not be inserted, as the pattern should match as being the same as the first.

By: Mark Michelson (mmichelson) 2010-02-11 13:54:22.000-0600

Before things get too out of hand here, let me try to explain what I'm going for in this particular test. All I want is to have a list of extensions, and given an input exten/priority/context/cid, make sure that the appropriate item is found when searching.

Tests for whether an extension should not be added because it already exists are different, as are tests that require a PBX to actually be run. Those can easily be added to test_pbx.c as separate tests instead.

By: Jared Smith (jsmith) 2010-02-11 14:10:34.000-0600

Not sure whether this is useful or not, but I thought I'd add it just in case:

exten => _1XX,1,Verbose(2,Monkey)
include => test2

exten => _1XX,1,Verbose(2,Squirrel)

exten => _2XX,1,Verbose(2,Spaceship)
exten => _2XX,n,Goto(1${EXTEN:1},1)

exten => _3XX,1,Verbose(2,Apathy)
exten => _3XX,n,Goto(test2,2${EXTEN:1},1)

Dial 100, and you should get "Monkey"
Dial 200, and you should get "Spaceship" and "Monkey"
Dial 300, and you should get "Apathy" and "Spaceship" and "Squirrel"

By: Mark Michelson (mmichelson) 2010-02-12 11:49:09.000-0600

I've added a new diff that allows you to muck with priorities when registering new test extensions. Now, instead of registering a single priority, you can register multiple ones, numbered how you please, up to 10 per extension. When searching for a specific pattern, you can specify a priority to find as well.

I also doxygenified the structures in the file.

jsmith, the example you gave above is something that definitely needs to be tested, but it falls out of the scope of this particular test. All this test can (and should) do is to say "I want exten 300, priority 1" and we make sure that in the example above that the exten "_3XX" at priority 1 is returned.

I'm less concerned in this test with the sequence of events that occurs when a particular extension is called. So cases like the ones you've posted where the CID changes in mid operation, or any use of Goto is not testable with what I have written.

Like I've said though, such things do need to be tested, they just fall outside the scope of a strict pattern matching unit test.

The next step for expanding the functionality of this test will be to have the ability for multiple contexts, including the ability to include one context within another. I'll update this issue once I've got that written. With that in place, the next step will be to write a bunch of good test cases.

By: Mark Michelson (mmichelson) 2010-02-12 14:01:26.000-0600

Uploaded test_pbx4.diff. This adds the ability to specify multiple contexts for testing, including the ability to include one context within another. I think this gets the framework for the pattern matching test to the point where it has all the necessary features. Now the test cases can begin!

By: Digium Subversion (svnbot) 2010-02-16 12:29:43.000-0600

Repository: asterisk
Revision: 246942

A   trunk/tests/test_pbx.c

r246942 | mmichelson | 2010-02-16 12:29:43 -0600 (Tue, 16 Feb 2010) | 15 lines

Add unit test for dialplan pattern matching.

This test works by reading input from arrays to build a sample
dialplan. From there, patterns are attempted to be matched against
said dialplan, with the expected match given. We then search in our
example dialplan to see if we find a match and if what we find matches
what we expected it to match.

(closes issue ASTERISK-15609)
Reported by: lmadsen
Tested by: mmichelson

Review: https://reviewboard.asterisk.org/r/504/