Match Methods

Introduction

The match methods generate match records to the LogicApp’s “trace log”.

These match records are similar to the “trace.debug” trace log records, and are interwoven with them in the trace log entries list. However, match records receive special treatment from the “IN Tester” which pulls them out and reports them as part of the pass/fail/abort traffic light system showing test success.

The match library includes a range of methods to suit different test scenarios supported by the N-Squared IN Tester product.

Each of the methods listed in this section are guaranteed to create exactly one of the following match records:

There is a third type of match record, which is:

Script logic cannot explicitly generate a match.abort entry in the trace log, this happens only as a side effect when script processing is aborted.

To abort script processing and generate a match.abort, call the Lua built-in error method.

    error ("Reason for aborting the test.")

Tester match methods are accessed via the “n2.n2svcd.tester.match” module:

    local match = require "n2.n2svcd.tester.match"

Note that some of the extended Lua Agents provide some more advanced, protocol specific match functions such as the op method provided by the INAP Lua Agent, or the TCAP attribute matching functions provided by the TCAP Lua Agent.

.pass [Synchronous]

The pass method requests the LogicApp to add a match.pass record to the script instance’s trace log list.

The pass method takes the following argument:

Parameter Type Description
description String A description of the test which is being performed.
text String A message describing how the test succeeded.

Example:

    match.pass ("Check returned buffer size.", "Buffer size " .. size .. " below expected max " .. max .. " (bytes).")

This method will not record any match records if the global TRACE_LEVEL == 0.

The pass method returns nil.

.fail [Synchronous]

The fail method requests the LogicApp to add a match.fail record to the script instance’s trace log list.

The parameters of the fail method are:

Parameter Type Description
description String A description of the test which is being performed.
text String A message describing how the test failed.

Example:

    match.fail ("Check returned buffer size.", "Buffer size " .. size .. " exceeds expected max " .. max .. " (bytes).")

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise the fail method returns the string passed in as text.

.string [Synchronous]

The string method performs a string comparison for an actual value vs. an expected value, and then calls either pass or fail depending if the actual value is string-wise equal to the expected value or not.

The parameters of the string method are:

Parameter Type Description
name String A label for the variable/parameter/attribute which is being tested.
actual String The actual string value, which may be `nil` or `UNDEF`.
A value of `nil` or `UNDEF` will fail this match.
expected String The expected string value, which must be a Lua string (not number, `nil`, or `UNDEF`).

Example:

    match.string ("message", result.message, "200 OK")

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.string ("message", result.message, "200 OK")
    if (msg) then error (msg) end

…since error (nil) will not actually generate an error.

.integer [Synchronous]

The integer method performs an integer comparison for an actual value vs. an expected value, and then calls either pass or fail depending if the actual value is integer-wise equal to the expected value or not.

The parameters of the integer method are:

Parameter Type Description
name String A label for the variable/parameter/attribute which is being tested.
actual Integer The actual integer value, which may be `nil` or `UNDEF`.
A value of `nil` or `UNDEF` will fail this match.
expected Number The expected integer value, which must be a Lua number (not string, `nil`, or `UNDEF`).

Example:

    match.integer ("buffer length", result.buffer_len, 256)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Othewise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

.is_nil [Synchronous]

The is_nil method performs a comparison for an actual value vs. nil, and then calls either pass or fail depending if the actual value is nil or not.

The parameters of the is_nil method are:

Parameter Type Description
name String A label for the variable/parameter/attribute which is being tested.
actual Any The actual value, which may be `nil` or `UNDEF`.

Example:

    match.is_nil ("failure description", result.fail_desc)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

.is_undef [Synchronous]

The is_undef method performs a comparison for an actual value vs. UNDEF, and then calls either pass or fail depending if the actual value is UNDEF or not.

The parameters of the is_undef method are:

Parameter Type Description
name String A label for the variable/parameter/attribute which is being tested.
actual Any The actual value, which may be `nil` or `UNDEF`.

Example:

    match.is_undef ("failure description", result.fail_desc)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

.range [Synchronous]

The range method performs a range comparison for an actual value vs. an expected range of numeric values, and then calls either pass or fail depending if the actual value is number-wise within the expected (inclusive) range or not.

The parameters of the range method are:

Parameter Type Description
name String A label for the variable/parameter/attribute which is being tested.
actual String / Number The actual numeric value, which may be `nil` or `UNDEF`.
A value of `nil` or `UNDEF` will fail this match.
min Number The expected minimum (inclusive) value, which must be a Lua number (not string, `nil`, or `UNDEF`).
max Number The expected maximum (inclusive) value, which must be a Lua number (not string, `nil`, or `UNDEF`).

Example:

    match.range ("elapsed_secs", tv_interval (time_start), 2.0, 3.5)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

.kpath_string [Synchronous]

The kpath_string method performs a string equality match for an actual string value vs. an expected string value.

The difference between kpath_string and string is that in the KPath method, the actual string value is contained within a Lua table or list, potentially in an arbitrarily nested heirarchy of Lua tables/lists.

The path to locating the “value-to-be-matched” within this heirarchy is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_string method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual string value is located within the object.
value String The expected value, which must be a Lua string (not number, `nil`, or `UNDEF`).

NOTE: The Lua implementation is more strict than the original JSON version, in that it does not allow value to be nil or UNDEF, nor a number.

NOTE: The KPath indexing for ARRAY elements is zero-based.

NOTE: If the actual value found via the KPath is a number, it will be converted to string form before comparison.

Example (match passes, string “y” is found and matched):

    match.kpath_string ({ abc = { "x", "y", "z" } }, "abc.[1]", "y" )

Example (match passes, sub-list “abc” has no element [3] zero-based index):

    match.kpath_string ({ abc = { "x", "y", "z" } }, "abc.[3]", nil )

Example (match passes, sib-table “abc” = has no element named “tst”):

    match.kpath_string ({ abc = { foo = "bar", x = "y" } }, "abc.tst", nil )

Example (match passes, sib-table “abc” = has no element named “tst” since Lua table entries cannot exist with value nil ):

    match.kpath_string ({ abc = { foo = "bar", tst = nil } }, "abc.tst", nil )

Example (match fails, sib-table “abc” = does have an element named “tst” ):

    match.kpath_string ({ abc = { foo = "bar", tst = UNDEF } }, "abc.tst", nil )

Example (match passes, integer value 3 is converted to “3” for comparison):

    match.kpath_string ({ abc = { foo = "bar", tst = 3 } }, "abc.tst", "3" )

Example (match fails, integer value as string “3” does not equal string “3.0”):

    match.kpath_string ({ abc = { foo = "bar", tst = 3 } }, "abc.tst", "3.0" )

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_string ({ result, "rest.content_json.status", "OK" )
    if (msg) then error (msg) end

.kpath_integer [Synchronous]

The kpath_integer method performs an integer equality match for an actual integer value contained within a table/list (heirarchy) vs. an expected integer value.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_integer method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual integer value is located within the object.
value Number The expected value, which must be a Lua number (not string, `nil`, or `UNDEF`).

NOTE: The Lua implementation is more strict than the original JSON version, in that it does not allow value to be nil or UNDEF, nor a string.

NOTE: The KPath indexing for ARRAY elements is zero-based.

NOTE: If the actual value found via the KPath is a string, it will be converted to integer form before comparison.

Example (match passes, number 8 is found and matched):

    match.kpath_integer ({ abc = { 7, 8, 9 } }, "abc.[1]", 8 )

Example (match passes, sub-list “abc” has no element [3] zero-based index):

    match.kpath_integer ({ abc = { "x", "y", "z" } }, "abc.[3]", nil )

Example (match passes, string value “08” is converted to 8 for comparison):

    match.kpath_integer ({ abc = { foo = "bar", tst = "08" } }, "abc.tst", 8 )

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_integer ({ result, "rest.content_json.update_count", 8 )
    if (msg) then error (msg) end

.kpath_regex [Synchronous]

The kpath_regex method performs a string regular expression match for an actual string value vs. an expected string regular expression pattern.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_regex method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual string value is located within the object.
pattern String The expected pattern value, which must be a Lua string (may not be nil or UNDEF.
This regular expression uses the full Perl RegEx syntax, not the Lua syntax.

NOTE: The KPath indexing for ARRAY elements is zero-based.

Example (match passes, string " Test " is found and matched):

    match.kpath_regex ({ abc = { xyz = { " Test "  } } }, "abc.xyz.[0]", "^\\s*[Tt]est\\s*$" )

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_regex ({ result, "rest.content_json.status", "^2.. OK$" )
    if (msg) then error (msg) end

.kpath_exists [Synchronous]

The kpath_exists method tests if an element in a structure does (or does not) exist.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_exists method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual value is located within the object.
exists Boolean Specify true to test that a value exists (even if not defined).
Specify false to test that a value does not exist.

NOTE: The KPath indexing for ARRAY elements is zero-based.

Example (match passes, value exists):

    match.kpath_exists ({ abc = { xyz = { 1 } } }, "abc.xyz.[0]", true)

Example (match passes, value does not exist):

    match.kpath_exists ({ abc = { xyz = { } } }, "abc.xyz.[0]", false)

Example (match passes, value does exist, even though it is undef ):

    match.kpath_exists ({ abc = { xyz = UNDEF } }, "abc.xyz", true)

Example (match fails, value does NOT exist, nil values cannot exist in a table ):

    match.kpath_exists ({ abc = { xyz = nil } }, "abc.xyz", true)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_exists ({ result, "rest.content_json.code", true )
    if (msg) then error (msg) end

.kpath_defined [Synchronous]

The kpath_defined method tests if an element in a structure exists and is (or is not) defined.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_defined method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual value is located within the object.
defined Boolean Specify true to test that a value exists and is defined.
Specify false to test that a value exists but is NOT defined.

NOTE: The KPath indexing for ARRAY elements is zero-based.

Example (match passes, value exists and is defined):

    match.kpath_defined ({ abc = { xyz = { 1 } } }, "abc.xyz.[0]", true)

Example (match passes, value does not exist):

    match.kpath_defined ({ abc = { xyz = "test" } }, "abc.foo", false)

Example (match passes, value exists, but is not defined ):

    match.kpath_defined ({ abc = { xyz = UNDEF } }, "abc.xyz", false)

Example (match passes, value does NOT exist, nil values cannot exist in a table ):

    match.kpath_defined ({ abc = { xyz = nil } }, "abc.xyz", false)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_defined ({ result, "rest.content_json.code", true )
    if (msg) then error (msg) end

.kpath_boolean [Synchronous]

The kpath_boolean method tests if an element in a structure exists, is defined, is specifically typed as a Boolean, and has the expected true/false value.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_boolean method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual value is located within the object.
value Boolean Specify true to test that a value exists, is defined, is Boolean, and is true.
Specify false to test that a value exists, is defined, is Boolean, and is false.

NOTE: The KPath indexing for ARRAY elements is zero-based.

Example (match passes, value exists, defined, Boolean, true):

    match.kpath_boolean ({ abc = { xyz = true } }, "abc.xyz", true)

Example (match fails, value does not exist):

    match.kpath_boolean ({ abc = { xyz = true } }, "abc.foo", true)

Example (match fails, value exists, but is not defined ):

    match.kpath_defined ({ abc = { xyz = UNDEF } }, "abc.xyz", true)

Example (match fails, value does NOT exist, nil values cannot exist in a table ):

    match.kpath_defined ({ abc = { xyz = nil } }, "abc.xyz", false)

Example (match fails, value exists, defined, but is not Boolean ):

    match.kpath_defined ({ abc = { xyz = 1 } }, "abc.xyz", false)

Example (match fails, value exists, defined, Boolean, but is not true ):

    match.kpath_defined ({ abc = { xyz = false } }, "abc.xyz", true)

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_boolean ({ result, "rest.content_json.decoded_ok", true )
    if (msg) then error (msg) end

.kpath_ordered_str_array [Synchronous]

The kpath_ordered_str_array method tests if an array of strings exists, has the expected length and sequence of values.

The path to locating the “value-to-be-matched” is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_ordered_str_array method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual value is located within the object.
value Table An array of string values which may include UNDEF entries.

Example (match passes, arrays identical):

    match.kpath_ordered_str_array ({ abc = { xyz = { "a", "b" } } }, "abc.xyz", { "a", "b" })

Example (match fails, array lengths differ):

    match.kpath_ordered_str_array ({ abc = { xyz = { "a", "b", "c" } } }, "abc.xyz", { "a", "b" })

Example (match passes, nil entries are discarded):

    match.kpath_ordered_str_array ({ abc = { xyz = { "a", "b", nil } } }, "abc.xyz", { "a", "b" })

Example (match fails, nil entries are discarded, UNDEF is not):

    match.kpath_ordered_str_array ({ abc = { xyz = { "a", "b", nil } } }, "abc.xyz", { "a", "b", UNDEF })

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_ordered_str_array ({ result, "arg_EDR.TRIGGERS", { "oAnswer_leg2", "oDisconnect_leg2" } )
    if (msg) then error (msg) end

.kpath_size [Synchronous]

The kpath_size method performs a size match of an actual array/list length vs. an expected size.

The path to locating the actual array/list is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_size method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual integer value is located within the object.
size Number The expected size, which must be a Lua number (not string, `nil`, or `UNDEF`).

NOTE: A scalar value matched by the KPath is considered to have size = 1.

Example (match passes):

    match.kpath_size ({ abc = { 7, 8, 9 } }, "abc", 3 )

Example (match passes, scalars have size = 1):

    match.kpath_size ({ abc = { foo = "bar" } }, "abc.foo", 1 )

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

Example (abort on match fail, continues on match pass):

    local msg = match.kpath_size ({ arg_REST, "content_json.customer_list", 2 )
    if (msg) then error (msg) end

.kpath_range [Synchronous]

The kpath_range method performs a range match of a numeric value against an inclusive min/max range.

The path to locating the actual value to match is specified as a “kpath” (aka KPath).

The KPath syntax is described in the Tester Internals / KPath section of this technical guide.

The parameters of the kpath_range method are:

Parameter Type Description
object Table / List The Lua table/list in which the expected value is contained.
kpath String The KPath description of where the actual integer value is located within the object.
min Number The expected minimum value (inclusive), which must be a Lua number (not string, `nil`, or `UNDEF`).
max Number The expected maximum value (inclusive), which must be a Lua number (not string, `nil`, or `UNDEF`).

Example (match passes):

    match.kpath_range ({ abc = [ 7.0 ] }, "abc.[0]", 7, 9 )

If the global TRACE_LEVEL == 0, then this method will not create any match records, will not perform any match checks, and will return nil.

Otherwise this method returns a string failure message in the case of match fail, and returns nil in the case of match pass.

.elapsed [Synchronous]

The elapsed method compares the “now” time against a specified determined point in time, and checks the interval (in seconds) matches the expected range

The parameters of the elapsed method are:

Parameter Type Description
description String A description of the test which is being performed.
tv Two-Element INTEGER List A "timeval" as returned from a prior call to match.elapsed or n2svcd.gettimeofday.
If passed as nil then the actual "match" step will be omitted, and only initialisation will occur.
[1] Integer The total number of Epoch seconds.
[2] Integer The microseconds associated with our number of Epoch seconds.
seconds Number The expected minimum elapsed time in seconds.
margin Number The expected window in seconds. The range is seconds - seconds + margin (inclusive).
(Default: 0.1 seconds)

The elapsed method returns two values.

Parameter Type Description
now Two-Element INTEGER List The "now" timeval.
[1] Integer The total number of Epoch seconds.
[2] Integer The microseconds associated with our number of Epoch seconds.
fail_message String or nil A string failure message in the case of match fail, and returns `nil` in the case of match pass.

Invoking this method without parameters will initialise the context without performing any matching.

Example:

    -- Initialise the timer.
    local tv = match.elapsed ()
    
    -- [logic step 1 should be instant]

    -- Check the elapsed time is 0.0 - 0.1 seconds.
    tv = match.elapsed ("Step 1", tv, 0.0)

    -- [logic step 2 takes 500 ms, error if timing not correct]

    -- Check the elapsed time is 0.5 - 0.5 seconds.
    -- Capture the failure message in case of not in range.
    local msg
    tv, msg = match.elapsed ("Step 2", tv, 0.5)

    -- Abort script processing if elapsed time 2 is not as expected.
    if (msg) error ("Step 2 timing failed.")